客戶端負載均衡 Spring Cloud Ribbon
Spring Cloud Ribbon是一個基于HTTP和TCP的客戶端負載均衡工具,它基于Netflix Ribbon實作,可以將面向服務的REST模板請求自動轉換為客戶端負載均衡的服務呼叫,
1. 客戶端負載均衡
負載均衡在系統架構中是一個非常重要且不得不去實施的內容,負載均衡是對系統的高可用,網路壓力的緩解和處理能力的擴容的重要手段之一,通常所說的負載均衡是指服務端負載均衡,而客戶端負載均衡和服務端負載均衡最大的不同點在于服務清單所存盤的位置,在客戶端負載均衡中,所有的客戶端節點都維護著自己要訪問的服務端清單,也需要心跳去維護服務端清單的健康性,只是需要與注冊中心配合完成,
1.1 使用客戶端負載均衡呼叫
- 服務提供者啟動多個服務實體并注冊到一個或多個相關聯的服務注冊中心
@Bean
@LoadBelanced
RestTemplate restTemplate() {
return new RestTemplate();
}
- 服務消費者通過呼叫被
@LoadBalanced注解修飾的RestTemplate來實作面向服務的介面呼叫
@Autowired
private RestTemplate restTemplate;
@RequestMapping(value = "https://www.cnblogs.com/ribbon-consumer", method = RequestMethod.GET)
public String helloConsumer() {
return restTemplate.getForEntity("http://HELLO-SERVICE/hello", String.class).getBody();
}
1.2 RestTemplate詳解
RestTemplate物件會使用Ribbon的自動化配置,同時通過配置@LoadBalanced開啟客戶端的負載均衡,
RestTemplate針對不同請求型別和引數型別的服務呼叫實作請參見JDK檔案,
2. 負載均衡策略及配置
2.1 負載均衡策略
在Ribbon中實作了非常多的選擇策略(IRule介面的各個實作)
- RandomRule:隨機選擇策略
該策略實作了從服務實體清單中隨機選擇一個服務實體,具體的選擇邏輯在一個while(server == null)回圈之內,若出現死回圈獲取不到服務實體時,很有可能存在并發的bug, - RoundRobinRule:線性輪詢選擇策略
該策略實作了按照線性輪詢的方式依次選擇每個服務實體,與隨機策略除獲取實體邏輯不同外,在回圈條件中新增一個計數器,當一直獲取不到實體超過10次就會結束嘗試,而線性輪詢的實作是通過AtomicInteger nextServerCyclicCounter物件實作,每次進行實體選擇時呼叫incrementAndGetModulo函式實作遞增, - RetryRule:具備重試機制的選擇策略
該策略實作了一個具備重試機制的實體選擇,在其內部定義了一個IRule物件,默認使用了RoundRobinRule選擇策略,實作了對內部選擇策略進行反復嘗試的策略,若期間能選擇到具體服務實體就回傳,否則根據根據設定的嘗試結束時間為閾值(maxRetryMills引數定義的值 + choose方法開始執行的時間戳),當超過該閾值回傳null, - WeightResponseTimeRule:加權選擇策略
該策略是對RoundRobinRule的擴展,增加了根據實體的運行情況來計算權重,并根據權重來挑選實體,它的實作主要有三個核心內容,- 定時任務:WeightResponseTimeRule策略在初始化的時候會啟動一個定時任務,用來為每個服務實體計算權重,該任務默認每30秒執行一次
- 權重計算:通過maintainWeights函式實作,先根據LoadBalancerStats記錄每個實體的統計資訊,累加所有實體的平均回應時間得到總平均回應時間totalResponseTime,再為實體清單逐個計算權重,規則為 weightSoFar + totalResponseTime - 實體平均回應時間,其中weightSoFar初始化為0,且每計算好幾個權重需要累加到weightSoFar上供下一次計算使用,需要注意的是權重值只是表示各實體的權重區間,并非每個實體的優先級,因此不是數值越大選中概率越大,
- 實體選擇:生成[0, 最大權重值)區間的亂數,遍歷權重串列,若權重值大于等于亂數則用當前權重串列的索引獲取服務實體,
- BestAvailableRule:最空閑連接
該策略利用LoadBalancerStats中保存的實體統計資訊,通過遍歷負載均衡器中維護的所有服務實體,過濾故障的實體并找出請求數最小的實體,
2.2 負載均衡配置
2.2.1 自動化配置
? 在引入Spring Cloud Ribbon依賴后,構建以下介面的實作
| interface | description | default |
|---|---|---|
| IClientConfig | Ribbon客戶端配置 | com.netflix.client.config.DefaultClientConfigImpl |
| IRule | Ribbon負載均衡策略 | com.netflix.loadbalancer.ZoneAvoidanceRule |
| IPing | Ribbon實體檢查策略 | com.netflix.loadbalancer.NoOpPing |
| ServerList |
服務實體清單維護機制 | com.netflixloadbalancer.ConfigurationBasedServerList |
| ServerListFilter |
服務實體清單過濾機制 | org.springframework.cloud.netflix.ribbon.ZonePreferenceServerListFilter |
| ILoadBalancer | 負載均衡器 | com.netflix.loadbalancer.ZoneAwareLoadBalancer |
修改Ribbon實體檢查策略示例
@Configuration
public class MyRibbonConfiguration {
@Bean
public IPing ribbonPing(IClientConfig config) {
return new PingUrl();
}
}
2.2.2 Camden版本對RibbonClient配置優化
在Camden版本中,Spring Cloud Ribbon對RibbonClient定義個性化配置的方法做了進一步優化,可以直接通過<clientName>.ribbon.<key>=<value>的形式進行配置(<clientName>.可省略表示全域配置),配置名配置的對應介面
| key | description |
|---|---|
| NFLoadBalancerPingClassName | 配置IPing介面的實作 |
| NFLoadBalancerClassName | 配置ILoadBalancer介面的實作 |
| NFLoadBalancerRuleClassName | 配置IRule介面的實作 |
| NIWSServerListClassName | 配置ServerList介面的實作 |
| NIWSServerListFilterClassName | 配置ServerListFilter介面的實作 |
修改Ribbon實體檢查策略示例
服務名.ribbon.NFLoadBalancerPingClassName=com.netflix.loadbalancer.PingUrl
2.2.3 與Eureka結合
當在Spring Cloud的應用中同時引入Spring Cloud Ribbon和Spring Cloud Eureka依賴時,會觸發Eureka中實作的對Ribbon的自動化配置,在與Spring Cloud Eureka結合使用時,配置將更加簡單,不在需要需要通過類似<clientName>.ribbon.<key>=<value>的引數指定具體的服務實體清單,而對于Ribbon的引數配置,依然可使用2.2.2中的兩種配置方式,對于客戶端的配置方式可直接使用Eureka中的服務名作為<client>完成針對某個微服務的個性配置,
Spring Cloud Ribbon默認實作了區域親和策略,可以通過Eureka實體的元資料配置來實作區域化的實體配置方案,
如:eureka.instance.metadataMap.zone=shanghai
在Spring Cloud Ribbon和Spring Cloud Eureka結合的工程中,可以通過引數配置的方式禁用Eureka對Ribbon服務實體的維護實作,
如:ribbon.eureka.enabled=false
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/89863.html
標籤:Java
