SpringCloud服务发现与消费

通过SpringCloud高可用,我们已经搭建起微服务架构中的核心组件--服务注册中心(包括单节点模式和高可用模式)。同时,还将一个简单的hello-service通过简单的配置使得该程序注册到Eureka注册中心上,称为该服务治理体系下的一个服务。
现在我们已经有了服务注册中心和服务提供者,下面就来尝试构建一个服务消费者

服务消费者

这个服务消费者,主要完成两个目标:发现服务以及消费服务
其中,服务的发现任务是由Eureka客户端完成,而服务消费的任务是由Ribbon完成,Ribbon是一个基于HTTP和TCP的客户端负载均衡器,它可以在通过客户端中配置的ribbonServerList服务端列表去轮询访问以达到负载均衡的作用。当Ribbon与Eureka联合使用时,Ribbon的服务实例清单ribbonServerList会被DiscoveryEnabledNIWSServerList重写,扩展成从Eureka注册中心中获取服务端列表。同时它也会用NIWSServerPing来取代IPing,它将职责委托给Eureka来确定服务端是否已经启动。本质就是它在Eureka服务发现的基础上实现了一套对服务实例的选择策略,从而实现对服务的消费。+

编码实现

1.准备工作

启动之前高可用的服务注册中心eureka-server以及hello-service服务,为了试实验Ribbon的客户端负载均衡的功能,通过java -jar命令行的方式来启动不同端口的hello-service
但是在打包之前,如果hello-service中有测试类,需要将测试类跳过,否则敲入命令mvn:install会报错,因此打包的时候要使用这个命令:

mvn install -Dmaven.test.skip=true

然后在target目录下,敲入命令:

java -jar springboot-01-1.0-SNAPSHOT.jar --server.port=8081
java -jar springboot-01-1.0-SNAPSHOT.jar --server.port=8082

在启动成功之后,如下图所示,从Eureka信息面板可以看到名为HELLO-SERVICE的服务中出现了两个实例单元,分别是通过命令启动的8081端口和8082端口的服务


15200008-a9f666d96d41a2d1.png
两个端口的服务

2.新建Consumer

创建一个SpringBoot的基础工程来实现消费服务者,取名为ribbon-consumer,并在pom中引入如下的依赖,新增了spring-cloud-starter-ribbon

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

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka-server</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-ribbon</artifactId>
        </dependency>
    </dependencies>

然后创建应用主类ConsumerApplication,通过@EnableDiscoveryClient注解让该应用注册为Eureka客户端应用,以获得服务发现的能力。同时,在该主类中创建RestTemplate的SpringBean实例,并通过@LoadBalanced注解开启客户端负载均衡。


@EnableDiscoveryClient
@SpringBootApplication
public class ConsumerApplication {

    @Bean
    @LoadBalanced
    RestTemplate restTemplate(){
        return new RestTemplate();
    }

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

创建ConsumerController类并实现/ribbon-consumer接口。在该接口中,通过在上面创建的RestTemplate来实现对HELLO-SERVICE服务提供的/hello接口进行调用。可以看到在这里访问的地址是服务名HELLO-SERVICE,而不是一个具体的地址,在服务治理框架中,这是一个重要的特性。

@RestController
public class ConsumerController {

    @Autowired
    RestTemplate restTemplate;

    @GetMapping("/ribbon-consumer")
    public String helloConsumer(){
        return restTemplate.getForEntity("http://HELLO-SERVICE/hello",String.class).getBody();
    }
}

在application.properties中配置Eureka服务注册中心的位置,需要与hello-service一样,不然是发现不了服务的。

spring.application.name=ribbon-consumer
server.port=9000

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

3.启动服务

启动服务,然后在注册中心的面板中我们可以看到有两个服务。

15200008-049c5d3f91b4238b.png
消费者服务

然后在地址栏中输入 http://localhost:9000/ribbon-consumer发起get请求,成功返回了“Hello world”,此时我们可以在ribbon-consumer应用的控制台中看到如下信息,Ribbon输出了当前客户端维护的HELLO-SERVICE的服务列表情况。其中包含了各个实例的位置,Ribbon就是按照此信息进行轮询访问,以实现基于客户端的负载均衡。

DynamicServerListLoadBalancer
for client HELLO - SERVICE initialized: DynamicServerListLoadBalancer: {
    NFLoadBalancer: name = HELLO - SERVICE,
    current list of Servers = [192.168 .31 .142: 8081, 192.168 .31 .142: 8082],
    Load balancer stats = Zone stats: {
        defaultzone = [Zone: defaultzone;Instance count: 2;Active connections count: 0;Circuit breaker tripped count: 0;Active connections per server: 0.0;]
    },
    Server stats: [
        [Server: 192.168 .31 .142: 8081;Zone: defaultZone;Total Requests: 0;Successive connection failure: 0;Total blackout seconds: 0;Last connection made: Thu Jan 01 08: 00: 00 CST 1970;First connection made: Thu Jan 01 08: 00: 00 CST 1970;Active Connections: 0;total failure count in last(1000) msecs: 0;average resp time: 0.0;90 percentile resp time: 0.0;95 percentile resp time: 0.0;min resp time: 0.0;max resp time: 0.0;stddev resp time: 0.0],
        [Server: 192.168 .31 .142: 8082;Zone: defaultZone;Total Requests: 0;Successive connection failure: 0;Total blackout seconds: 0;Last connection made: Thu Jan 01 08: 00: 00 CST 1970;First connection made: Thu Jan 01 08: 00: 00 CST 1970;Active Connections: 0;total failure count in last(1000) msecs: 0;average resp time: 0.0;90 percentile resp time: 0.0;95 percentile resp time: 0.0;min resp time: 0.0;max resp time: 0.0;stddev resp time: 0.0]
    ]
}
ServerList: org.springframework.cloud.netflix.ribbon.eureka.DomainExtractingServerList @673b1fae

再尝试发送几次请求,并观察两个HELLO-SERVICE的控制台,可以看到两个控制台会交替打印下面的日志,可以用来判断当前的ribbon-consumer对HELLO-SERVICE的调用是否是负载均衡的。

c.tinner.web.controller.HelloController  : /add, host:192.168.31.142, service_id:hello-service

猜你喜欢

转载自blog.csdn.net/weixin_34184158/article/details/87091168