Spring Cloud客戶端負載均衡Ribbon筆記
負載均衡
服務端負載均衡:我在工作中常用就是Nginx+Tomcat集群。由Nginx負責接收請求,按照設置的演算法(輪詢,加權輪詢,隨機,加權隨機,源地址哈希,最小連接數)將請求轉發至後端。
也要有一個心跳監測模塊,及時去掉不可用的服務節點,用來維護一個可用的服務節點清單。
大型公司一般都用F5硬體負載均衡。
客戶端負載均衡:如果將可用服務節點清單挪到Client端,就是客戶端負載均衡了。在Spring Cloud中,Ribbon結合Eureka,客戶端從註冊中心拿到服務節點列表,按照演算法取出一個地址,進行調用。
RestTemplate
在Spring Cloud全家桶中,各個微服務的介面都是HTTP的形式,所以RestTemplate就是一個繞不過去的類,摘抄一些個人覺得的重點。
GET
getForEntity
返回的是ResponseEntity,是Spring對Http響應的封裝,包含了HTTP請求狀態碼的枚舉對象(404,200此類),Http請求頭對象,請求體對象。
重載實現有三種,這裡只說兩種。
注意:代碼裡面的URL寫的都是IP:PORT形式,在實際工作中,應該是服務實例名,HELLO-SERVICE這種。
1
參數(101、姓名)與前面的數字(1,2)順序對應。
2
參數Map的Key,與前面的佔位符(id、name)對應。
getForObject
與getForEntity相比,getForObject直接返回接收內容的對象,省略了responseEntity.getBody()這一步。
如果我們的不需要關注Http響應信息的時候,可以用此方法。
3
4
與getForEntity基本相同,不再贅述。
POST
與GET基本類似。
5
6
PUT
7
put是沒有返回值的。
DELETE
8
delete沒有返回值。
Ribbon負載均衡機制
Ribbon實現了客戶端的負載均衡,調用服務使用的是用@LoadBalanced修飾的RestTemplate:
9
通過對其跟蹤,定位到LoadBalancerClient及其父類ServiceInstanceChooser,方法有如下:
reconstructURI:將轉成http://HOST:PORT/path/
choose:從負載均衡器中選一個服務實例。
execute:用挑出來的服務實例執行請求。
繼續搜索,有LoadBalancerAutoConfiguration與LoadBalancerInterceptor兩個類。主要功能:
1、 由LoadBalancerAutoConfiguration生成LoadBalancerInterceptor,用於發起請求時攔截。
2、 維護RestTemplate列表。
3、 生成RestTemplateCustomizer,給RestTemplate增加LoadBalancerInterceptor攔截器。
以上可得,我們在發起請求的時候,會被LoadBalancerInterceptor的intercept()方法攔截。
其主要工作是通過服務實例名,交給LoadBalancerClient的execute()去執行。
具體實現類是RibbonLoadBalancerClient,其主要工作是:
1、 根據服務實例名獲取負載均衡器ILoadBalancer。
2、 根據ILoadBalancer獲取Server,生成具體的服務實例RibbonServer。
3、 將Request轉到服務實例去執行。
既然是負載均衡,那麼最重要的就是根據負載策略去選擇具體的服務了,也即ILoadBalancer的chooseServer()。其具體的實現類是DynamicServerListLoadBalancer,DSLB繼承了BaseLoadBalancer,BLB繼承了AbstractLoadBalancer,ALB實現了ILoadBalancer。
(就不畫UML圖了)。
而具體的chooseServer()的實現是在BaseLoadBalancer中,而它又是交給IRule的choose()去實現的。
默認的實現類是RoundRobinRule,輪詢。
在實際應用中,針對不同的服務,我們可能需要執行不同的負載策略,Ribbon內置了7種(網上很多,本文不再列出),可在配置文件中進行配置,如圖:
10
以上就是給hello-service這個服務配置了ZoneAwareLoadBalancer,給user-service配置了RandomRule。其他沒有配的,使用默認的RoundRobinRule。
以上是Ribbon結合RestTemplate進行客戶端負載均衡HTTP請求的流程主幹,此外還有很多方法,比如結合Eureka從註冊中心獲取服務列表,對服務列表的維護。通過IPing的實現以10秒(默認)的頻率去檢查服務列表是否有更新等,不再贅述。
11
TAG:Java個人學習心得 |