作者:Lxlxxx
連結:https://juejin.cn/post/7249624466150408250
前言
首先要了解Feign是如何進行遠端呼叫的,這裏麵包括,註冊中心、負載均衡、FeignClient之間的關系,微服務透過不論是eureka、nacos也好註冊到伺服端,Feign是靠Ribbon做負載的,而Ribbon需要拿到註冊中心的服務列表,將服務進行負載緩存到本地,然後FeignClient客戶端在進行呼叫,大概就是這麽一個過程。
# Ribbon是如何進行負載的
首先我們要清楚Ribbon是如何進行負載的,也就是如何獲取nacos、eureka的服務列表,這個很關鍵。
# RibbonClientConfiguration
RibbonClientConfiguration類中透過LoadBalancer,我們知道ribbon是靠LoadBalancer做負載的 無非就是ILoadBalancer介面的方法,依次是添加新的服務、在負載均衡裏選擇一個服務、markServerDown服務下線、獲取服務列表、獲取存活的伺服器、獲取所有伺服器(包括健康和不健康的)
# ZoneAwareLoadBalancer
loadBalancer預設的是ZoneAwareLoadBalancer負載均衡器,透過繼承父類DynamicServerListLoadBalancer的restOfInit方法,裏面比較重要的兩個方法,enableAndInitLearnNewServersFeature和updateListOfServers方法
enableAndInitLearnNewServersFeature方法裏面
LOGGER.info("UsingserverListUpdater {}", serverListUpdater.get class().getSimpleName());
serverListUpdater.start(updateAction);
讓我們看ServerListUpdater.start方法的實作,透過自訂執行緒去拿,這就是獲取服務列表;
# Ribbon負載均衡策略
服務列表獲取說了,當然負載均衡的策略這塊也有必要講一下,主要有七種;
RoundRobinRule(輪詢策略,按照服務順序依次迴圈呼叫)
WeightedResponseTimeRule(權重比策略,優先選擇權重比高的服務,也就是服務響應時間比較短的,響應時間越長權重比越低)
RandomRule(隨機策略,服務提供者列表隨機選擇一個服務)
BestAvailableRule(最小連線數策略,獲取服務列表中連線數最小的服務例項)
RetryRule(重試策略,重試獲取已經失效的服務,指定時間沒有獲取到返回NULL)
AvailabilityFilteringRule(可用性敏感策略,過濾非健康服務例項,選擇lianji)
ZoneAvoidanceRule(區域敏感策略)
# Ribbon-eager-load(饑餓載入)模式
Ribbon對於負載Client是在服務啟動後,發生呼叫的時候才會去建立Client,所以在第一次發生http請求呼叫的時候,不光要算上http的請求時間,還要算上Client的建立時間,所以第一次呼叫的時候才會很慢,寫個方法呼叫下;
System 服務呼叫System2服務
@GetMapping("/requestSystem2Api")
public String requestSystem2Api(){
long startTime = System.currentTimeMillis();
R<String> stringR = iTestServiceClient.testRequestMethod();
if (null !=stringR){
log.info("介面返回:"+stringR.getMsg());
}
long needTime = System.currentTimeMillis() - startTime;
log.info("介面呼叫需要的時間:"+needTime);
return"";
}
從呼叫日誌可以看出,第一次呼叫System2服務,Ribbon的DynamicServerListLoadBalancer會將feign客戶端進行負載,然後進行呼叫,第一次呼叫的時間就是會長一些,第二次呼叫直接進行請求可以看到呼叫時間很快。
開啟Ribbon饑餓載入
ribbon:
nacos:
enabled: true # 開啟naocos輪詢
eager-load:
enabled: true # 開啟Ribbon的饑餓載入模式(防止第一次請求超時的問題)
clients: Lxlxxx-system2 # 指定需要開啟的服務(需要開啟Ribbon的饑餓載入模式)
ReadTimeout: 10000
ConnectTimeout: 10000
MaxAutoRetries: 0
MaxAutoRetriesNextServer: 1
OkToRetryOnAllOperations: false
在計畫啟動的時候,可以從日誌看到,已經把Lxlxxx-system2服務進行載入,從而避免了第一次請求超時的情況;
# 總結
其實這種饑餓載入模式,類似於「客戶端負載預熱」的一個操作,計畫啟動的時候進行載入,防止服務之間呼叫可以因為數據量、業務邏輯處理復雜性導致介面超時,如果你的服務之間呼叫業務處理比較復雜、且慢,不妨可以試試這種解決方式。
熱門推薦