深入理解feign遠程調用的各種超時參數

1. 引言

在spring cloud微服中,feign遠程調用可能是大家每天都接觸到東西,但很多同學卻沒咋搞清楚這里邊的各種超時問題,生產環境可能會蹦出各種奇怪的問題。
首先說下結論:
1)只使用feign組件,不使用ribbion組件,其默認feign的連接超時是10s,讀超時是60s;
2) 同時使用了feign和ribbion組件,(1)若沒有任何人為配置超時時間,遠程調用使用ribbion的默認超時時間,連接超時、讀超時都是1秒鐘;(2)若同時主動配置了feign 、ribbion的超時時間,則使用配置的feign超時時間;(3)若只主動配置了feign的超時時間,則使用配置的feign超時時間;(4)若只主動配置了ribbon超時時間,則使用配置的ribbion超時時間。

2. only feign

feign本身是通過FeignClientFactoryBean 創建出來的,feign的超時配置也在方法org.springframework.cloud.openfeign.FeignClientFactoryBean#configureUsingConfiguration中。此方法properties.isDefaultToProperties()的默認值是true,我們一般也不會去改它,所以一般是執行紅方框中的邏輯。(1)先執行全局配置configureUsingConfiguration(context, builder),(2)再執行屬性配置類中FeignClientProperties的默認配置, (3)最后執行屬性配置類FeignClientProperties中當前feign client特定的配置。這三個步驟的覆蓋順序是后者覆蓋前者,也就是越往后優先級越高。默認情況下我們未做任何配置時,FeignClientProperties是空對象,也就是說此時只會執行步驟(1)的屬性配置。
在這里插入圖片描述
全局屬性配置方法org.springframework.cloud.openfeign.FeignClientFactoryBean#configureUsingConfiguration回到spring容器中去取超時配置對象Request.Options
在這里插入圖片描述在這里插入圖片描述
自動配置類相應方法為我們配置了一個Request.Options對象(當spring容器中不存在此類型的bean時)
在這里插入圖片描述
LoadBalancerFeignClient.DEFAULT_OPTIONS的連接超時、讀超時分別是10s、60s.


