Ribbon是什麼?
Spring Cloud Ribbon是一個基於HTTP和TCP的客戶端負載均衡工具,它基於Netflix Ribbon實現。通過Spring Cloud的封裝,可以讓我們輕鬆地將面向服務的REST模版請求自動轉換成客戶端負載均衡的服務調用。Spring Cloud Ribbon雖然只是一個工具類框架,它不像服務註冊中心、配置中心、API網關那樣需要獨立部署,但是它幾乎存在於每一個Spring Cloud構建的微服務和基礎設施中。因爲微服務間的調用,API網關的請求轉發等內容,實際上都是通過Ribbon來實現的,包括後續我將要介紹的Feign,它也是基於Ribbon實現的工具。所以,對Spring Cloud Ribbon的理解和使用,對於我們使用Spring Cloud來構建微服務非常重要。
Spring Cloud Alibaba 如何使用Ribbon?
在我們引入 spring-cloud-starter-alibaba-nacos-discovery這個依賴之後,裏面就已經包含了Ribbon的依賴
Ribbon的組成
接口 | 作用 | 默認值 |
---|---|---|
IClientConfig | 讀取配置 | DefaultClientConfigImpl |
IRule | 負載均衡規則,選擇實例 | ZoneAvoidanceRule |
IPing | 篩選掉ping不通的實例 | DummyPing |
ServerList<Server> | 交給Ribbon的實例列表 | Ribbon: ConfigurationBasedServerList Spring Cloud Alibaba: NacosServerList |
ServerListFilter<Server> | 過濾掉不符合條件的實例 | ZonePreferenceServerListFilter |
ILoadBalancer | Ribbon的入口 | ZoneAwareLoadBalancer |
ServerListUpdater | 更新交給Ribbon的List的策略 | PollingServerListUpdater |
因爲我們通常自定義配置最多的就是Ribbon的負載均衡規則,所以把負載均衡規則列出來
規則名稱 |
特點 |
---|---|
AvailabilityFilteringRule |
過濾掉一直連接失敗的被標記爲circuit tripped的後端Server,並過濾掉那些高併發的後端Server或者使用一個AvailabilityPredicate來包含過濾server的邏輯,其實就是檢查status裏記錄的各個Server的運行狀態 |
BestAvailableRule |
選擇一個最小的併發請求的Server,逐個考察Server,如果Server被tripped了,則跳過 |
RandomRule | 隨機選擇一個Server |
ResponseTimeWeightedRule | 已廢棄,作用同WeightedResponseTimeRule |
RetryRule | 對選定的負載均衡策略機上重試機制,在一個配置時間段內當選擇Server不成功,則一直嘗試使用subRule的方式選擇一個可用的Sever |
RoundRobinRule | 輪詢選擇,輪詢index,選擇index對應位置的Server |
WeightedResponseTimeRule | 根據響應時間加權,響應時間越長,權重越小,被選中的可能性越低 |
ZoneAvoidanceRule | 複合判斷Server所有Zone的性能和Server的可用性選擇Server,在沒有Zone的環境下,類似於輪詢(RoundRobinRule) |
ClientConfigEnabledRoundRobinRule |
客戶端自定義配置規則 |
NacosRule |
同集羣優先調用的效果,並且還能支持Nacos權重配置。 |
Ribbion細粒度配置自定義
1.Ribbion細粒度配置自定義java代碼方式
1.新建一個 ribbonconfiguration包(不同於Spring Boot 啓動類的包,不然會出現配置事務管理無效等問題)
2.在剛剛新建的包下新建 RibbonConfiguration類
@Configuration
public class RibbonConfiguration {
@Bean
public IRule ribbonRule(){
// 實現隨機選擇rule規則
return new RandomRule();
}
}
3.在創建一個configuration包(在Spring Boot啓動類的同級創建)
4. 創建 UserCenterRibbonConfiguration類
// 微服務單個配置
@Configuration
@RibbonClient(name = "center-user",configuration = RibbonConfiguration.class)
public class UserCenterRibbonConfiguration {
}
2.Ribbion細粒度配置自定義配置屬性方式
在application.yml文件中添加
# 單獨爲某個微服務配置
center-user:
ribbon:
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
3. 兩種配置方式對比
配置方式 | 優點 | 缺點 |
---|---|---|
代碼配置 | 基於代碼,更加靈活 | 有小坑(父子上下文) 線下修改得重新打包,發佈 |
屬性配置 | 易上手 配置更加直觀 線上修改無需重新打包 發佈優先級更高 |
極端場景下沒有代碼配置方式靈活 |
總結:
- 儘量使用屬性配置,屬性方式實現不了的情況下再考慮用代碼配置
在同一個微服務內儘量保持單一性,比如統一使用屬性配置,不要兩種方式混用,增加定位代碼的複雜性
4.Ribbon支持的配置項
配置屬性方式:
<clientName>.ribbon. 如下屬性:
- NFLoadBalancerClassName: ILoadBalancer 實現類全路徑
- NFLoadBalancerRuleClassName: IRule 實現類全路徑
- NFLoadBalancerIPingClassName: IPing實現類全路徑
- NIWSServerListClassName: ServerList實現類全路徑
- NIWSServerListFilterClassName: ServerListFilter實現類全路徑
Ribbion全局配置
在Ribbion細粒度配置自定義java代碼方式的第四步創建的UserCenterRibbonConfiguration類中做修改即可
@Configuration
// 微服務單個配置
//@RibbonClient(name = "center-user",configuration = RibbonConfiguration.class)
// 全局配置
@RibbonClients(defaultConfiguration = RibbonConfiguration.class )
public class UserCenterRibbonConfiguration {
}
Ribbon飢餓懶加載
在我們使用ribbon做負載時會發現,第一次請求會比較慢,這個時候我們需要開始飢餓懶加載
在application.yml添加配置即可
ribbon:
eager-load:
# 開啓飢餓加載
enabled: true
# 哪些服務啓用飢餓加載,多個服務用逗號分隔
clients: center-user