Hystrix配置实战及feign超时配置失效
一、feign超时配置失效
最近项目上遇见feign超时配置总是失效。导致feign调用超过2s之后就会超时,会进行自动重试,重复调用两次服务,并且还是指定接口。这就更加奇怪。最后通过观察以及源码调试,发现问题所在。在这里先说下原因。
原因:同一个服务feign组件做了拆分,使用contextId对feign拆分后的feign做了声明。配置超时配置的时候,不能再使用feign组件注解 @FeignClient里的name去做配置了,而应该是contextId里的名称
示例代码:
//A服务的基础业务接口
@FeignClient(contextId = "AServer", name = "AServer", configuration = FeignConfiguration.class)
public interface ABaseServer { } //A服务的个性化业务接口
@FeignClient(contextId = "ASpecialServiceServer", name = "AServer", configuration = FeignConfiguration.class)
public interface ASpecialServer { } //上面是对feign拆分后的声明
//错误的yml配置
feign:
client:
config:
#这里仍然使用了name作为超时配置,那么只有ABaseServer 里面声明的接口才会使用以下的配置,因为恰巧ABaseServer的contextId名称是AServer。
AServer:
connectTimeout: 60000
readTimeout: 60000 //正确的yml配置,手段一:配置上以contextId为声明来配置
feign:
client:
config:
#基础业务接口的超时配置
AServer:
connectTimeout: 60000
readTimeout: 60000
#个性化业务接口的超时配置
ASpecialServiceServer:
connectTimeout: 50000
readTimeout: 50000 //正确的yml配置,手段二:A服务全部使用default全局配置,Bserver单独声明,并不会使用全局配置
feign:
client:
config:
default:
connectTimeout: 60000
readTimeout: 60000
BServer:
connectTimeout: 30000
readTimeout: 30000
feign内部集成了ribbon做为了负载均衡的组件,ribbon也有相关超时配置,feign的超时配置不当也会造成超时失效,关于如何配置可以参考之前的一篇博客:https://www.cnblogs.com/wa1l-E/p/13994240.html
这次feign的超时不生效,主要原因是,项目上做了一次feign的拆分,即A服务调用B服务的接口由于过多,接口从功能模块和业务上做了feign组件的拆分,也就是spring容器中会有两个feign针对同一个服务。
问题1:拆分后,springboot在启动时,会报错,原因是针对同一个服务有多个feign 实例,而spring容器又默认是单例加载。
解决这个问题有两个方案:
1、
2、在feign注解定义上加上contextId来避免启动报错。示例代码如下:
@FeignClient(name = "A", contextId = "ABaseServiceServer", configuration = FeignConfiguration.class)
public interface AServer { } @FeignClient(name = "A", contextId = "ACustomServiceServer", configuration = FeignConfiguration.class)
public interface AServer { }
都是同一个服务的feign组件,但是contextId不同,解决了问题。
项目上采用了第二种解决手段,但也正是因为对解决问题没有做到追根刨底的精神,导致引入了feign超时失效的原因。
问题2:使用ContextId对feign做声明后,导致部分接口超时失效。
结论:在开篇时,结论已经说过,这里就不再赘述。主要说下原因以及定位问题的过程和解决方法。
定位过程:发现该问题时,首先发现是部分接口失效,当然是测试并观察,发现只有未使用contextId配置的feign组件的接口会超时。但是当时并不知道是contextId的声明影响。所以果断开撕源码。定位问题
首先Feign有一个内部类Builder,听名字就知道使用了建造者是设计模式,建造者适合创造属性多变的对象, 而Feign恰好具备这种特性,使用建造者设计模式在适合不过了。
Builder类有一个属性Options option这个Options类就是feign的超时配置声明。如下图:

再来看一下UML图

可以看到真正的配置就是再容器初始话feign的时候,初始化 builder的时候使用的配置就是真正使用的配置。那么接下来就好办了,使用我之前讲过的源码调试大法,开始调试,启动服务,断点开启,最后一路追踪,发现实例化的代码如下:
不知道启动后怎么调试找到相关代码的同学可以参考另一篇博客:https://www.cnblogs.com/wa1l-E/p/14115042.html 还是一句话,动手多实践。

