Spring Cloud學習筆記【二】Eureka 服務提供者/服務消費者(ribbon)


Ribbon 是 Netflix 發布的開源項目,主要功能是為 REST 客戶端實現負載均衡。它主要包括六個組件:

  • ServerList,負載均衡使用的服務器列表。這個列表會緩存在負載均衡器中,並定期更新。當 Ribbon 與 Eureka 結合使用時,ServerList 的實現類就是 DiscoveryEnabledNIWSServerList,它會保存 Eureka Server 中注冊的服務實例表。
  • ServerListFilter,服務器列表過濾器。這是一個接口,主要用於對 Service Consumer 獲取到的服務器列表進行預過濾,過濾的結果也是 ServerList。Ribbon 提供了多種過濾器的實現。
  • IPing,探測服務實例是否存活的策略。
  • IRule,負載均衡策略,其實現類表述的策略包括:輪詢、隨機、根據響應時間加權等,我們也可以自己定義負載均衡策略,比如我們就利用自己實現的策略,實現了服務的版本控制和直連配置。實現好之后,將實現類重新注入到 Ribbon 中即可。
  • ILoadBalancer,負載均衡器。這也是一個接口,Ribbon 為其提供了多個實現,比如 ZoneAwareLoadBalancer。而上層代碼通過調用其 API 進行服務調用的負載均衡選擇。一般 ILoadBalancer 的實現類中會引用一個 IRule。
  • RestClient,服務調用器。顧名思義,這就是負載均衡后,Ribbon 向 Service Provider 發起 REST 請求的工具。

Ribbon 工作時會做四件事情:

  1. 優先選擇在同一個 Zone 且負載較少的 Eureka Server;
  2. 定期從 Eureka 更新並過濾服務實例列表;
  3. 根據用戶指定的策略,在從 Server 取到的服務注冊列表中選擇一個實例的地址;
  4. 通過 RestClient 進行服務調用。

服務提供者

創建一個Spring Starter Project,命名service-producer,添加依賴

 1 <dependencies>
 2   <dependency>
 3     <groupId>org.springframework.boot</groupId>
 4     <artifactId>spring-boot-starter-web</artifactId>
 5   </dependency>
 6   <dependency>
 7     <groupId>org.springframework.cloud</groupId>
 8     <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
 9   </dependency>
10 </dependencies>

配置屬性(application.yml)

server:
  port: 8080  #啟動其他實例時需要修改端口號
spring:
  application:
    name: service-producer
eureka:
  client:
    serviceUrl:
      defaultZone: http://admin:123456@localhost:8761/eureka/

控制層創建一個controller,對外提供一個接口(這里比較簡單就只返回服務的端口號)

 1 package com.carry.springcloud.controller;  2 
 3 import org.springframework.beans.factory.annotation.Value;  4 import org.springframework.web.bind.annotation.GetMapping;  5 import org.springframework.web.bind.annotation.RestController;  6 
 7 @RestController  8 public class ProducerController {  9 
10     @Value("${server.port}") 11  String serverPort; 12     
13     @GetMapping("/getPortInfo") 14     public String produce() { 15         return "調用服務的端口號為:" + serverPort; 16  } 17 }

啟動類加上@EnableEurekaClient注解即可

 1 package com.carry.springcloud;  2 
 3 import org.springframework.boot.SpringApplication;  4 import org.springframework.boot.autoconfigure.SpringBootApplication;  5 import org.springframework.cloud.netflix.eureka.EnableEurekaClient;  6 
 7 @EnableEurekaClient  8 @SpringBootApplication  9 public class ServiceProducerApplication { 10 
11     public static void main(String[] args) { 12         SpringApplication.run(ServiceProducerApplication.class, args); 13  } 14 }

測試

打開瀏覽器訪問localhost:8080/getPortInfo,出現以下結果說明是OK的

服務消費者(Ribbon)

創建一個Spring Starter Project,命名service-consumer-ribbon,添加依賴

 1 <dependencies>
 2    <dependency>
 3       <groupId>org.springframework.boot</groupId>
 4       <artifactId>spring-boot-starter-web</artifactId>
 5    </dependency>
 6    <dependency>
 7       <groupId>org.springframework.cloud</groupId>
 8       <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
 9    </dependency>
10    <dependency>
11       <groupId>org.springframework.cloud</groupId>
12       <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
13    </dependency>
14 </dependencies>

配置屬性(application.yml)

server:
  port: 8082
spring:
  application:
    name: service-consumer-ribbon
eureka:
  client:
    serviceUrl:
      defaultZone: http://admin:123456@localhost:8761/eureka/

在啟動類中@Bean 將 restTemplate注入到ioc容器, 並使用@LoadBalanced 注解聲明開啟 負載均衡

 1 package com.carry.springcloud;  2 
 3 import org.springframework.boot.SpringApplication;  4 import org.springframework.boot.autoconfigure.SpringBootApplication;  5 import org.springframework.cloud.client.loadbalancer.LoadBalanced;  6 import org.springframework.cloud.netflix.eureka.EnableEurekaClient;  7 import org.springframework.context.annotation.Bean;  8 import org.springframework.web.client.RestTemplate;  9 
10 @EnableEurekaClient 11 @SpringBootApplication 12 public class ServiceConsumerRibbonApplication { 13 
14     public static void main(String[] args) { 15         SpringApplication.run(ServiceConsumerRibbonApplication.class, args); 16  } 17 
18  @Bean 19  @LoadBalanced 20  RestTemplate restTemplate() { 21         return new RestTemplate(); 22  } 23 }

編寫一個controller,注入RestTemplate用其調用服務提供者接口

 1 package com.carry.springcloud.controller;  2 
 3 import org.springframework.beans.factory.annotation.Autowired;  4 import org.springframework.web.bind.annotation.GetMapping;  5 import org.springframework.web.bind.annotation.RestController;  6 import org.springframework.web.client.RestTemplate;  7 
 8 @RestController  9 public class RibbonController { 10 
11  @Autowired 12  RestTemplate restTemplate; 13 
14     @GetMapping("/getPoducerInfo") 15     public String getPoducerInfo() { 16         String result = this.restTemplate.getForObject("http://service-producer/getPortInfo", String.class); 17         return result; 18  } 19 }

注:上面代碼中restTemplate.getForObject第一個參數url規則為:協議http+服務名(即application.yml配置spring.application.name的值)+接口值

測試

1、啟動Eureka服務

2、啟動兩個服務提供者service-producer實例,端口分別為8080和8081

3、啟動服務消費者service-consumer-ribbon

4、瀏覽器中訪問 localhost:8761,注冊成功

5、訪問服務消費者localhost:8082/getPoducerInfo

再次訪問

結果顯示是輪詢調用兩個服務提供者實例,這是因為默認的負載均衡算法是輪詢,也可自行修改負載均衡算法,例如:隨機算法,權重,只需要在application.yml里配置即可。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM