前言

Github:https://github.com/HealerJean

博客:http://blog.healerjean.com

本文章父工程

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.3.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>


    <groupId>com.healerjean.proj</groupId>
    <artifactId>hlj-parent</artifactId>
    <version>${project.healerjean.version}</version>
    <name>>hlj-parent</name>
    <description>父工程</description>
    <packaging>pom</packaging>

    <modules>
        <module>hlj-eureka-server-1111</module>
        <module>hlj-eureka-server-1112</module>
        <module>hlj-server-provider-2001</module>
        <module>hlj-server-consumer-3001</module>
    </modules>

    <properties>
        <project.healerjean.version>1.0.0-SNAPSHOT</project.healerjean.version>
        <java.version>1.8</java.version>
        <lombok.version>1.18.4</lombok.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <!--swagger 版本-->
        <swagger.version>2.7.0</swagger.version>
        <!--要激活的resoure目录-->
        <profiles.active>src/profiles/local</profiles.active>
        <!--spring-cloud版本-->
        <spring-cloud.version>Dalston.RELEASE</spring-cloud.version>
        <!--commons-lang3-->
        <commons-lang3.version>3.7</commons-lang3.version>
    </properties>

    <dependencyManagement>
        <dependencies>

            <!--spring-cloud-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <!--lombok版本太低了,不支持java10  升级版本:>= 1.18.0-->
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>${lombok.version}</version>
            </dependency>

            <!--swagger-->
            <dependency>
                <groupId>io.springfox</groupId>
                <artifactId>springfox-swagger2</artifactId>
                <version>${swagger.version}</version>
            </dependency>
            <dependency>
                <groupId>io.springfox</groupId>
                <artifactId>springfox-swagger-ui</artifactId>
                <version>${swagger.version}</version>
            </dependency>

            <!--StringUtils-->
            <dependency>
                <groupId>org.apache.commons</groupId>
                <artifactId>commons-lang3</artifactId>
                <version>${commons-lang3.version}</version>
            </dependency>
        </dependencies>

    </dependencyManagement>


    <profiles>
        <profile>
            <!-- 本地开发环境 -->
            <id>local</id>
            <properties>
                <profiles.active>src/profiles/local</profiles.active>
            </properties>
            <activation>
                <activeByDefault>true</activeByDefault>
            </activation>
        </profile>
        <profile>
            <!-- 开发环境 -->
            <id>dev</id>
            <properties>
                <profiles.active>src/profiles/dev</profiles.active>
            </properties>
            <activation>
                <property>
                    <name>dev</name>
                    <value>true</value>
                </property>
            </activation>
        </profile>
        <profile>
            <!-- 生产环境 -->
            <id>product</id>
            <properties>
                <profiles.active>src/profiles/product</profiles.active>
            </properties>
            <activation>
                <property>
                    <name>product</name>
                    <value>true</value>
                </property>
            </activation>
        </profile>
    </profiles>


    <build>

        <!-- 定义资源目录 -->
        <resources>
            <resource>
                <directory>src/main/resources</directory>
            </resource>
            <resource>
                <directory>${profiles.active}</directory>
            </resource>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>false</filtering>
            </resource>
        </resources>

        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.5.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

1、服务注册中心:1111

项目名称:hlj-eureka-server-1111

1.1、pom.xml依赖

<!--eureka 服务端,服务注册中心-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-eureka-server</artifactId>
</dependency>

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.healerjean.proj</groupId>
        <artifactId>hlj-parent</artifactId>
        <version>1.0.0-SNAPSHOT</version>
    </parent>

    <artifactId>hlj-eureka-server-1111</artifactId>
    <version>${project.healerjean.version}</version>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!--eureka 服务端,服务注册中心-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka-server</artifactId>
        </dependency>

        <!--lombok-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

1.2、application.properties:配置文件

spring.application.name=hlj-eureka-serve
server.port=1111
# 服务注册中心 端口
eureka.instance.hostname=localhost
eureka.client.serviceUrl.defaultZone=http://localhost:1111/eureka/
#默认设置下,这个服务注册中心会将自己作为客户端,所以需要禁用它的客户端注册行为
#这个为注册中心,false代表不向注册中心注册自己 ##直接启动之后会发现这个是空的,说明注册中心没有注册任何服务
eureka.client.register-with-eureka=false
#注册中心的职责就是维护服务实例,并不需要它去检索服务,所以将它关闭
eureka.client.fetch-registry=false