public class LoadBalancerFeignClient implements Client {static final Request.Options DEFAULT_OPTIONS = new Request.Options();//.....
}	public static class Options {private final long connectTimeout;private final TimeUnit connectTimeoutUnit;private final long readTimeout;private final TimeUnit readTimeoutUnit;private final boolean followRedirects;//......./*** Creates the new Options instance using the following defaults:* <ul>* <li>Connect Timeout: 10 seconds</li>* <li>Read Timeout: 60 seconds</li>* <li>Follow all 3xx redirects</li>* </ul>*/public Options() {this(10, TimeUnit.SECONDS, 60, TimeUnit.SECONDS, true);}//.......}   

3. feign+ribbon

在feign引入ribbon負載均衡時,遠程調用的feign client會用LoadBalancerFeignClient.
LoadBalancerFeignClient.execute方法中有調用getClientConfig(options, clientName);的代碼行,而IClientConfig中包含有feign和ribbion超時時間。
在這里插入圖片描述
getClientConfig方法參數中的options是feign本身的超時配置,
可以看到當參數options等于DEFAULT_OPTIONS,即沒有為feign主動配置超時時間這種情況,這種情況會到容器用去獲取超時配置;當options不等于DEFAULT_OPTIONS,即已經為feign主動配置了超時時間這種情況下,我們會使用feign的超時時間。

IClientConfig getClientConfig(Request.Options options, String clientName) {IClientConfig requestConfig;if (options == DEFAULT_OPTIONS) {requestConfig = this.clientFactory.getClientConfig(clientName);}else {requestConfig = new FeignOptionsClientConfig(options);}return requestConfig;}

這個IClientConfig 在配置類org.springframework.cloud.netflix.ribbon.RibbonClientConfiguration的配置方法ribbonClientConfig執行config.loadProperties(this.name);將配置文件中ribbion的配置信息賦值到config對象后,又執行了config.set(CommonClientConfigKey.ConnectTimeout, DEFAULT_CONNECT_TIMEOUT); config.set(CommonClientConfigKey.ReadTimeout, DEFAULT_READ_TIMEOUT);重新將連接超時、讀超時重置為1000毫秒,即1秒。

@SuppressWarnings("deprecation")
@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties
// Order is important here, last should be the default, first should be optional
// see
// https://github.com/spring-cloud/spring-cloud-netflix/issues/2086#issuecomment-316281653
@Import({ HttpClientConfiguration.class, OkHttpRibbonConfiguration.class,RestClientRibbonConfiguration.class, HttpClientRibbonConfiguration.class })
public class RibbonClientConfiguration {/*** Ribbon client default connect timeout.*/public static final int DEFAULT_CONNECT_TIMEOUT = 1000;/*** Ribbon client default read timeout.*/public static final int DEFAULT_READ_TIMEOUT = 1000;/*** Ribbon client default Gzip Payload flag.*/public static final boolean DEFAULT_GZIP_PAYLOAD = true;@RibbonClientNameprivate String name = "client";
@Bean@ConditionalOnMissingBeanpublic IClientConfig ribbonClientConfig() {DefaultClientConfigImpl config = new DefaultClientConfigImpl();config.loadProperties(this.name);config.set(CommonClientConfigKey.ConnectTimeout, DEFAULT_CONNECT_TIMEOUT);config.set(CommonClientConfigKey.ReadTimeout, DEFAULT_READ_TIMEOUT);config.set(CommonClientConfigKey.GZipPayload, DEFAULT_GZIP_PAYLOAD);return config;}//....}}

我們在看看DefaultClientConfigImpl的怎么處理屬性的。
可以看出上邊RibbonClientConfiguration.ribbonClientConfig方法中設置的超時時間,它們被放在DefaultClientConfigImpl#properties中的,而取配置屬性的底層方法都是getProperty(String key),所以在沒有為feign配置超時時間時,ribbon的取值時先取當前指定ribbon client的超時時間,若不存在則取全局ribbon的超時時間,若還是不存在,則取DefaultClientConfigImpl#properties中的默認值1秒。

public class DefaultClientConfigImpl implements IClientConfig {@Overridepublic <T> DefaultClientConfigImpl set(IClientConfigKey<T> key, T value) {properties.put(key.key(), value);return this;}protected Object getProperty(String key) {//這里enableDynamicProperties一定是trueif (enableDynamicProperties) {String dynamicValue = null;DynamicStringProperty dynamicProperty = dynamicProperties.get(key);//dynamicProperty是nullif (dynamicProperty != null) {dynamicValue = dynamicProperty.get();}if (dynamicValue == null) {//到配置文件中取當前client的'clientName.ribbion.ReadTimeout'這種格式的屬性dynamicValue = DynamicProperty.getInstance(getConfigKey(key)).getString();if (dynamicValue == null) {//到配置文件中取全局'ribbion.ReadTimeout'這種格式的屬性dynamicValue = DynamicProperty.getInstance(getDefaultPropName(key)).getString();}}if (dynamicValue != null) {return dynamicValue;}}//DefaultClientConfigImpl類中定義的默認值return properties.get(key);}}

LoadBalancerFeignClient#execute 方法中的lbClient(clientName)創建了一個負載均衡器RetryableFeignLoadBalancer,且此負載均衡期中的config就是上邊RibbonClientConfiguration#ribbonClientConfig配置方法中所對應的IClientConfig.

private FeignLoadBalancer lbClient(String clientName) {return this.lbClientFactory.create(clientName);}
public FeignLoadBalancer create(String clientName) {FeignLoadBalancer client = this.cache.get(clientName);if (client != null) {return client;}IClientConfig config = this.factory.getClientConfig(clientName);ILoadBalancer lb = this.factory.getLoadBalancer(clientName);ServerIntrospector serverIntrospector = this.factory.getInstance(clientName,ServerIntrospector.class);client = this.loadBalancedRetryFactory != null? new RetryableFeignLoadBalancer(lb, config, serverIntrospector,this.loadBalancedRetryFactory): new FeignLoadBalancer(lb, config, serverIntrospector);this.cache.put(clientName, client);return client;}

現在回到LoadBalancerFeignClient#execute方法塊調用負載均衡的
return lbClient(clientName) .executeWithLoadBalancer(ribbonRequest, requestConfig).toResponse();的核心實現RetryableFeignLoadBalancer#execute

在這里插入圖片描述
FeignLoadBalancer是RetryableFeignLoadBalancer的父類型,構造RetryableFeignLoadBalancer時調用的構造方法new RetryableFeignLoadBalancer(lb, config, serverIntrospector, this.loadBalancedRetryFactory)會調用父類的public FeignLoadBalancer(ILoadBalancer lb, IClientConfig clientConfig, ServerIntrospector serverIntrospector) 方法,而RibbonClientConfiguration#ribbonClientConfig配置方法中所對應的IClientConfig會傳入此構造方法的clientConfig參數,因此這里的this.connectTimeout this.readTimeout都是ribbon的超時時間。
configOverride是feign超時配置或ribbon超時配置,而ribbon.connectTimeout(this.connectTimeout)this.connectTime超時參數是作為默認值的,所以說ribbon超時參數是會被覆蓋掉,它的優先級低(feign、ribbon超時參數同時存在時)

在這里插入圖片描述

在這里插入圖片描述

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/23411.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/23411.shtml
英文地址,請注明出處:http://en.pswp.cn/web/23411.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【Text2SQL 論文】How to prompt LLMs for Text2SQL

論文&#xff1a;How to Prompt LLMs for Text-to-SQL: A Study in Zero-shot, Single-domain, and Cross-domain Settings ???? arXiv:2305.11853, NeurlPS 2023 Code: GitHub 一、論文速讀 本文主要是在三種常見的 Text2SQL ICL settings 評估不同的 prompt constructio…

數據分析必備:一步步教你如何用Pandas做數據分析(18)

1、Pandas 串聯 Pandas 連接的操作實例 Pandas提供了各種功能&#xff0c;可以輕松地將Series&#xff0c;DataFrame和Panel對象組合在一起。 pd.concat(objs,axis0,joinouter,join_axesNone,ignore_indexFalse)objs ? 這是Series的序列或映射&#xff0c;DataFrame或Panel對…

【云嵐到家】-day01-項目熟悉-查詢區域服務開發

文章目錄 1 云嵐家政項目概述1.1 簡介1.2 項目業務流程1.3 項目業務模塊1.4 項目架構及技術棧1.5 學習后掌握能力 2 熟悉項目2.1 熟悉需求2.2 熟悉設計2.2.1 表結構2.2.2 熟悉工程結構2.2.3 jzo2o-foundations2.2.3.1 工程結構2.2.3.2 接口測試 3 開發區域服務模塊3.1 流程分析…

Python接口自動化之使用requests庫發送http請求

requests庫 ? 什么是Requests &#xff1f;Requests 是?Python語?編寫&#xff0c;基于urllib&#xff0c;采?Apache2 Licensed開源協議的 HTTP 庫。它? urllib 更加?便&#xff0c;可以節約我們?量的?作&#xff0c;完全滿?HTTP測試需求。 ? 安裝&#xff1a;cmd命…

docker 拉取不到鏡像的問題:拉取超時

error pulling image configuration: download failed after attempts6: dial tcp 31.13.94.10:443: i/o timeout 首先設置國內的鏡像源&#xff1a;復制下面直接執行 sudo mkdir -p /etc/docker sudo tee /etc/docker/daemon.json <<-EOF{"registry-mirrors"…

【POSIX】消息類的格式與使用

本文給出一個MacOS操作系統中的消息類的使用過程示例&#xff08;結合gencat命令&#xff0c;<nl_types.h>頭文件以及catopen,catgets,catclose3個函數&#xff09; 首先根據對應的操作系統&#xff0c;查看 gencat 命令 man gencat 可以詳細看到其中對于輸入文件&…

Spark MLlib 機器學習詳解

目錄 &#x1f349;引言 &#x1f349;Spark MLlib 簡介 &#x1f348; 主要特點 &#x1f348;常見應用場景 &#x1f349;安裝與配置 &#x1f349;數據處理與準備 &#x1f348;加載數據 &#x1f348;數據預處理 &#x1f349;分類模型 &#x1f348;邏輯回歸 &a…

? 傳知代碼 ? 輔助任務改進社交帖子多模態分類

&#x1f49b;前情提要&#x1f49b; 本文是傳知代碼平臺中的相關前沿知識與技術的分享~ 接下來我們即將進入一個全新的空間&#xff0c;對技術有一個全新的視角~ 本文所涉及所有資源均在傳知代碼平臺可獲取 以下的內容一定會讓你對AI 賦能時代有一個顛覆性的認識哦&#x…

【自然語言處理】【Scaling Law】語言模型物理學 第3.3部分:知識容量Scaling Laws

語言模型物理學3.3&#xff1a;知識容量Scaling Laws 論文名稱&#xff1a;Physics of Language Models: Part 3.3, Knowledge Capacity Scaling Laws 論文地址&#xff1a;https://arxiv.org/pdf/2404.05405 相關博客 【自然語言處理】【Scaling Law】Observational Scaling …

R語言探索與分析17-股票題目

Value at Risk&#xff08;VaR&#xff09;是一種統計技術&#xff0c;用于量化投資組合在正常市場條件下可能遭受的最大潛在損失。它是風險管理和金融領域中一個非常重要的概念。VaR通常以貨幣單位表示&#xff0c;用于估計在給定的置信水平和特定時間范圍內&#xff0c;投資組…

OpenCV的小部件最基本范例

OpenCV也有與PYQT類似的小部件&#xff0c;例如滑塊slider。OpenCV可以用與PYQT類似的“信號與槽”方法&#xff0c;也可以在函數中直接查詢小部件的值。 import cv2 import numpy as npcv2.namedWindow(Show1) image np.zeros((100, 400, 3), np.uint8) # 創建一個空白內容…

JavaScript基礎知識4(數組、函數、參數、作用域、具名和匿名函數、邏輯運算符短路、轉化布爾類型)

JavaScript基礎知識4&#xff08;數組、函數、參數、作用域、具名和匿名函數、邏輯運算符短路、轉化布爾類型&#xff09; 數組數組是什么&#xff1f;數組的基本使用定義數組和數組單元訪問數組和數組索引數據單元值類型數組長度屬性 操作數組 函數聲明和調用聲明&#xff08;…

(面試官問我微服務與naocs的使用我回答了如下,面試官讓我回去等通知)微服務拆分與nacos的配置使用

微服務架構 正常的小項目就是所有的功能集成在一個模塊中&#xff0c;這樣代碼之間不僅非常耦合&#xff0c;而且修改處理的時候也非常的麻煩&#xff0c;應對高并發時也不好處理&#xff0c;所以 我們可以使用微服務架構&#xff0c;對項目進行模塊之間的拆分&#xff0c;每一…

前端傳參數后端變量類型能夠接受到List卻無法接收到值

問題描述 今天寫了個接口&#xff0c;下圖所示 ReqVO里是這樣的&#xff1a; 然后前端去請求&#xff0c;從請求結果中看發現這里值是在的&#xff08;有經驗的可能就看出來了otherInfo.id: 這樣以參數后端是接收不到的&#xff0c;但是當時沒發現&#xff09; 傳進來后端…

維納運動的概念

維納運動&#xff08;Wiener Process&#xff09;&#xff0c;也稱為標準布朗運動&#xff0c;是一種重要的隨機過程&#xff0c;廣泛應用于數學、物理學和金融學等領域。它是一個連續時間的隨機過程&#xff0c;具有一些特殊的性質&#xff0c;使其成為描述隨機動態系統的經典…

GAT1399協議分析(8)--批量圖像查詢

一、請求消息定義 視頻圖像包含視頻片段、 圖像、 文件、 人員、 人臉、 機動車、 非機動車、 物品、 場景和視頻案事件、 視頻圖像標簽等對象 在消息體中,可以包含其中一種類,加上Data字段即可。 ImageInfo對象 二、請求消息實例 wireshark 抓包實例 請求: 文本化: /V…

制造執行MES系統在光伏行業的應用

全球對可再生能源的需求不斷增長&#xff0c;光伏能源作為一種清潔、可持續的能源形式&#xff0c;已經在廣泛應用中受到了廣泛關注。為滿足工業領域的光伏能源需求&#xff0c;光伏制造執行系統(MES)作為一種集成化的技術解決方案&#xff0c;提供了更高效、更可靠的解決方案。…

WPS的JSA算國產編程語言,IDE,腳本工具嗎?javascript代替VBA

現在wps用javascript代替VBA&#xff0c;應該算很成功了吧。 如果可以獨立出來變成一個腳本語言&#xff0c;簡單的IDE(本身也有類似VBA&#xff0c;不要寄宿在WPS里面運行&#xff0c;這樣就可以變成VBS一樣執行腳本了&#xff0c;用來開發按鍵精靈,LUA一樣的腳本很不錯 以下…

Activity->Activity中動態添加Fragment->Fragment回退棧BackStack

Fragment回退棧 Fragment回退棧用于管理Fragment的導航歷史(添加、刪除、替換)。每個Activity都有一個包含其所有Fragment的FragmentManager&#xff0c;調用其addToBackStack方法時&#xff0c;這個事務就會被添加到FragmentManager的回退棧中當用戶按下返回鍵時&#xff0c;…

MySQL報ERROR 2002 (HY000)解決

今天在連接客戶服務器時MySQL的時候報: ERROR 2002 (HY000): Can’t connect to local MySQL server through socket ‘/tmp/mysql/mysql.sock’ (2) [rootXXX ~]# mysql -uroot -p Enter password: ERROR 2002 (HY000): Can’t connect to local MySQL server through socket…