1. 概述
Ribbon實現客戶端的負載均衡。Spring cloud Feign已經默認集成Ribbon。這是我開始學習ribbon和fegin迷惑的地方,為什么很多文章都先講了ribbon,然后直接講feign,但是沒有提到Fegin和ribbon的關系。
本文的主要的內容如下
- 1.ribbon功能說明
- 2.ribbon的6個主要組件:IRule、IPing、ServerList 、ServerListFilter、ServerListUpdater、ILoadBalancer
- 3.ribbon通過屬性文件配置ribbon
2. Ribbon功能說明
Ribbon實現客戶端的負載均衡,負載均衡器提供很多對http和tcp的行為控制。Spring cloud Feign已經集成Ribbon,所以注解@FeignClient的類,默認實現了ribbon的功能。
Ribbon主要包括如下功能
- 1.支持通過DNS和IP和服務端通信
- 2.可以根據算法從多個服務中選取一個服務進行訪問
- 3.通過將客戶端和服務器分成幾個區域(zone)來建立客戶端和服務器之間的關系。客戶端盡量訪問和自己在相同區域(zone)的服務,減少服務的延遲
- 4.保留服務器的統計信息,ribbon可以實現用於避免高延遲或頻繁訪問故障的服務器
- 5.保留區域(zone)的統計數據,ribbon可以實現避免可能訪問失效的區域(zone)
3. Ribbon主要組件
Ribbon主要包含如下組件:
- 1.IRule
- 2.IPing
- 3.ServerList
- 4.ServerListFilter
- 5.ServerListUpdater
- 6.IClientConfig
- 7.ILoadBalancer
3.1. IRule
功能:根據特定算法中從服務列表中選取一個要訪問的服務 常用IRule實現有以下幾種:
RoundRobinRule
輪詢規則,默認規則。同時也是更高級rules的回退策略
AvailabilityFilteringRule
這個負載均衡器規則,會先過濾掉以下服務:
- a. 由於多次訪問故障而處於斷路器跳閘狀態
- b. 並發的連接數量超過閾值
然后對剩余的服務列表按照RoundRobinRule策略進行訪問
WeightedResponseTimeRule
根據平均響應時間計算所有服務的權重,響應時間越快,服務權重越重、被選中的概率越高。剛啟動時,如果統計信息不足,則使用RoundRobinRule策略,等統計信息足夠,會切換到WeightedResponseTimeRule。
RetryRule
先按照RoundRobinRule的策略獲取服務,如果獲取服務失敗,則在指定時間內會進行重試,獲取可用的服務
BestAvailableRule
此負載均衡器會先過濾掉由於多次訪問故障而處於斷路器跳閘狀態的服務,然后選擇一個並發量最小的服務
RandomRule
隨機獲取一個服務
3.2. IPing
功能:在后台運行的一個組件,用於檢查服務列表是否都活
NIWSDiscoveryPing
不執行真正的ping。如果Discovery Client認為是在線,則程序認為本次心跳成功,服務活着
PingUrl
此組件會使用HttpClient調用服務的一個URL,如果調用成功,則認為本次心跳成功,表示此服務活着。
NoOpPing
永遠返回true,即認為服務永遠活着
DummyPing
默認實現,默認返回true,即認為服務永遠活着
3.3. ServerList
功能:存儲服務列表。分為靜態和動態。如果是動態的,后台有個線程會定時刷新和過濾服務列表
常用ServerList 實現有以下幾種:
ConfigurationBasedServerList
從配置文件中獲取所有服務列表
配置例子:
sample-client.ribbon.listOfServers=www.microsoft.com:80,www.yahoo.com:80,www.google.com:80
DiscoveryEnabledNIWSServerList
從Eureka Client中獲取服務列表。此值必須通過屬性中的VipAddress來標識服務器集群。DynamicServerListLoadBalancer會調用此對象動態獲取服務列表
DomainExtractingServerList
代理類,根據ServerList的值實現具體的邏輯
3.4. ServerListFilter
該接口允許過濾配置或動態獲取的具有所需特性的服務器列表。ServerListFilter是DynamicServerListLoadBalancer用於過濾從ServerList實現返回的服務器的組件。
常用ServerListFilter 實現有以下幾種:
ZoneAffinityServerListFilter
過濾掉所有的不和客戶端在相同zone的服務,如果和客戶端相同的zone不存在,才不過濾不同zone有服務。
啟用此配置使用以下配置
<clientName>.ribbon.EnableZoneAffinity=true
ZonePreferenceServerListFilter
ZoneAffinityServerListFilter的子類。和ZoneAffinityServerListFilter相似,但是比較的zone是發布環境里面的zone。過濾掉所有和客戶端環境里的配置的zone的不同的服務,如果和客戶端相同的zone不存在,才不進行過濾。
ServerListSubsetFilter
ZoneAffinityServerListFilter的子類。此過濾器確保客戶端僅看到由ServerList實現返回的整個服務器的固定子集。 它還可以定期用新服務器替代可用性差的子集中的服務器。
要啟用此過濾器,請指定以下屬性:
<clientName>.ribbon.NIWSServerListClassName=com.netflix.niws.loadbalancer.DiscoveryEnabledNIWSServerList
# the server must register itself with Eureka server with VipAddress "myservice"
<clientName>.ribbon.DeploymentContextBasedVipAddresses=myservice
<clientName>.ribbon.NIWSServerListFilterClassName=com.netflix.loadbalancer.ServerListSubsetFilter
# only show client 5 servers. default is 20.
<clientName>.ribbon.ServerListSubsetFilter.size=5
3.5. ServerListUpdater
功能:被DynamicServerListLoadBalancer用於動態的更新服務列表。 常用的實現類:
PollingServerListUpdater
默認的實現策略。此對象會啟動一個定時線程池,定時執行更新策略
EurekaNotificationServerListUpdater
當收到緩存刷新的通知,會更新服務列表。
3.6. IClientConfig
功能: 定義各種配置信息,用來初始化ribbon客戶端和負載均衡器
常用IClientConfig實現有以下幾種:
DefaultClientConfigImpl
IClientConfig的默認實現,配置文件里的部分值為ribbon。
3.7. ILoadBalancer
定義軟件負載平衡器操作的接口。動態更新一組服務列表及根據指定算法從現有服務器列表中選擇一個服務
DynamicServerListLoadBalancer
DynamicServerListLoadBalancer組合Rule、IPing、ServerList、ServerListFilter、ServerListUpdater 實現類,實現動態更新和過濾更新服務列表
ZoneAwareLoadBalancer
這是DynamicServerListLoadBalancer的子類,主要加入zone的因素。統計每個zone的平均請求的情況,保證從所有zone選取對當前客戶端服務最好的服務組列表
4. 通過屬性文件配置ribbon的主要組件
除了可以使用編程方式創建外,ribbon也提供通過反射和配置屬性文件來實現對應的功能。
4.1. 根據屬性文件配置ribbon
配置屬性的格式如下:
<clientName>.<nameSpace>.<propertyName>=<value>
1. <clientName>:這是調用ribbon的客戶端名稱,如果此值為沒有配置,則此條屬性會作用到所有的客戶端。
2. <nameSpace>:默認值為 “ribbon”
3. <propertyName>:所有的可用的屬性都在com.netflix.client.conf.CommonClientConfigKey。
如果你沒有配置任何屬性,則ribbon會使用com.netflix.client.config.DefaultClientConfigImpl里的值。反之,則會使用你配置的值替換默認的值
下面是對客戶端名稱為”sample-client”配置屬性的demo
# Max number of retries on the same server (excluding the first try)
sample-client.ribbon.MaxAutoRetries=1
# Max number of next servers to retry (excluding the first server)
sample-client.ribbon.MaxAutoRetriesNextServer=1
# Whether all operations can be retried for this client
sample-client.ribbon.OkToRetryOnAllOperations=true
# Interval to refresh the server list from the source
sample-client.ribbon.ServerListRefreshInterval=2000
# Connect timeout used by Apache HttpClient
sample-client.ribbon.ConnectTimeout=3000
# Read timeout used by Apache HttpClient
sample-client.ribbon.ReadTimeout=3000
# Initial list of servers, can be changed via Archaius dynamic property at runtime
sample-client.ribbon.listOfServers=www.microsoft.com:80,www.yahoo.com:80,www.google.com:80
4.2. 通過配置文件配置Ribbon的主要組件
使用以下屬性值可以配置ribbon組合接口使用哪個具體的實現類,xx表示類的全限定名稱,這里略:
<clientName>.<nameSpace>.NFLoadBalancerClassName=xx
<clientName>.<nameSpace>.NFLoadBalancerRuleClassName=xx
<clientName>.<nameSpace>.NFLoadBalancerPingClassName=xx
<clientName>.<nameSpace>.NIWSServerListClassName=xx
<clientName>.<nameSpace>.NIWSServerListFilterClassName=xx
4.3 Spring Cloud Netflix 提供默認的ribbon實現類
IClientConfig ribbonClientConfig: DefaultClientConfigImpl
IRule ribbonRule: ZoneAvoidanceRule
IPing ribbonPing: DummyPing
ServerList ribbonServerList: ConfigurationBasedServerList
ServerListFilter ribbonServerListFilter: ZonePreferenceServerListFilter
ILoadBalancer ribbonLoadBalancer: ZoneAwareLoadBalancer
ServerListUpdater ribbonServerListUpdater: PollingServerListUpdater
本文轉載自 https://juejin.im/post/5d68b73af265da03b12061be