1.3、启动类 :

@EnableEurekaServer开启Eureka服务注册中心的支持,用来供给其他应用进行对话

//开启Eureka服务注册中心的支持,用来供给其他应用进行对话
@EnableEurekaServer
@SpringBootApplication
public class EurekaServer_1111_Application {

    public static void main(String[] args) {
        SpringApplication.run(EurekaServer_1111_Application.class, args);
    }

}

1.4、启动

1586342984831

2、服提供者 :2001

项目名称:hlj-server-provider-2001

2.1、pom.xml:依赖

<!--eureka 客户端,处理服务的注册和发现-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.healerjean.proj</groupId>
        <artifactId>hlj-parent</artifactId>
        <version>1.0.0-SNAPSHOT</version>
    </parent>

    <artifactId>hlj-server-provider-2001</artifactId>
    <version>${project.healerjean.version}</version>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>

        <!--eureka 客户端,处理服务的注册和发现-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
        </dependency>

        <!--swagger-->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
        </dependency>

        <!--lombok-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

        <!--StringUtils-->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

2.2、application.properties:配置文件

spring.application.name=hlj-server-provider
server.port=2001

eureka.client.serviceUrl.defaultZone=http://localhost:1111/eureka/

2.3、启动类:

@EnableDiscoveryClient支持服务发现

package com.healerjean.proj;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

//支持服务发现
@EnableDiscoveryClient
@SpringBootApplication
public class ServerProvider_2001_Application {

    public static void main(String[] args) {
        SpringApplication.run(ServerProvider_2001_Application.class, args);
    }

}

2.4、ProviderController

package com.healerjean.proj.controller;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author HealerJean
 * @ClassName HomeController
 * @date 2020/4/8  17:03.
 * @Description
 */
@Api(description = "服务提供者Home控制器")
@RestController
@RequestMapping("api/provider")
@Slf4j
public class ProviderController extends BaseController {


    @Autowired
    private DiscoveryClient discoveryClient;


    @ApiOperation(value = "connect",
                  notes = "connect",
                  consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE,
                  produces = MediaType.APPLICATION_JSON_UTF8_VALUE,
                  response = ServiceInstance.class)
    @GetMapping(value = "connect")
    public ServiceInstance index() {
        log.info("服务提供者Home控制器--------connect--------");
        ServiceInstance serviceInstance = discoveryClient.getLocalServiceInstance();
        log.info("host:【{}】,serviceId:【{}】", 
                 serviceInstance.getHost(), 
                 serviceInstance.getServiceId());
        return serviceInstance;
    }
}



2.5、启动

在启动服务注册中心之后,可以看到这个服务提供者

http://localhost:1111/

1586343042645

2.6、访问接口测试

http://127.0.0.1:2001/api/provider/connect

控制台日志

host:【windows10.microdone.cn】,serviceId:【hlj-server-provider-2001】

接口返回

服务提供者:2001

{
  "host": "windows10.microdone.cn",
  "port": 2001,
  "metadata": {},
  "serviceId": "hlj-server-provider-2001",
  "uri": "http://windows10.microdone.cn:2001",
  "secure": false
}

3、高可用注册中心:1111、1112

解释:将自己作为服务向其他服务注册中心注册自己,这样就会形成一组互相注册的注册中心,用来实心服务清单的互相同步

3.1、高可用注册中心配置

3.1.1、端口:1111

spring.application.name=hlj-eureka-server
server.port=1111
# 服务注册中心 端口
eureka.instance.hostname=localhost
eureka.client.serviceUrl.defaultZone=http://localhost:1112/eureka/

3.1.2、端口:1112

spring.application.name=hlj-eureka-server
server.port=1112
# 服务注册中心 端口
eureka.instance.hostname=localhost
eureka.client.serviceUrl.defaultZone=http://localhost:1111/eureka/

3.2、分别启动这两个注册中心

3.2.1、端口为1111的服务注册中心

http://localhost:1111/

1586343162134

3.2.1、端口为1112的服务注册中心

http://localhost:1112/

1586343183931

3.3、使用帮助

1、即使这个服务提供者所指定的注册中心只有一个,但是因为上面的配置的高可用,其实二者共享了,但是如果不凑巧。我们绑定的那个挂了就完蛋了

2、 为这个服务提供者/服务消费者指定上面的两个注册中心 ,这样即使一个注册中心挂掉了,另外的一个注册中心还能够继续提供服务

