客戶端負載均衡器 Ribbon 整合Eureka實現遠端呼叫
Ribbon介紹
Ribbon是Netflix公司開源的一個負載均衡的專案(https://github.com/Netflix/ribbon),它是一個基於HTTP、TCP的客戶端負載均衡器。
什麼是負載均衡?
負載均衡是微服務架構中必須使用的技術,通過負載均衡來實現系統的高可用、叢集擴容等功能。負載均衡可通過硬體裝置及軟體來實現,硬體比如:F5、Array等,軟體比如:Nginx等。
如下圖是負載均衡的架構圖:
使用者請求先到達負載均衡器(也相當於一個服務)或者均衡器叢集,負載均衡器根據負載均衡演算法將請求轉發到微服務。負載均衡演算法有:輪訓、隨機、加權輪訓、加權隨機、地址雜湊等方法,負載均衡器維護一份服務列表,根據負載均衡演算法將請求轉發到相應的微服務上,所以負載均衡可以為微服務叢集分擔請求,降低系統的壓力。
什麼是客戶端負載均衡?
上圖是服務端負載均衡,客戶端負載均衡與服務端負載均衡的區別在於客戶端要維護一份服務列表,Ribbon從Eureka Server獲取服務列表,Ribbon根據負載均衡演算法直接請求到具體的微服務,中間省去了負載均衡服務。如下圖是在網上找的Ribbon負載均衡的流程圖:
1、在消費微服務中使用Ribbon實現負載均衡,Ribbon先從EurekaServer中獲取服務列表。
2、Ribbon根據負載均衡的演算法去呼叫微服務。
在Eureka client 中使用Ribbon
Spring Cloud引入Ribbon配合 restTemplate 實現客戶端負載均衡。Java中遠端呼叫的技術有很多,如webservice、socket、rmi、Apache HttpClient、OkHttp等,網際網路專案使用基於http的客戶端較多,本專案使用OkHttp。
匯入ribbon所需的依賴
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-ribbon</artifactId> <version>1.3.6.RELEASE</version> </dependency> <dependency> <groupId>com.squareup.okhttp3</groupId> <artifactId>okhttp</artifactId> </dependency>
在application.yml中配置ribbon相關配置
ribbon:
MaxAutoRetries: 2 #最大重試次數,當Eureka中可以找到服務,但是服務連不上時將會重試
MaxAutoRetriesNextServer: 3 #切換例項的重試次數
OkToRetryOnAllOperations: false #對所有操作請求都進行重試,如果是get則可以,如果是post,put等操作沒有實現冪等的情況下是很危險的,所以設定為false
ConnectTimeout: 5000 #請求連線的超時時間ReadTimeout: 6000 #請求處理的超時時間
負載均衡測試
1)啟動生產者微服務..看看是否在Eureka Server中註冊成功
2)定義RestTemplate,使用@LoadBalanced註解
在消費者的啟動類中定義RestTemplate,讓ribbon 切入,根據restTemplate 提供的serverId 找到對應的服務,並呼叫
@Bean //配置一個resttemplate 遠端呼叫類
@LoadBalanced //配置切面註解,使
public RestTemplate restTemplate(){
return new RestTemplate(new OkHttp3ClientHttpRequestFactory());
}
測試呼叫
服務id 是根據Eureka Server中定的
請求地址 是生產者提供的呼叫路徑 也就是 /get/id
@SpringBootTest
@RunWith(SpringRunner.class)
public class RibbonTest {
@Resource
RestTemplate restTemplate;
@Test
public void fun01(){
// 服務id
String serverId = "XC-SERVER-CMS";
// 通過服務id 呼叫
ResponseEntity<Map> responseEntity = restTemplate.getForEntity("http://" + serverId + "/get/5a754adf6abb500ad05688d9", Map.class);
Map body = responseEntity.getBody();
System.out.println(body);
}
}
測試結果 body是查詢到資料了的,也就是服務呼叫成功
可能有人會覺得很麻煩,因為每次都需要拼裝資料,Feign 很好的解決了這個問題,使複雜的呼叫過程變成呼叫介面從而輕易實現遠端呼叫