97行见名其义:初始化Feign.builder,109行是关键代码,看名字就知道,配置feign,那么builder的option一定是在这里初始化的,我们一路追进去看看

到了上面的方法中,我们发现了尤其重要的两行代码,看名字就知道使用configure配置属性,那么在这里一定是使用配置去初始话Feign的超时相关配置,没有的话会使用默认的配置。
这里的方法就不赘述了,有兴趣的同学可以去断点看看,最关键的另一个发现是 在获取配置的时候,使用的是
contextId,这不由得和上面Feign注解 @FeignClient中声明的contextId关联起来,最后通过调试也发现,确实是这样。contextId源码注释是bean的显实声明名称,如果不配置默认使用beanName.到这里就发现问题了。
那么解决手段就简单了
解决手段:
手段一:如果拆分后的接口不需要做特殊的超时配置区分,那么使用default全局配置既可,至于其他的feign客户端,在做配置,便不会使用全局的配置。
手段二:如果拆分后的接口,超时配置是不一样的,那么使用contextId做超时配置才是正确的。
最后建议实际使用手段二,粒度更细。
二、Hystrix配置实战:
首先介绍一下上面Feign超时后,Hystrix配置后,会自动重试的原因,然后再介绍一下Hystrix的主要配置,搭建一个Hstrix-dashboard,然后通过一个接口的测试,通过dashBoard观察Hystrix的配置的。
1、Hystrix的配置
熔断配置:
#hystrix熔断器配置:(接口发生异常,服务调用方直接做熔断处理,返回提示,避免流量过大接口调用引起雪崩。)
#如果接口发生异常,那么会熔断,熔断开启。后面的请求不会再去进行服务远程调用,直接走熔断
#下面配置策略是: 10s滚动窗口期内,大于等于1个线程 失败率超过百分之50,则打开熔断开关.负责关闭熔断开关
#熔断开关打开后,后续请求直接走熔断,不会进行远程调用
hystrix.command.default.circuitBreaker.requestVolumeThreshold=1
hystrix.command.default.metrics.rollingStats.timeInMilliseconds=10000
hystrix.command.default.circuitBreaker.errorThresholdPercentage=50
#在5s后,熔断会进入 半开状态,会放入一部分请求进行远程调用,如果成功,则关闭熔断.如果失败,则继续打开熔断
hystrix.command.default.circuitBreaker.sleepWindowInMilliseconds=5000
降级配置:
#hystrix降级配置:(接口发生异常,服务调用方直接对接口进行降级处理,返回托底数据。和熔断的区别是一个有托底数据,一个没有。)
#超时打开,设置为70s,这里的超时时间必须大于Ribbon和feign的超时,因为小于Feign正常调用超时时间,直接会熔断.
hystrix.command.default.execution.timeout.enabled=true
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=70000
2、配置Hystrix-dashboard调试Hystrix熔断和降级配置
- 搭建Hystrix-dashboard: 没空的同学可以直接下载我之前搭建的: https://github.com/coffeebabeCGG/spring-cloud 这里就不赘述如何搭建了
- 启动项目后,需要填如要监控的服务地址:http://ip:port/context-path/actuator/hystrix.stream

从下图可以看到queryByPage接口的熔断目前是关闭状态。关于dashboard的详细参数说明,下面给大家补一张图。