spring.application.name=hello-service
server.port=8080

eureka.client.serviceUrl.defaultZone=http://localhost:1111/eureka/,http://localhost:1112/eureka/

4、服务消费者 :3001

解释:根据上面的操作,我们其实已经有了服务注册中心和服务提供者,下面就是开始构建一个服务消费者,它主要完成两个目标,发现服务和消费服务,Eureka为客户端可以发现服务,Ribbon则作为消费服务,它同时也作为辅助均衡器

4.1、pom.xml依赖

<!--eureka 客户端,处理服务的注册和发现-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>

<!--ribbon 消费服务,它同时也作为辅助均衡器-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-ribbon</artifactId>
</dependency>
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.healerjean.proj</groupId>
        <artifactId>hlj-parent</artifactId>
        <version>1.0.0-SNAPSHOT</version>
    </parent>

    <artifactId>hlj-server-consumer-3001</artifactId>
    <version>${project.healerjean.version}</version>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>

        <!--eureka 客户端,处理服务的注册和发现-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
        </dependency>

        <!--ribbon 消费服务,它同时也作为辅助均衡器-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-ribbon</artifactId>
        </dependency>

        <!--swagger-->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
        </dependency>

        <!--lombok-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

        <!--StringUtils-->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

4.2、application.properties配置文件

spring.application.name=hlj-server-consumer
server.port=3001


#为这个服务消费者指定两个注册中心 ,这样即使一个注册中心挂掉了,另外的一个注册中心还能够继续提供服务
eureka.client.serviceUrl.defaultZone=http://localhost:1111/eureka/,http://localhost:1112/eureka/
hlj.server.providerName=HLJ-SERVER-PROVIDER

4.3、启动类

@EnableDiscoveryClient 服务发现

` @LoadBalanced` 开启客户端负载均衡,如果有多个提供者,就可以随机访问了

package com.healerjean.proj;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;

//支持服务发现
@EnableDiscoveryClient
@SpringBootApplication
public class ServerConsumer_3001_Application {

    //开启客户端负载均衡
    @Bean
    @LoadBalanced
    RestTemplate restTemplate() {
        return new RestTemplate();
    }

    public static void main(String[] args) {
        SpringApplication.run(ServerConsumer_3001_Application.class, args);
    }

}

4.4、ConsumerController

package com.healerjean.proj.controller;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

/**
 * @author HealerJean
 * @ClassName HomeController
 * @date 2020/4/8  17:03.
 * @Description
 */
@Api(description = "服务消费者控制器")
@RestController
@RequestMapping("api/consumer")
@Slf4j
public class ConsumerController extends BaseController {


    @Autowired
    private RestTemplate restTemplate;
    @Value("${hlj.server.providerName}")
    private String serverProviderName;

    @ApiOperation(value = "connect",
            notes = "connect",
            consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE,
            produces = MediaType.APPLICATION_JSON_UTF8_VALUE,
            response = ServiceInstance.class)
    @GetMapping(value = "connect")
    public String connectProvider() {
        log.info("服务消费者控制器--------connect--------");
        return restTemplate.getForEntity(
                "http://" + serverProviderName + "/api/provider/connect/", 
                String.class)
            .getBody();
    }
}


4.5、创建服务提供者:2002

这里为了测试客户端负载均衡,添加了这个服务提供者。

这个服务提供者是从服务提供者2001,复制而来

spring.application.name=hlj-server-provider
server.port=2002

#为这个服务提供者指定两个注册中心 ,这样即使一个注册中心挂掉了,另外的一个注册中心还能够继续提供服务
eureka.client.serviceUrl.defaultZone=http://localhost:1111/eureka/,http://localhost:1112/eureka/

4.6、启动以上所有的服务,访问接口测试

解释 可以观察到,访问的时候,调用的服务提供者是随机被我们访问的,8080和8081 是随机出现的,这就是负载均衡喽

http://127.0.0.1:3001/api/consumer/connect  		

接口返回:

服务提供者:2001

{
    "host": "windows10.microdone.cn",
    "port": 2001,
    "metadata": {},
    "serviceId": "hlj-server-provider",
    "uri": "http://windows10.microdone.cn:2001",
    "secure": false
}

服务提供者:2002

{
    "host": "windows10.microdone.cn",
    "port": 2002,
    "serviceId": "hlj-server-provider",
    "metadata": {},
    "uri": "http://windows10.microdone.cn:2002",
    "secure": false
}

ContactAuthor