Spring Cloud 入門 之 Ribbon 篇(二)

一、前言

上一篇《Spring Cloud 入門 之 Eureka 篇(一)》 介紹了微服務的搭建,服務註冊與發現。但在文章中留了一個小尾巴--如何正確使用 Eureka 進行服務發現並調用服務。

本篇文章將介紹如何使用 Ribbon 完成發現服務的調用以及其負載均衡的規則的使用。

二、簡單介紹

Spring Cloud Ribbon 是基於 Netflix Ribbon 實現的一套客戶端負載均衡工具,其主要功能是提供客戶端的軟件負載均衡算法,將 Netflix 的中間層服務連接在一起。

其運行原理如下圖:

Ribbon 運行時分成 2 個步驟:

1) 先選擇在同一個區域負載較少的 EurekaServer;
2) 再根據用戶指定的策略,在從 EurekaServer 中獲取註冊列表中的服務信息進行調用。

其中,Ribbon 提供多種負載均衡策略:如輪詢、隨機、響應時間加權等。

三、實戰演練

我們在 order-server 項目的基礎上進行修改。不清楚的讀者請先轉移至 《Spring Cloud 入門 之 Eureka 篇(一)》 進行瀏覽。

此外,筆者額外的創建 2 個 goods-server 項目,即現在有 3 個 goods-server 項目給 order-server 服務實現客戶端的負載均衡調用。

現在的項目列表如下:

服務實例 端口 描述
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 項目中:

1.添加依賴:

<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 的依賴。

2.請求類添加 @LoadBalanced 註解:

@Configuration
public class RestConfiguration {

	@Bean
	@LoadBalanced
	public RestTemplate getRestTemplate() {
		return new RestTemplate();
	}
}

正如上文介紹的,Ribbon 是客戶端負載均衡工具,所以在 getRestTemplate 方法上添加 @LoadBalanced 註解實現負載均衡。

3.修改請求地址:

@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 默認使用負載均衡的策略是輪詢,對服務進行調用。

四、負載均衡策略

# 4.1 策略規則

Ribbon 提供 IRule 接口,該接口定義瞭如何訪問服務的方法,以下是該接口的實現類:

1) RoundRobinRule:輪詢,默認使用的規則;
2) RandomRule:隨機;
3) AvailabilityFilteringRule:先過濾由於多次訪問故障而處於斷路器跳閘狀態以及併發連接數量超過閥值得服務,然後從剩餘服務列表中按照輪詢策略進行訪問;
4) WeightedResponseTimeRule:根據平均響應時間計算所有的權重,響應時間越快服務權重越有可能被選中;
5) RetryRule:先按照 RoundRobinRule 策略獲取服務,如果獲取服務失敗則在指定時間內進行重試,獲取可用服務;
6) BestAvailableRule:先過濾由於多次訪問故障而處於斷路器跳閘狀態的服務,然後選擇併發量最小的服務;
7) ZoneAvoidanceRule:判斷 server 所在區域的性能和 server 的可用性來選擇服務器。

# 4.2 策略使用

在 order-server 項目中:

@Configuration
public class RestConfiguration {

	@Bean
	@LoadBalanced
	public RestTemplate getRestTemplate() {
		return new RestTemplate();
	}
	
	@Bean
	public IRule testRule() {
	    return new RandomRule();
	}
}

手動創建負載均衡規則對象,本次測試使用的策略是隨機。

啓動 order-server 項目後再次使用 Postman 測試,運行結果如下:

由圖可知,隨機策略已生效,負載均衡的策略由輪詢變成了隨機。

五、案例源碼

Ribbon demo 源碼

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