一、認識Ribbon
首先咱們需要認識下負載均衡,一般分為服務器端負載和客戶端負載均衡。
服務器端負載均衡:比如Nginx、F5,請求達到服務器后由負載均衡根據算法將請求轉發到目標服務器進行處理。
客戶端負載均衡:比如Ribbon,服務消費者會獲取一個服務器地址列表,調用前根據負載均衡的算法進行選擇某個服務器,然后進行調用。
Ribbon是Netfix發布的負載均衡,Eureka一般配合Ribbon進行使用,Ribbon利用從Eureka注冊中心中獲取服務列表,根據一定的算法進行負載調用,還有Feign組件已使用Ribbon。
Ribbon客戶端組件提供一系列完善的配置選項,比如連接超時、重試、重試算法等。Ribbon內置可插拔、可定制的負載均衡組件。下面是用到的一些負載均衡策略:
- 簡單輪詢負載均衡
- 加權響應時間負載均衡
- 區域感知輪詢負載均衡
- 隨機負載均衡
二、Ribbon應用
1、要將Ribbon包含在您的項目中,請使用起始者,其組ID為org.springframework.cloud
,工件ID為spring-cloud-starter-netflix-ribbon
。需要注意的是在引入Eureka客戶端之后就存在Ribbon依賴,不需要單獨進行添加。檢測依賴如下所示。
2、Ribbon的使用需要在RestTemplate上添加對應注解@LoadBalanced即可
/** * 注⼊RestTemplate * LoadBalanced開啟ribbon * @return */ @Bean @LoadBalanced public RestTemplate getRestTemplate() { return new RestTemplate(); }
3、調用的時候即指定服務名稱就行,不需要指定ip+端口,如下所示:
4、修改負載均衡策略
#針對的被調⽤⽅微服務名稱,不加就是全局⽣效 city-service-resume: ribbon: #負載策略調整 NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
全局生效配置如下
ribbon:
#負載策略調整
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
三、Ribbon底層原理。
Ribbon主要實現邏輯是基於RestTemplates上添加了一個攔截器,進行攔截處理。
Spring Cloud 實現負載均衡通過在RestTemplates增加@LoadBalanced注解,將Rest請求交給Ribben去管理。
Ribben的配置類LoadBalanceAutoConfiguration主要實現的功能:
1、創建了一個LoadBalanceInterceptor的Bean,用於實現對客戶端發起的請求就行攔,是實現客戶端的負載均衡。
2、創建了一個LoadBalanceCustomizer的Bean 用於給RestTemplate增加LoadBalanceInterceptor攔截器。
3、維護了一個被@LoadBalance注釋的RestTemplate的對象列表,並在這里進行初始化,通過調用LoadBalanceCustomizer的實例來給需要客戶端負載均衡的TestTemplate增加LoadBalanceInterceptor攔截器。
4、LoadBalanceInterceptor攔截去會根據傳入的ServiceID去獲取具體的實例,攔截去實現的各個方法,
addServices :向負載均衡器維護的列表中添加服務實例,添加服務的時候會將新加入的實例和之前的所有實例加入List中
chooseServices:通過Rule(線性輪訓、按權重負載、按流量負載)和 Ping來選擇具體的服務實例啟動的ping的定時任務默10秒
markServiecsDowe:標示異常的服務實例
getReachableService:獲取當前正常的服務實例
getAllServices:獲取所有維護的服務實例
5.Ribben 的服務實例由Eureka的服務發現來獲取,Ribben會將Eureka中注冊章的服務轉換成自己的服務實例信息。(請求了Eureka的獲取服務列表)
6.Ribben 的服務更新器主要通過DynamicServiceListLoadBalancer 來實現
7.Ribben實服務實例和真實地址之間轉換的原理,從Netfix的service中獲取host和port 如果service中的host和port中的地址和真實地中中的一直則直接返回真實地址,如果不一致則使用service中的host和port結合真實地址中的相關參數,拼接成新的地址。
*負載均衡的策略實現
資源整合部分來源:簡書