Ribbon

在springcloud中,引入Ribbon來作為客戶端時,負載均衡使用的是被@LoadBalanced修飾的RestTemplate對象。

RestTemplate詳細的用法

  • GET請求

第一種方式
返回ResponseEntity,該對象是Spring對HTTP請求響應的封裝,其中主要存儲了HTTP的幾個重要元素,HttpStatus代表了錯誤碼如404,500等。以及HttpHeaders代表了請求頭,body代表了接收到的對象,其類型是根據第二個參數決定的。第一個url為請求地址,可以使用{1}占位符,而參數的值在該方法的最后的可變參數。

ResponseEntity<String> forEntity = restTemplate.getForEntity("http://eureka-client/hello",String.class);
String body = forEntity.getBody();
HttpHeaders headers = forEntity.getHeaders();
HttpStatus statusCode = forEntity.getStatusCode();

三個重載方法:

getForEntity(String url,Class responseType,Object... urlVariables);
getForEntity(String url,Class responseType,Map urlVariables);
getForEntity(URI url,Class responseType);

第二種方式

String forObject = restTemplate.getForObject("http://eureka-client/hello", String.class);

第二種方式與第一種方式唯一的不同就是getForObject的返回值類型直接就是參數列表的第二個參數指定的類型,所以這種方式沒法獲取錯誤碼和請求頭等信息。

RestTemplate本來是Spring提供的發送REST請求的工具類,但是當其被@LoadBalanced注解修飾后,通過其發送REST請求,會被LoadBalanceInterceptor類的inteceptor攔截,然后進行一些負載均衡和請求地址的轉換。

負載均衡策略

通過繼承AbstractLoadBalancerRule抽象類來具體實現負載均衡策略。
RandomRule
通過隨機服務實例的數量來產生一個隨機數,通過索引獲取該服務實例

RoundRobinRule
按照線性輪詢的方式依次選擇每個服務實例的功能
RetryRule
該策略實現了一個具備重試機制的實例選擇功能。其內部還定義了一個IRule對象,默認使用RoundRobinRule實例。在choose方法中則實現了對內部定義的策略進行反復嘗試的策略,若期間能夠選擇到具體的服務實例就返回,若選擇不到就根據設置的嘗試結束時間為閥值(maxRetryMillis參數定義的值+choose方法開始執行是的時間戳),當超過該值后就返回null
WeightedResponseTimeRule
該策略是對RoundRobinRule的擴展,增加了根據實例的運行情況來計數權重,并根據權重來挑選實例。該策略實例化的時候在內部創建了一個定時任務,每過30s便去統計一下各個實例的權重。
ClientConfigEnableRoundRobinRule
該策略較為特殊,一般不直接使用它。該策略內部定義了一個RoundRobinRule策略,choose函數的實現也是使用了RoundRobinRule的線下輪詢機制。一般使用方法:繼承該策略,默認的choose方法實現了線性輪詢機制,在子類中做一些高級策略時通常可能會存在一些無法實施的情況,那么就可以用父類的實現作為備選。
BestAvailableRule
該策略繼承ClientConfigEnableRoundRobinRule,在實現中它注入了負載均衡器的統計對象LoadBalancerStats,同時在具體的choose算法中利用LoadBalancerStats保存的實例統計信息來滿足要求的實例。它通過遍歷負載均衡器中維護的所有服務實例,會過濾掉故障的實例,并找出并發請求數最少的一個,所以該策略的特性是可選出最空閑的實例。
PredicateBasedRule
抽象策略,繼承了ClientConfigEnableRoundRobinRule,基于Predicate實現的策略,Predicate是Google Guava Collection工具對集合進行過濾的條件接口,策略:先過濾清單,在輪詢選擇

AvailableFilteringRule
繼承自PredicationBasedRule

ZoneAvoidanceRule
繼承自PredicationBasedRule

重試

spring cloud eureka比較注重可用性,所以在極端情況下,它寧愿接收故障實例也不會丟掉“健康”實例,比如當服務注冊中心的網絡發生故障斷開時,由于所有的服務實例無法持續維持心跳,一般的服務治理會將所有的服務實例剔除,但是eureka則會因為超過85%的實例丟失心跳而觸發保護機制,注冊中心將會保留此時的所有節點,以實現服務間依然可以進行互相調用的場景,即使其中有部分故障節點,但這樣做可以繼續保障大多數的服務正常消費。
由于spring cloud eureka咋可用性與一致性上的取舍,所以我們在實現服務調用的時候通常會加入一些重試機制。spring cloud 整合了spring retry來增強RestTemplate的重試能力,只需通過簡單的配置,原來那些通過RestTemplate實現的服務訪問就會自動根據配置來實現重試策略。

spring.cloud.loadbalancer.retry.enabled=true
#開啟重試機制
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=10000
#斷路器的超時時間需要大于Ribbon的超時時間,不然不會觸發重試
eureka-consumer.ribbon.ConnectTimeout=250
#請求連接的超時時間
eureka-consumer.ribbon.ReadTimeout=1000
#請求處理的超時時間
eureka-consumer.ribbon.OkToRetryOnAllOperations=true
#對所有操作請求都進行重試
eureka-consumer.ribbon.MaxAutoRetriesNextServer=2
#切換實例的重試次數
eureka-consumer.ribbon.MaxAutoRetries=1
#對當前實例的重試次數

當訪問到故障請求的時候,它會在嘗試訪問一次當前實例(次數由MaxAutoRetries配置),如果不行,就換一個實例進行訪問,如果還是不行,在換一次實例訪問(更換次數由MaxAutoRetriesNextServer配置),如果依然不行,在返回失敗信息。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容