微服务中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方法中有调用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超时参数同时存在时)


相关文章:
微服务中feign远程调用相关的各种超时问题
1. 引言 在spring cloud微服中,feign远程调用可能是大家每天都接触到东西,但很多同学却没咋搞清楚这里边的各种超时问题,生产环境可能会蹦出各种奇怪的问题。 首先说下结论: 1)只使用feign组件,不使用ribbion组件&…...
springboot整合chatgpt,并且让其可以记录上下文
整合很简单,不过需要几个小条件 1.必须要有openai官方的key 2.国内需要有代理服务器或者国外的服务器把项目部署出去也没问题 我没有使用spring的springAI,听说很方便,日后有机会去体验体验,我今天用了两种方式整合了gpt 1.Ch…...
CTP前端:解码数字世界的魔法师
CTP前端:解码数字世界的魔法师 CTP前端,一个充满神秘与魅力的职业,他们在数字世界中挥舞着魔法棒,创造着令人惊叹的奇迹。那么,CTP前端究竟是做什么的呢?让我们从四个方面、五个方面、六个方面和七个方面&…...
rabbitmq的交换机类型以及他们的区别
RabbitMQ中有四种主要的交换机类型,它们是:Direct,Topic,Fanout,Headers。 Direct(直连交换机):接收到消息后,会将消息发送到与消息的routing key完全匹配的队列上。Dire…...
理解不同层的表示(layer representations)
在机器学习和深度学习领域,特别是在处理音频和自然语言处理(NLP)任务时,"层的表示"(layer representations)通常是指神经网络不同层在处理输入数据时生成的特征或嵌入。这些表示捕获了输入数据的…...
原生js访问http获取数据的方法
在原生JavaScript中,直接通过浏览器端的JavaScript访问HTTP接口获取数据通常涉及XMLHttpRequest对象或现代的fetch API。 1. 使用XMLHttpRequest XMLHttpRequest是一个老旧的API,但在某些情况下仍然很有用。以下是一个简单的例子: javascr…...
Windows 2000 Server:安全配置终极指南
"远古技术,仅供娱乐" 💭 前言:Windows 2000 服务器在当时的市场中占据了很大的比例,主要原因包括操作简单和易于管理,但也经常因为安全性问题受到谴责,Windows 2000 的安全性真的那么差吗&#x…...
基于 FastAI 文本迁移学习的情感分类(93%+Accuracy)
前言 系列专栏:【深度学习:算法项目实战】✨︎ 涉及医疗健康、财经金融、商业零售、食品饮料、运动健身、交通运输、环境科学、社交媒体以及文本和图像处理等诸多领域,讨论了各种复杂的深度神经网络思想,如卷积神经网络、循环神经网络、生成对抗网络、门控循环单元、长短期记…...
集成Google Authenticator实现多因素认证(MFA)
目录 参考1、应用背景2、多因素认证3、谷歌google authenticator集成用法3.1、原理3.2、 MFA绑定3.2.1、 用户输入用户名密码登录3.2.2、检查是否已经绑定MFA(检查数据库是否保存该用户的google secret)3.2.3、谷歌身份证认证器扫描绑定3.2.4、手动测试验…...
网关(Gateway)- 自定义过滤器工厂
自定义过滤工厂类 DemoGatewayFilterFactory package com.learning.springcloud.custom;import org.apache.commons.lang.StringUtils; import org.springframework.cloud.gateway.filter.GatewayFilter; import org.springframework.cloud.gateway.filter.GatewayFilterChai…...
HTML静态网页成品作业(HTML+CSS)—— 香奈儿香水介绍网页(1个页面)
🎉不定期分享源码,关注不丢失哦 文章目录 一、作品介绍二、作品演示三、代码目录四、网站代码HTML部分代码 五、源码获取 一、作品介绍 🏷️本套采用HTMLCSS,未使用Javacsript代码,共有1个页面。 二、作品演示 三、代…...
C++11 lambda表达式和包装器
C11 lambda表达式和包装器 一.lambda表达式1.lambda表达式的引入2.基本语法和使用1.基本语法2.使用1.传值捕捉的错误之处2.传引用捕捉 3.lambda表达式的底层原理4.lambda的特殊之处5.lambda配合decltype的新玩法 二.function包装器1.概念2.包装函数1.包装普通函数2.包装成员函数…...
3. MySQL 数据表的基本操作
文章目录 【 1. MySQL 创建数据表 】【 2. MySQL 查看表 】2.1 查看表的属性DESCRIBE/DESC 以表格的形式展示表属性SHOW CREATE TABLE 以SQL语句的形式展示表属性 2.2 查看表的内容 【 3. MySQL 修改数据表结构 】3.1 修改表名3.2 修改表字符集3.3 添加字段在末尾添加字段在开头…...
Linux命令篇(一):文件管理部分
💝💝💝首先,欢迎各位来到我的博客,很高兴能够在这里和您见面!希望您在这里不仅可以有所收获,同时也能感受到一份轻松欢乐的氛围,祝你生活愉快! 文章目录 1、cat命令常用参…...
IP协议1.0
基本概念: • 主机: 配有IP地址, 但是不进⾏路由控制的设备; • 路由器: 即配有IP地址, ⼜能进⾏路由控制; • 节点: 主机和路由器的统称; IP协议的报头 • 4位版本号(version): 指定IP协议的版本, 对于IPv4来说, 就是4. • 4位头部⻓度(header length): IP头部的⻓…...
源码编译安装LNMP
LNMP包含: linux、Nginx、Mysql、php LNMP的工作原理 : 由客户端发送页面请求给Nginx,Nginx会根据location匹配用户访问请求的URL路径判断是静态还是动态,静态的一般是以 .html .htm .css .shtml结尾,动态的一般是以 .…...
安装Chrome扩展程序来 一键禁用页面上的所有动画和过渡。有那些扩展程序推荐一下
要安装Chrome扩展程序来一键禁用页面上的所有动画和过渡,以下是一些推荐的扩展程序: Toggle CSS Animations and Transitions 功能:此扩展程序允许用户轻松地在网页上切换CSS动画和过渡的开启与关闭状态。使用方法:安装后&#x…...
读人工智能时代与人类未来笔记19_读后总结与感想兼导读
1. 基本信息 人工智能时代与人类未来 (美)亨利基辛格,(美)埃里克施密特,(美)丹尼尔胡滕洛赫尔 著 中信出版社,2023年6月出版 1.1. 读薄率 书籍总字数145千字,笔记总字数39934字。 读薄率39934145000≈27.5% 1.2. 读厚方向 千脑智能 脑机穿越 未来呼啸而来 …...
个人影响力
华人出了个黄仁勋,世界级影响力,还是近代华人历史首次出现具有如此影响力的人。凭借的逻辑是什呢?在人工智能领域有巨大影响力。...
OBS实现多路并发推流
OBS实现多路并发推流 解决方案速览相关依赖下载安装多路推流 解决方案速览 利用OBS进行本地直播画面的构建。 使用Multiple RTMP outputs plugin进行多路并发推流。 相关依赖下载安装 OBS软件 # OBS官网 https://obsproject.com/zh-cnMultiple RTMP outputs plugin # 插件官网…...
AI-调查研究-01-正念冥想有用吗?对健康的影响及科学指南
点一下关注吧!!!非常感谢!!持续更新!!! 🚀 AI篇持续更新中!(长期更新) 目前2025年06月05日更新到: AI炼丹日志-28 - Aud…...
从零实现富文本编辑器#5-编辑器选区模型的状态结构表达
先前我们总结了浏览器选区模型的交互策略,并且实现了基本的选区操作,还调研了自绘选区的实现。那么相对的,我们还需要设计编辑器的选区表达,也可以称为模型选区。编辑器中应用变更时的操作范围,就是以模型选区为基准来…...
家政维修平台实战20:权限设计
目录 1 获取工人信息2 搭建工人入口3 权限判断总结 目前我们已经搭建好了基础的用户体系,主要是分成几个表,用户表我们是记录用户的基础信息,包括手机、昵称、头像。而工人和员工各有各的表。那么就有一个问题,不同的角色…...
Redis数据倾斜问题解决
Redis 数据倾斜问题解析与解决方案 什么是 Redis 数据倾斜 Redis 数据倾斜指的是在 Redis 集群中,部分节点存储的数据量或访问量远高于其他节点,导致这些节点负载过高,影响整体性能。 数据倾斜的主要表现 部分节点内存使用率远高于其他节…...
Java线上CPU飙高问题排查全指南
一、引言 在Java应用的线上运行环境中,CPU飙高是一个常见且棘手的性能问题。当系统出现CPU飙高时,通常会导致应用响应缓慢,甚至服务不可用,严重影响用户体验和业务运行。因此,掌握一套科学有效的CPU飙高问题排查方法&…...
深度学习习题2
1.如果增加神经网络的宽度,精确度会增加到一个特定阈值后,便开始降低。造成这一现象的可能原因是什么? A、即使增加卷积核的数量,只有少部分的核会被用作预测 B、当卷积核数量增加时,神经网络的预测能力会降低 C、当卷…...
华硕a豆14 Air香氛版,美学与科技的馨香融合
在快节奏的现代生活中,我们渴望一个能激发创想、愉悦感官的工作与生活伙伴,它不仅是冰冷的科技工具,更能触动我们内心深处的细腻情感。正是在这样的期许下,华硕a豆14 Air香氛版翩然而至,它以一种前所未有的方式&#x…...
Xen Server服务器释放磁盘空间
disk.sh #!/bin/bashcd /run/sr-mount/e54f0646-ae11-0457-b64f-eba4673b824c # 全部虚拟机物理磁盘文件存储 a$(ls -l | awk {print $NF} | cut -d. -f1) # 使用中的虚拟机物理磁盘文件 b$(xe vm-disk-list --multiple | grep uuid | awk {print $NF})printf "%s\n"…...
MySQL JOIN 表过多的优化思路
当 MySQL 查询涉及大量表 JOIN 时,性能会显著下降。以下是优化思路和简易实现方法: 一、核心优化思路 减少 JOIN 数量 数据冗余:添加必要的冗余字段(如订单表直接存储用户名)合并表:将频繁关联的小表合并成…...
抽象类和接口(全)
一、抽象类 1.概念:如果⼀个类中没有包含⾜够的信息来描绘⼀个具体的对象,这样的类就是抽象类。 像是没有实际⼯作的⽅法,我们可以把它设计成⼀个抽象⽅法,包含抽象⽅法的类我们称为抽象类。 2.语法 在Java中,⼀个类如果被 abs…...
