Ribbon是Netflix公司開源的一個負載均衡的項目(https://github.com/Netflix/ribbon),它是一個基於HTTP、TCP的客戶端負載均衡器。
服務端負載均衡
負載均衡是微服務架構中必須使用的技術,通過負載均衡來實現系統的高可用、集群擴容等功能。負載均衡可通過硬件設備及軟件來實現,硬件比如:F5、Array等,軟件比如:LVS、Nginx等。
用戶請求先到達負載均衡器(也相當於一個服務),負載均衡器根據負載均衡算法將請求轉發到微服務。負載均衡算法有:輪訓、隨機、加權輪訓、加權隨機、地址哈希等方法,負載均衡器維護一份服務列表,根據負載均衡算法將請求轉發到相應的微服務上,所以負載均衡可以為微服務集群分擔請求,降低系統的壓力
客戶端負載均衡
上圖是服務端負載均衡,客戶端負載均衡與服務端負載均衡的區別在於客戶端要維護一份服務列表,Ribbon從Eureka Server獲取服務列表,Ribbon根據負載均衡算法直接請求到具體的微服務,中間省去了負載均衡服務。
Ribbon負載均衡的流程圖:
1、在消費微服務中使用Ribbon實現負載均衡,Ribbon先從EurekaServer中獲取服務列表。
2、Ribbon根據負載均衡的算法去調用微服務。
Ribbon測試
Spring Cloud引入Ribbon配合 restTemplate 實現客戶端負載均衡。Java中遠程調用的技術有很多,如:webservice、socket、rmi、Apache HttpClient、OkHttp等。
1、在客戶端添加Ribbon依賴:
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring‐cloud‐starter‐ribbon</artifactId> </dependency> <dependency> <groupId>com.squareup.okhttp3</groupId> <artifactId>okhttp</artifactId> </dependency
依賴關系:
2、配置Ribbon參數
ribbon: MaxAutoRetries: 2 #最大重試次數,當Eureka中可以找到服務,但是服務連不上時將會重試 MaxAutoRetriesNextServer: 3 #切換實例的重試次數 OkToRetryOnAllOperations: false #對所有操作請求都進行重試,如果是get則可以,如果是post,put等操作沒有實現冪等的情況下是很危險的,所以設置為false ConnectTimeout: 5000 #請求連接的超時時間 ReadTimeout: 6000 #請求處理的超時時間
3、負載均衡測試
啟動兩個服務,端口需要不一致
定義RestTemplate,使用@LoadBalanced注解
@Bean @LoadBalanced public RestTemplate restTemplate() { return new RestTemplate(new OkHttp3ClientHttpRequestFactory()); }
測試代碼
//負載均衡調用 @Test public void testRibbon() { //服務id String serviceId = "XC‐SERVICE‐MANAGE‐CMS"; for(int i=0;i<10;i++){ //通過服務id調用 ResponseEntity<CmsPage> forEntity = restTemplate.getForEntity("http://" + serviceId + "/cms/page/get/5a754adf6abb500ad05688d9", CmsPage.class); CmsPage cmsPage = forEntity.getBody(); System.out.println(cmsPage); } }
Feign
使用Feign可以非常方便的實現Http 客戶端。Spring Cloud引入Feign並且集成了Ribbon實現客戶端負載均衡調用
添加依賴
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring‐cloud‐starter‐openfeign</artifactId> </dependency> <dependency> <groupId>com.netflix.feign</groupId> <artifactId>feign‐okhttp</artifactId> </dependency>
定義FeignClient接口
@FeignClient(value = XcServiceList.XC_SERVICE_MANAGE_CMS) public interface CmsPageClient { @GetMapping("/cms/page/get/{id}") public CmsPage findById(@PathVariable("id") String id); }
啟動類添加@EnableFeignClients注解
測試
@RunWith(SpringRunner.class) @SpringBootTest public class FeignTest { @Autowired CmsPageClient cmsPageClient; @Test public void testFeign() { //通過服務id調用cms的查詢頁面接口 CmsPage cmsPage = cmsPageClient.findById("5a754adf6abb500ad05688d9"); System.out.println(cmsPage); } }