最后:接口postMan的runtest批量调用接口测试,通过dashBoard观察接口的熔断情况,配置是否生效。就可以了解Hystrix的基本使用了。
Hystrix配置实战及feign超时配置失效的更多相关文章
- Spring cloud 超时配置总结
基准配置: eureka-server : 注册中心 端口号1000 service-A : 服务A端口号2000 service-B : 服务B 端口号3000 其中,B服务通过feign调用服务A ...
- Hystrix 超时配置的N种玩法
前阵子在我的知识星球中,有位朋友对我提了个问题,问我如何让Hystrix支持对接口级别的超时配置,今天给大家写篇文章,普及下Hystrix配置超时的几种方式. 至于以后你是用阿里的Sentinel还是 ...
- Feign 失败降级未生效和超时配置优先级问题
一.问题: 生产环境服务A 通过feign调用 服务B,服务A报警信息如下: 详细分析发现问题 (1)服务A调用服务B失败,未触发声明的失败降级操作 (2)同时配置ribbon和feign超时时间,优 ...
- spring coud Feign常用配置
Ribbon配置 在Feign中配置Ribbon非常简单,直接在application.properties中配置即可,如: # 设置连接超时时间 ribbon.ConnectTimeout=500 ...
- Spring Cloud Feign 自定义配置(重试、拦截与错误码处理) 实践
Spring Cloud Feign 自定义配置(重试.拦截与错误码处理) 实践 目录 Spring Cloud Feign 自定义配置(重试.拦截与错误码处理) 实践 引子 FeignClient的 ...
- redis 集群配置实战
文章转载自:http://hot66hot.iteye.com/blog/2050676 最近研究Redis-cluster,正好搭建了一个环境,遇到了很多坑,系统的总结下,等到redis3 rele ...
- zabbix proxy配置实战案例
zabbix proxy配置实战案例 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.zabbix proxy概述 上一篇博客我们分享了zabbix agent有两种工作模式,即 ...
- zabbix java gateway配置实战案例
zabbix java gateway配置实战案例 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.部署tomcat服务 博主推荐阅读: CentOS: https://www. ...
- 10 Dubbo 配置实战
Dubbo 配置实战 快速入门 dubbo 建议看这篇文章是在学习了快速入门 dubbo 那篇文章的基础上来学习 配置说明 文档地址 https://dubbo.apache.org/zh/index ...
随机推荐
- 由”二进制里不能有3“引发的对parseInt的思考
看到一道面试题,["1", "2", "3"].map(parseInt) 答案是多少? 心生好奇,做做看,发现卡住,没什么头绪.首先对pa ...
- DVWA(六):XSS-Reflected 反射型XSS全等级详解
XSS 概念: 由于web应用程序对用户的输入过滤不严,通过html注入篡改网页,插入恶意脚本,从而在用户浏览网页时,控制用户浏览器的一种攻击. XSS类型: Reflected(反射型):只是简单的 ...
- Something about 树链剖分
声明:部分思路与图片源于OI Wiki 关于树链剖分 树链剖分用于将树分割成若干条链的形式,以维护树上路径的信息. 树链剖分有多种形式,如 重链剖分,长链剖分 和用于 $LCT$ 的剖分,大多数情况下 ...
- NOIP 模拟 $36\; \rm Cicada 与排序$
题解 \(by\;zj\varphi\) 设 \(rk_{i,j}\) 表示第 \(i\) 个数最后在相同的数里排第 \(j\) 位的概率. 转移时用一个 \(dp\),\(dp_{i,j,0/1}\ ...
- [ES6深度解析]14:子类 Subclassing
我们描述了ES6中添加的新类系统,用于处理创建对象构造函数的琐碎情况.我们展示了如何使用它来编写如下代码: class Circle { constructor(radius) { this.radi ...
- HTML <form> 标签的 method 属性
定义和用法 method 属性规定如何发送表单数据(表单数据发送到 action 属性所规定的页面). 表单数据可以作为 URL 变量(method="get")或者 HTTP p ...
- springboot分页插件的使用
在springboot工程下的pom.xml中添加依赖 <!--分页 pagehelper --> <dependency> <groupId>com.github ...
- vue项目打包 部署nginx服务器 访问远程接口 本地json 跨域问题
本文建立在你已经在windows7上已经配好了nginx的前提下进行!!! 如果没有请移步至:https://www.cnblogs.com/jack1208-rose0203/p/5739765.h ...
- 解析和遍历一个HTML文档
如何解析一个HTML文档: String html = "<html><head><title>First parse</title>< ...
- Jackson的使用和定制
springmvc在使用注解@ResponseBody返回一个POJO对象时, 其内部会借助Jackson来完成POJO转化为JSON的工作. public class Message { priva ...