前言
首先要了解 Feign 是如何進行遠程調用的,這里面包括,注冊中心、負載均衡、FeignClient 之間的關系,微服務通過不論是 eureka、nacos 也好注冊到服務端,Feign 是靠 Ribbon 做負載的,而 Ribbon 需要拿到注冊中心的服務列表,將服務進行負載緩存到本地,然后 FeignClient 客戶端在進行調用,大概就是這么一個過程。
Ribbon是如何進行負載的
首先我們要清楚 Ribbon 是如何進行負載的,也就是如何獲取 nacos、eureka 的服務列表,這個很關鍵。
Ribbon是如何進行負載的
RibbonClientConfiguration
RibbonClientConfiguration 類中通過 LoadBalancer,我們知道 ribbon 是靠LoadBalancer 做負載的 無非就是 ILoadBalancer 接口的方法,依次是添加新的服務、在負載均衡里選擇一個服務、markServerDown 服務下線、獲取服務列表、獲取存活的服務器、獲取所有服務器(包括健康和不健康的)
ILoadBalancer 接口
ZoneAwareLoadBalancer
loadBalancer 默認的是 ZoneAwareLoadBalancer 負載均衡器,通過繼承父類DynamicServerListLoadBalancer 的 restOfInit 方法,里面比較重要的兩個方法,enableAndInitLearnNewServersFeature和updateListOfServers 方法
restOfInit 方法
enableAndInitLearnNewServersFeature 方法里面。
LOGGER.info("UsingserverListUpdater{}",serverListUpdater.getClass().getSimpleName()); serverListUpdater.start(updateAction);
讓我們看 ServerListUpdater.start 方法的實現,通過自定義線程去拿,這就是獲取服務列表。
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") publicStringrequestSystem2Api(){ longstartTime=System.currentTimeMillis(); RstringR=iTestServiceClient.testRequestMethod(); if(null!=stringR){ log.info("接口返回:"+stringR.getMsg()); } longneedTime=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 服務進行加載,從而避免了第一次請求超時的情況。
開啟Ribbon饑餓加載
總結
其實這種饑餓加載模式,類似于“客戶端負載預熱”的一個操作,項目啟動的時候進行加載,防止服務之間調用可以因為數據量、業務邏輯處理復雜性導致接口超時,如果你的服務之間調用業務處理比較復雜、且慢,不妨可以試試這種解決方式。
審核編輯:劉清
-
HTTP接口
+關注
關注
0文章
21瀏覽量
1775 -
負載均衡器
+關注
關注
0文章
18瀏覽量
2577
原文標題:面試官:Feign 第一次調用為什么會很慢?大部分人都答不上來!
文章出處:【微信號:芋道源碼,微信公眾號:芋道源碼】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論