原文地址:Spring Cloud 入門 之 Ribbon 篇(二) 博客地址:http://www.extlight.comjava
上一篇《Spring Cloud 入門 之 Eureka 篇(一)》 介紹了微服務的搭建,服務註冊與發現。但在文章中留了一個小尾巴--如何正確使用 Eureka 進行服務發現並調用服務。git
本篇文章將介紹如何使用 Ribbon 完成發現服務的調用以及其負載均衡的規則的使用。github
Spring Cloud Ribbon 是基於 Netflix Ribbon 實現的一套客戶端負載均衡工具,其主要功能是提供客戶端的軟件負載均衡算法,將 Netflix 的中間層服務鏈接在一塊兒。web
其運行原理以下圖:算法
Ribbon 運行時分紅 2 個步驟:spring
1) 先選擇在同一個區域負載較少的 EurekaServer; 2) 再根據用戶指定的策略,在從 EurekaServer 中獲取註冊列表中的服務信息進行調用。
其中,Ribbon 提供多種負載均衡策略:如輪詢、隨機、響應時間加權等。api
咱們在 order-server 項目的基礎上進行修改。不清楚的讀者請先轉移至 《Spring Cloud 入門 之 Eureka 篇(一)》 進行瀏覽。服務器
此外,筆者額外的建立 2 個 goods-server 項目,即如今有 3 個 goods-server 項目給 order-server 服務實現客戶端的負載均衡調用。併發
如今的項目列表以下:mvc
服務實例 | 端口 | 描述 |
---|---|---|
common-api | - | 公用的 api,如:實體類 |
eureka-server | 9000 | 註冊中心(Eureka 服務端) |
goods-server | 8081 | 商品服務(Eureka 客戶端) |
goods-server-02 | 8082 | 商品服務(Eureka 客戶端) |
goods-server-03 | 8083 | 商品服務(Eureka 客戶端) |
order-server | 8100 | 訂單服務(Eureka 客戶端) |
在 order-server 項目中:
<dependencies> <!-- common api --> <dependency> <groupId>com.extlight.springcloud</groupId> <artifactId>common-api</artifactId> <version>${parent-version}</version> </dependency> <!-- springmvc --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- eureka 客戶端 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <!-- ribbon --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-ribbon</artifactId> </dependency> </dependencies>
添加加 ribbon 的依賴。
@Configuration public class RestConfiguration { @Bean @LoadBalanced public RestTemplate getRestTemplate() { return new RestTemplate(); } }
正如上文介紹的,Ribbon 是客戶端負載均衡工具,因此在 getRestTemplate 方法上添加 @LoadBalanced 註解實現負載均衡。
@Service public class OrderServiceImpl implements OrderService{ @Autowired private RestTemplate restTemplate; // @Autowired // private DiscoveryClient client; @Override public void placeOrder(Order order) throws Exception{ // 獲取商品服務地址列表 // List<ServiceInstance> list = this.client.getInstances("GOODS"); // String uri = ""; // for (ServiceInstance instance : list) { // if (instance.getUri() != null && !"".equals(instance.getUri())) { // uri = instance.getUri().toString(); // break; // } // } // // Result result = restTemplate.getForObject(new URI(uri + "/goods/goodsInfo/" + order.getGoodsId()), Result.class); Result result = this.restTemplate.getForObject("http://GOODS/goods/goodsInfo/" + order.getGoodsId(), Result.class); if (result != null && result.getCode() == 200) { System.out.println("=====下訂單===="); System.out.println(result.getData()); } } }
修改 DiscoveryClient 相關代碼,使用 GOODS 做爲請求商品服務的請求 URL。
完成上邊 3 個操做後,啓動 3 臺 goods-server 服務 和 order-server 服務,經過 Postman 進行測試,運行結果以下:
上圖中,經過 6 次請求返回的商品的端口信息可知,Ribbon 默認使用負載均衡的策略是輪詢,對服務進行調用。
Ribbon 提供 IRule 接口,該接口定義瞭如何訪問服務的方法,如下是該接口的實現類:
1) RoundRobinRule:輪詢,默認使用的規則; 2) RandomRule:隨機; 3) AvailabilityFilteringRule:先過濾因爲屢次訪問故障而處於斷路器跳閘狀態以及併發鏈接數量超過閥值得服務,而後從剩餘服務列表中按照輪詢策略進行訪問; 4) WeightedResponseTimeRule:根據平均響應時間計算全部的權重,響應時間越快服務權重越有可能被選中; 5) RetryRule:先按照 RoundRobinRule 策略獲取服務,若是獲取服務失敗則在指定時間內進行重試,獲取可用服務; 6) BestAvailableRule:先過濾因爲屢次訪問故障而處於斷路器跳閘狀態的服務,而後選擇併發量最小的服務; 7) ZoneAvoidanceRule:判斷 server 所在區域的性能和 server 的可用性來選擇服務器。
在 order-server 項目中:
@Configuration public class RestConfiguration { @Bean @LoadBalanced public RestTemplate getRestTemplate() { return new RestTemplate(); } @Bean public IRule testRule() { return new RandomRule(); } }
手動建立負載均衡規則對象,本次測試使用的策略是隨機。
啓動 order-server 項目後再次使用 Postman 測試,運行結果以下:
由圖可知,隨機策略已生效,負載均衡的策略由輪詢變成了隨機。