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端口的服務


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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章