SpringCloud Ribbon (二)

客戶端負載均衡 Spring Cloud Ribbon

Spring Cloud Ribbon是一個基於HTTP和TCP的客戶端負載均衡工具,它基於Netflix Ribbon實現,能夠將面向服務的REST模板請求自動轉換爲客戶端負載均衡的服務調用。java

1. 客戶端負載均衡

負載均衡在系統架構中是一個很是重要且不得不去實施的內容。負載均衡是對系統的高可用,網絡壓力的緩解和處理能力的擴容的重要手段之一。一般所說的負載均衡是指服務端負載均衡,而客戶端負載均衡和服務端負載均衡最大的不一樣點在於服務清單所存儲的位置。在客戶端負載均衡中,全部的客戶端節點都維護着本身要訪問的服務端清單,也須要心跳去維護服務端清單的健康性,只是須要與註冊中心配合完成。spring

1.1 使用客戶端負載均衡調用

  • 服務提供者啓動多個服務實例並註冊到一個或多個相關聯的服務註冊中心
@Bean
@LoadBelanced
RestTemplate restTemplate() {
  return new RestTemplate();
}
  • 服務消費者經過調用被@LoadBalanced註解修飾的RestTemplate來實現面向服務的接口調用
@Autowired
private RestTemplate restTemplate;

@RequestMapping(value = "/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的擴展,增長了根據實例的運行狀況來計算權重,並根據權重來挑選實例,它的實現主要有三個核心內容。
    1. 定時任務:WeightResponseTimeRule策略在初始化的時候會啓動一個定時任務,用來爲每一個服務實例計算權重,該任務默認每30秒執行一次
    2. 權重計算:經過maintainWeights函數實現。先根據LoadBalancerStats記錄每一個實例的統計信息,累加全部實例的平均響應時間獲得總平均響應時間totalResponseTime,再爲實例清單逐個計算權重,規則爲 weightSoFar + totalResponseTime - 實例平均響應時間,其中weightSoFar初始化爲0,且每計算好幾個權重須要累加到weightSoFar上供下一次計算使用。須要注意的是權重值只是表示各實例的權重區間,並不是每一個實例的優先級,所以不是數值越大選中機率越大。
    3. 實例選擇:生成[0, 最大權重值)區間的隨機數,遍歷權重列表,若權重值大於等於隨機數則用當前權重列表的索引獲取服務實例。
  • BestAvailableRule:最空閒鏈接
    該策略利用LoadBalancerStats中保存的實例統計信息,經過遍歷負載均衡器中維護的全部服務實例,過濾故障的實例並找出請求數最小的實例。

2.2 負載均衡配置

2.2.1 自動化配置

​ 在引入Spring Cloud Ribbon依賴後,構建如下接口的實現app

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>.可省略表示全局配置)。配置名配置的對應接口dom

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

相關文章
相關標籤/搜索