SpringCloud服务发现与消费

作者: 一直想上树的猪 | 来源:发表于2019-01-29 11:19 被阅读0次

    通过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端口的服务


    两个端口的服务

    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.启动服务

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

    消费者服务
    然后在地址栏中输入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
    

    相关文章

      网友评论

        本文标题:SpringCloud服务发现与消费

        本文链接:https://www.haomeiwen.com/subject/xnhvjqtx.html