spring-cloud服务网关中的Timeout设置
大家在初次使用spring-cloud的gateway的时候,肯定会被里面各种的Timeout搞得晕头转向。hytrix有设置,ribbon也有。我们一开始也是乱设一桶,Github上各种项目里也没几个设置正确的。对Timeout的研究源于一次log中的warning
The Hystrix timeout of 60000 ms for the command “foo” is set lower than the combination of the Ribbon read and connect timeout, 200000ms.
hytrix超时时间
log出自AbstractRibbonCommand.java
,那么索性研究一下源码。
假设:
- 这里gateway会请求一个serviceName=foo的服务
protected static int getHystrixTimeout(IClientConfig config, String commandKey) {int ribbonTimeout = getRibbonTimeout(config, commandKey);DynamicPropertyFactory dynamicPropertyFactory = DynamicPropertyFactory.getInstance();// 获取默认的hytrix超时时间int defaultHystrixTimeout = dynamicPropertyFactory.getIntProperty("hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds",0).get();// 获取具体服务的hytrix超时时间,这里应该是hystrix.command.foo.execution.isolation.thread.timeoutInMillisecondsint commandHystrixTimeout = dynamicPropertyFactory.getIntProperty("hystrix.command." + commandKey + ".execution.isolation.thread.timeoutInMilliseconds",0).get();int hystrixTimeout;// hystrixTimeout的优先级是 具体服务的hytrix超时时间 > 默认的hytrix超时时间 > ribbon超时时间if(commandHystrixTimeout > 0) {hystrixTimeout = commandHystrixTimeout;}else if(defaultHystrixTimeout > 0) {hystrixTimeout = defaultHystrixTimeout;} else {hystrixTimeout = ribbonTimeout;}// 如果默认的或者具体服务的hytrix超时时间小于ribbon超时时间就会警告if(hystrixTimeout < ribbonTimeout) {LOGGER.warn("The Hystrix timeout of " + hystrixTimeout + "ms for the command " + commandKey +" is set lower than the combination of the Ribbon read and connect timeout, " + ribbonTimeout + "ms.");}return hystrixTimeout;
}
紧接着,看一下我们的配置是什么
hystrix:command:default:execution:isolation:thread:timeoutInMilliseconds: 60000ribbon:ReadTimeout: 50000ConnectTimeout: 50000MaxAutoRetries: 0MaxAutoRetriesNextServer: 1
ribbon超时时间
这里ribbon的超时时间是50000ms,那么为什么log中写的ribbon时间是200000ms?
继续分析源码:
protected static int getRibbonTimeout(IClientConfig config, String commandKey) {int ribbonTimeout;// 这是比较异常的情况,不说if (config == null) {ribbonTimeout = RibbonClientConfiguration.DEFAULT_READ_TIMEOUT + RibbonClientConfiguration.DEFAULT_CONNECT_TIMEOUT;} else {// 这里获取了四个参数,ReadTimeout,ConnectTimeout,MaxAutoRetries, MaxAutoRetriesNextServerint ribbonReadTimeout = getTimeout(config, commandKey, "ReadTimeout",IClientConfigKey.Keys.ReadTimeout, RibbonClientConfiguration.DEFAULT_READ_TIMEOUT);int ribbonConnectTimeout = getTimeout(config, commandKey, "ConnectTimeout",IClientConfigKey.Keys.ConnectTimeout, RibbonClientConfiguration.DEFAULT_CONNECT_TIMEOUT);int maxAutoRetries = getTimeout(config, commandKey, "MaxAutoRetries",IClientConfigKey.Keys.MaxAutoRetries, DefaultClientConfigImpl.DEFAULT_MAX_AUTO_RETRIES);int maxAutoRetriesNextServer = getTimeout(config, commandKey, "MaxAutoRetriesNextServer",IClientConfigKey.Keys.MaxAutoRetriesNextServer, DefaultClientConfigImpl.DEFAULT_MAX_AUTO_RETRIES_NEXT_SERVER);// 原来ribbonTimeout的计算方法在这里,以上文的设置为例// ribbonTimeout = (50000 + 50000) * (0 + 1) * (1 + 1) = 200000ribbonTimeout = (ribbonReadTimeout + ribbonConnectTimeout) * (maxAutoRetries + 1) * (maxAutoRetriesNextServer + 1);}return ribbonTimeout;
}
可以看到ribbonTimeout是一个总时间,所以从逻辑上来讲,作者希望hystrixTimeout要大于ribbonTimeout,否则hystrix熔断了以后,ribbon的重试就都没有意义了。
ribbon单服务设置
到这里最前面的疑问已经解开了,但是hytrix可以分服务设置timeout,ribbon可不可以? 源码走起,这里看的文件是DefaultClientConfigImpl.java
// 这是获取配置的入口方法,如果是null,那么用默认值
// 所有ribbon的默认值的都在该类中设置了,可以自己看一下
public <T> T get(IClientConfigKey<T> key, T defaultValue) {T value = get(key);if (value == null) {value = defaultValue;}return value;
}
// 这是核心方法
protected Object getProperty(String key) {if (enableDynamicProperties) {String dynamicValue = null;DynamicStringProperty dynamicProperty = dynamicProperties.get(key);// dynamicProperties其实是一个缓存,首次访问foo服务的时候会加载if (dynamicProperty != null) {dynamicValue = dynamicProperty.get();}// 如果缓存没有,那么就再获取一次,注意这里的getConfigKey(key)是生成key的方法if (dynamicValue == null) {dynamicValue = DynamicProperty.getInstance(getConfigKey(key)).getString();// 如果还是没有取默认值,getDefaultPropName(key)生成key的方法if (dynamicValue == null) {dynamicValue = DynamicProperty.getInstance(getDefaultPropName(key)).getString();}}if (dynamicValue != null) {return dynamicValue;}}return properties.get(key);
}
以我们的服务为例:
getConfigKey(key)
returns foo.ribbon.ReadTimeout
getDefaultPropName(key)
returns ribbon.ReadTimeout
一目了然,{serviceName}.ribbon.{propertyName}
就可以了。
小结
感觉ribbon和hytrix的配置获取源码略微有点乱,所以也导致大家在设置的时候有些无所适从。spring-cloud
的代码一直在迭代,无论github上还是文档可能都相对滞后,这时候阅读源码并且动手debug一下是最能接近事实真相的了。
原文
spring-cloud服务网关中的Timeout设置相关推荐
- Spring Cloud中Feign如何统一设置验证token
前面我们大致的聊了下如何保证各个微服务之前调用的认证问题 Spring Cloud中如何保证各个微服务之间调用的安全性 Spring Cloud中如何保证各个微服务之间调用的安全性(下篇) 原理是通过 ...
- Spring Cloud Hystrix 进行服务熔断设置时,报错找不到对应的服务熔断方法
问题描述:在进行服务熔断时出现 [Request processing failed; nested exception is com.netflix.hystrix.contrib.javanica ...
- Spring Cloud Alibaba 微服务详细笔记
文章目录 SpringCloud 一.微服务概述 1.1.什么是微服务? 1.2.为什么是微服务? 1.3.架构演变 1.4.微服务的解决方案 二.什么是SpringCloud 2.1.官方定义 2. ...
- Spring Cloud微服务系统架构的一些简单介绍和使用
Spring Cloud 目录 特征 云原生应用程序 Spring Cloud上下文:应用程序上下文服务 引导应用程序上下文 应用程序上下文层次结构 改变Bootstrap的位置Properties ...
- Spring Cloud Gateway 3.1.3最新版中文手册官网2022
Spring Cloud Gateway 3.1.3 该项目提供了一个库,用于在 Spring WebFlux 之上构建 API 网关.Spring Cloud Gateway 旨在提供一种简单而有效 ...
- Spring Cloud Kubernetes 中文文档
本参考指南介绍了如何使用Spring Cloud Kubernetes. 1.为什么需要Spring Cloud Kubernetes? Spring Cloud Kubernetes提供了使用Kub ...
- Spring Cloud Dalston.RELEASE中文文档
Spring Cloud Dalston.RELEASE中文文档 Spring Cloud 目录 特性 云原生应用程序 Spring Cloud上下文:应用程序上下文服务 引导应用程序上下文 应用程序 ...
- 网关 翻译版本 spring cloud gateway
Spring Cloud Gateway 官网原文地址 https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html ...
- Spring Cloud 参数
encrypt说明 名称 默 认 描述 encrypt.fail-on-error true 标记说,如果存在加密或解密错误,进程将失败. encrypt.key 对称密钥.作为一个更强大的替代方 ...
最新文章
- extmail mysql数据库 重启_centos 5.8 x86_64下安装mysql+postfix+extmail+extman+courier-authlib+courier-imap...
- 微服务和SOA架构的区别
- oracle主从表分离怎么实时更新数据_高可用数据库主从复制延时的解决方案
- BOMbing The System
- thinkphp v5.0.11漏洞_ThinkPHP5丨远程代码执行漏洞动态分析
- php中gd为什么是乱码的,php gd库中文乱码怎么解决?
- C++远程dll注入到QQ聊天工具
- 如何应对内网安全的那些新挑战——威胁不断,防御不止
- 库克看下!华为MatePad 11月25日发布:剑指苹果
- CentOS 6.5 + Nginx 1.8.0 + PHP 5.6(with PHP-FPM) 负载均衡源码安装 之 (三)Nginx负载均衡配置...
- 把数组变换成字符串(8)
- 【5】线性反馈移位寄存器
- 如何卸载 adobe creative cloud?
- 北大计算机陈旭,北大图灵班——欢迎来到计算机王国
- 山东理工大学ACM平台题答案 1134 数列求和
- windows上QQ机器人搭建教程
- win11电脑内存占用过高的解决办法
- Python分析抖音数据,让视频爆起来
- lua小技巧(二)——lua全局变量的检测
- 原生js完成拼图小游戏
热门文章
- java房屋装修公司业务管理系统
- WM6模拟器(测试软件的好工具)使用手册
- 利用matlab程序分别设计一正弦型信号_【电力电子】【2013.06】【含源码】永磁同步电动机三相逆变器的设计...
- php解压base64编码,PHP函数分享之解压缩base64压缩文件
- 树莓派使用DHT11测量温湿度
- iOS16图标文字阴影如何去掉?分享阴影不显示的方法!
- git pull --rebase 出错处理
- 关于UBNT网桥真实吞吐量
- 前端面试—网站性能优化
- 通过云速搭CADT实现云原生分布式数据库PolarDB-X 2.0的部署