ribbon-consumer

版权声明:本文为博主原创文章,转载需标明出处哦 ^-^。 https://blog.csdn.net/qq_33101675/article/details/88887262

github:https://github.com/Maple521/springcloud/tree/master/ribbon-consumer

通过前几节内容的介绍和实践,我们已经搭建起来微服务架构中的核心组件-----服务注册中心。现在我们已经有了服务注册中心和服务提供者,下面就来尝试构建一个服务消费者,它主要完成两个目标,发现服务以及消费服务。其中,服务发现的任务由Eureka的客户端完成,而服务消费的任务由Ribbon完成。Ribbon是一个基于HTTP和TCP的客户端负载均衡器,它可以在通过客户端中配置的ribbonServerList的服务端列表去轮询访问以达到均衡负载的作用。当Ribbon与Eureka联合使用时,Ribbon的服务实例清单RibbonServerList会被DiscoveryEnableNIWSServerList重写,扩展成从Eureka注册中心中获取服务端列表。同时它也会用NIWSDiscoveryPing来取代IPing,它将职责委托给Eureka来确定服务端是否已经启动。

下面我们通过构建一个简单的示例,看看在Eureka的服务治理体系下如何实现服务的发现与消费。

(1)首先,我们做一些准备工作。启动之前实现的服务注册中心eureka-server以及hello-service服务,为了实验Ribbon的客户端负载均衡功能,我们通过java -jar命令行的方式来启动两个不同端口的hello-service,具体如下:

eureka-server的application.properties为:

server.port=1111

eureka.instance.hostname=localhost
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false
eureka.client.serviceUrl.defaultZone=http://${eureka.instance.hostname}:${server.port}/eureka/

hello-service的application.properties为:

spring.application.name=hello-service
eureka.client.serviceUrl.defaultZone=http://localhost:1111/eureka/

然后打包hello-service,命令行进到target目录,执行

java -jar eureka-producer-0.0.1-SNAPSHOT.jar --server.port=8081

java -jar eureka-producer-0.0.1-SNAPSHOT.jar --server.port=8082

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

下面创建一个Spring Boot的基础工程来实现服务消费者,取名为ribbon-consumer。

我的pom文件为

<?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 http://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.3.7.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.ribbon</groupId>
    <artifactId>ribbon-consumer</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>ribbon-consumer</name>
    <description>Demo project for Ribbon Consumer</description>

    <properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>Brixton.SR5</spring-cloud.version>
    </properties>

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

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

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

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

</project>

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

package com.ribbon.ribbonconsumer;

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 RibbonConsumerApplication {

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

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

}

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

package com.ribbon.ribbonconsumer.controller;

import org.springframework.beans.factory.annotation.Autowired;
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;

@RestController
public class ConsumerController {

    @Autowired
    RestTemplate restTemplate;

    @RequestMapping(value = "/ribbon-consumer",method = RequestMethod.GET)
    public String helloConsumer(){
        return restTemplate.getForEntity("http://HELLO-SERVICE/hello",String.class).getBody();
    }
}

在application.properties中配置Eureka服务注册中心的位置,需要与之谦的HELLO-SERVICE一样,不然是发现不了该服务的,同时设置该消费者的端口为9000,不能与之前启动的应用端口冲突。

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

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

启动ribbon-consumer应用后,我们可以在Eureka信息面板中看到,当前出了HELLO-SERVICE之外,还多了我们实现的

RIBBON-CONSUMER

通过向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=[wanghongbodeair:8082, wanghongbodeair:8081],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:wanghongbodeair: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:wanghongbodeair: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@44dc910e

我们再来看下HELLO-SERVICE控制台打印的情况,发现在8082端口下有如下信息打印,8081上什么也没有

/hello,host:wanghongbodeair,service_id:hello-service

再尝试发送几次请求,发现上面的信息在两个HELLO-SERVICE的控制台里随机打印,至此,负载均衡实现完成。

猜你喜欢

转载自blog.csdn.net/qq_33101675/article/details/88887262