大家在初次使用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设置相关推荐

  1. Spring Cloud中Feign如何统一设置验证token

    前面我们大致的聊了下如何保证各个微服务之前调用的认证问题 Spring Cloud中如何保证各个微服务之间调用的安全性 Spring Cloud中如何保证各个微服务之间调用的安全性(下篇) 原理是通过 ...

  2. Spring Cloud Hystrix 进行服务熔断设置时,报错找不到对应的服务熔断方法

    问题描述:在进行服务熔断时出现 [Request processing failed; nested exception is com.netflix.hystrix.contrib.javanica ...

  3. Spring Cloud Alibaba 微服务详细笔记

    文章目录 SpringCloud 一.微服务概述 1.1.什么是微服务? 1.2.为什么是微服务? 1.3.架构演变 1.4.微服务的解决方案 二.什么是SpringCloud 2.1.官方定义 2. ...

  4. Spring Cloud微服务系统架构的一些简单介绍和使用

    Spring Cloud 目录 特征 云原生应用程序 Spring Cloud上下文:应用程序上下文服务 引导应用程序上下文 应用程序上下文层次结构 改变Bootstrap的位置Properties ...

  5. Spring Cloud Gateway 3.1.3最新版中文手册官网2022

    Spring Cloud Gateway 3.1.3 该项目提供了一个库,用于在 Spring WebFlux 之上构建 API 网关.Spring Cloud Gateway 旨在提供一种简单而有效 ...

  6. Spring Cloud Kubernetes 中文文档

    本参考指南介绍了如何使用Spring Cloud Kubernetes. 1.为什么需要Spring Cloud Kubernetes? Spring Cloud Kubernetes提供了使用Kub ...

  7. Spring Cloud Dalston.RELEASE中文文档

    Spring Cloud Dalston.RELEASE中文文档 Spring Cloud 目录 特性 云原生应用程序 Spring Cloud上下文:应用程序上下文服务 引导应用程序上下文 应用程序 ...

  8. 网关 翻译版本 spring cloud gateway

    Spring Cloud Gateway 官网原文地址 https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html ...

  9. Spring Cloud 参数

    encrypt说明 名称 默 认 描述 encrypt.fail-on-error true 标记说,如果存在加密或解密错误,进程将失败. encrypt.key   对称密钥.作为一个更强大的替代方 ...

最新文章

  1. extmail mysql数据库 重启_centos 5.8 x86_64下安装mysql+postfix+extmail+extman+courier-authlib+courier-imap...
  2. 微服务和SOA架构的区别
  3. oracle主从表分离怎么实时更新数据_高可用数据库主从复制延时的解决方案
  4. BOMbing The System
  5. thinkphp v5.0.11漏洞_ThinkPHP5丨远程代码执行漏洞动态分析
  6. php中gd为什么是乱码的,php gd库中文乱码怎么解决?
  7. C++远程dll注入到QQ聊天工具
  8. 如何应对内网安全的那些新挑战——威胁不断,防御不止
  9. 库克看下!华为MatePad 11月25日发布:剑指苹果
  10. CentOS 6.5 + Nginx 1.8.0 + PHP 5.6(with PHP-FPM) 负载均衡源码安装 之 (三)Nginx负载均衡配置...
  11. 把数组变换成字符串(8)
  12. 【5】线性反馈移位寄存器
  13. 如何卸载 adobe creative cloud?
  14. 北大计算机陈旭,北大图灵班——欢迎来到计算机王国
  15. 山东理工大学ACM平台题答案 1134 数列求和
  16. windows上QQ机器人搭建教程
  17. win11电脑内存占用过高的解决办法
  18. Python分析抖音数据,让视频爆起来
  19. lua小技巧(二)——lua全局变量的检测
  20. 原生js完成拼图小游戏

热门文章

  1. java房屋装修公司业务管理系统
  2. WM6模拟器(测试软件的好工具)使用手册
  3. 利用matlab程序分别设计一正弦型信号_【电力电子】【2013.06】【含源码】永磁同步电动机三相逆变器的设计...
  4. php解压base64编码,PHP函数分享之解压缩base64压缩文件
  5. 树莓派使用DHT11测量温湿度
  6. iOS16图标文字阴影如何去掉?分享阴影不显示的方法!
  7. git pull --rebase 出错处理
  8. 关于UBNT网桥真实吞吐量
  9. 前端面试—网站性能优化
  10. 通过云速搭CADT实现云原生分布式数据库PolarDB-X 2.0的部署