定时任务与feign超时的纠葛,该咋优化?
1 背景
业务定时器应用半夜经常会触发熔断异常的告警邮件

根据邮件提示的类找到归纳以下表格
| 编号 | 报错方法 | 接口所属应用 | 所属定时任务类 |
|---|---|---|---|
| A | VipTradeReportFeignService#getShopTradeReportByDate | pinka-mod-stats | ShopOrderSturctureTask |
| B | VipMemberStatsFeignService#statMemberRecord | pinka-mod-stats | MemberStatTask |
| C | VipPartnerWalletFeignService.handlePartnerWithdraw | pinka-mod-customer | PartnerWithdrawCheckTask |
| D | VipWeixinBabyActivityFeignService.getBabyActivityNoticePage | pinka-mod-weixin | VipWeixinBabyNoticeTask |
以上AD都是在一个分布式定时器事件处理应用(pinka-mod-scheduler)中对外的feign微服务调用产生的,相当于4类任务,每类都会调1次或多次外部feign微服务接口,而其中的AD接口发生了问题
其中A和B都是如下形式的异常
com.netflix.hystrix.exception.HystrixTimeoutException
at com.netflix.hystrix.AbstractCommand$HystrixObservableTimeoutOperator$1$1.run(AbstractCommand.java:1154)
at com.netflix.hystrix.strategy.concurrency.HystrixContextRunnable$1.call(HystrixContextRunnable.java:45)
at com.netflix.hystrix.strategy.concurrency.HystrixContextRunnable$1.call(HystrixContextRunnable.java:41)
...
而C和D都是如下形式的异常
feign.RetryableException: 10.13.32.111:56000 failed to respond executing POST http://pinka-mod-customer/vip/partner/wallet/handlePartnerWithdraw
at feign.FeignException.errorExecuting(FeignException.java:67)
at feign.SynchronousMethodHandler.executeAndDecode(SynchronousMethodHandler.java:104)
at feign.SynchronousMethodHandler.invoke(SynchronousMethodHandler.java:76)
at feign.hystrix.HystrixInvocationHandler$1.run(HystrixInvocationHandler.java:114)
...
Caused by: org.apache.http.NoHttpResponseException: 10.13.32.111:56000 failed to respond
at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:141)
at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:56)
at org.apache.http.impl.io.AbstractMessageParser.parse(AbstractMessageParser.java:259)
...
2 追查
2.1 HystrixTimeoutException超时异常
A与B的异常几乎每天都发生,且提示很明显,是Hystrix中设置了超时时间(目前为10s),并且执行超时导致的。为何会超时?去接口实现发现是有for循环场景的耗时逻辑

通过Kibana日志系统查历史执行耗时,也可以发现都基本>13s,所以这类异常基本确因

2.1.1 解决与思考
这其实是一个很典型场景,定时器任务执行并且处理逻辑是在另外一个微服务中,而处理逻辑属于复杂耗时,怎么办?
A. 增加超时时间,这是个粗暴的思路,因为设长了可能导致更大的问题,因为超时本来就是为了fastfail,设20s那之后可能还会遇到要30s甚至更久的场景。所以这个方案不能用在所有调用的公共默认超时时间上;
但是可以考虑用在某些接口上,比如VipTradeReportFeignService#getShopTradeReportByDate接口评估正常耗时就是要15s以上,那就单独为其设置。相关配置方式:
#默认公共超时
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=10000
#单独为某个feign接口设置超时
hystrix.command."FeignService#sayHello(String)".execution.isolation.thread.timeoutInMilliseconds=15000
B. 优化接口提供方的逻辑执行时间。比如上述VipTradeReportFeignService#getShopTradeReportByDate中的for循环,能否移到接口调用方,相当于接口提供方每次只执行for循环的1次操作。说白了就是确保接口返回要在超时时间内,这也符合微服务接口的设计原则。
C. 还有种思路是接口处理异步化,即接口提供方立刻返回,自己再用异步线程去处理最终逻辑。但是单纯这样会导致任务执行不可靠,即接口返回成功不代表真实一定执行成功了,如果此时接口提供方重启或异常导致耗时的异步逻辑执行一半就中断了,反而无法利用分布式定时任务调度的机制去重试执行等。所以使用此思路时,接口立刻返回但不能立刻将任务也作为成功执行完毕,需要配合一些异步通知机制,即接口提供方真实成功结束耗时操作,通知给接口调用方,接口调用方再将任务作为成功返回上报。
2.2 feign.RetryableException failed to respond executing 异常
这是C和D的异常,是随机低频告警。看字面意思是接口请求无响应,再结合邮件中的“熔断”字眼就自然推测是接口提供应用的问题了(事后证明被“熔断”字眼坑了)。所以去追查接口所属应用pinka-mod-customer在告警前后的监控指标,发现tcp连接、CPU、内存、网络流量表现都没什么异常状况。另外如果是熔断,那此接口必然得是调用失败多次呀,而每次定时任务对该接口调用却只有一次。
这时候查看接口提供方Controller层日志,发现告警时刻确实提供方没进入controller处理。

由此推测,提供方应用本身并无问题。而查看调用方应用日志和性能指标,在那个时刻也无异常情况,还在不断向其他应用调用产生日志。再结合这个异常日志,推测原因是由于调用方与提供方某次调用的网络闪断导致的(所以是随机低频)。
但为何会开启“熔断”,这个还无法解释。此时去追查邮件告警的代码源头,告警本质是通过重写了openfeign官方的HystrixCommand创建逻辑中的getFallback方法实现的,即进入fallback逻辑就会发邮件

此时真相大白了,其实只是进了fallback降级,并不代表开启熔断,比如在HystrixCommand的run中抛出异常会进fallback,run执行超时会进fallback,熔断也会进fallback。即A~D这些异常,虽然邮件写的是熔断,但其实都没开启熔断,而只是进了fallback降级!
所以feign.RetryableException failed to respond executing这个其实只是一次偶然的调用失败进了fallback而已,并没之前猜想的那么复杂。
2.2.1 解决与思考
邮件告警逻辑自然是要修改,区分熔断和降级。如果要判断熔断,可以用如下方法
protected Object getFallback() {
if (this.isCircuitBreakerOpen()) {
// 熔断告警方式
sendExceptionEmail(...);
}else{
// 非熔断降级告警,如果无需告警也可不写
sendExceptionEmail(...);
}
....
}
“架构人生,迭代生命” ——深邃老夏,搜索summer_deep微信公众号可获取更多帮助
定时任务与feign超时的纠葛,该咋优化?的更多相关文章
- Hystrix配置实战及feign超时配置失效
一.feign超时配置失效 最近项目上遇见feign超时配置总是失效.导致feign调用超过2s之后就会超时,会进行自动重试,重复调用两次服务,并且还是指定接口.这就更加奇怪.最后通过观察以及源码调试 ...
- .NET 纯原生实现 Cron 定时任务执行,未依赖第三方组件 (Timer 优化版)
在上个月写过一篇 .NET 纯原生实现 Cron 定时任务执行,未依赖第三方组件 的文章,当时 CronSchedule 的实现是使用了,每个服务都独立进入到一个 while 循环中,进行定期扫描是否 ...
- springcoud feign超时的问题
配置 #开启超时控制 打开feign-hystix feign.hystrix.enabled=true ribbon.ReadTimeout= ribbon.ConnectTimeout= #如果e ...
- Feign超时设置
转-原文:https://xli1224.github.io/2017/09/22/configure-feign/ 在分析 Feign 源码的时候,我们看到 Feign 构建代理对象是分了几层的,一 ...
- Feign 超时设置
问题描述 微服务之间使用 Feign 调用,偶发超时问题,配置如下: feign: client: config: default: connectTimeout: 10000 readTimeout ...
- Feign超时不生效问题
使用Feign作为RPC调用组件,可以配置连接超时和读取超时两个参数 使用Feign配置超时需要注意:Feign内部使用了负载均衡组件Ribbon,而Ribbon本身也有连接超时和读取超时相关配置一. ...
- mysql事件(定时任务)处理超时失效订单
MySQL事件(定时任务) https://blog.csdn.net/pan_junbiao/article/details/86489237 UPDATE wz_mer_goods_spec as ...
- springcloud 设置feign超时时间
转载网址:http://www.pianshen.com/article/187038775/
- java 异步查询转同步多种实现方式:循环等待,CountDownLatch,Spring EventListener,超时处理和空循环性能优化
异步转同步 业务需求 有些接口查询反馈结果是异步返回的,无法立刻获取查询结果. 正常处理逻辑 触发异步操作,然后传递一个唯一标识. 等到异步结果返回,根据传入的唯一标识,匹配此次结果. 如何转换为同步 ...
随机推荐
- SPSSAU新功能上线:高级公式、综合得分一键计算!
一直关注我们的朋友们一定会发现,近期SPSSAU增添了很多新功能. 我们精挑细选出6个最常使用的功能,介绍给大家,看看这些新功能你有没有解锁成功呢? 01 一键删除无效样本 “无效样本”功能中,添加了 ...
- (数据科学学习手札94)QGIS+Conda+jupyter玩转Python GIS
本文完整代码及数据已上传至我的Github仓库https://github.com/CNFeffery/DataScienceStudyNotes 1 简介 QGIS随着近些年的发展,得益于其开源免费 ...
- 类的加载,链接和初始化——1运行时常量池(来自于java虚拟机规范英文版本+本人的翻译和理解)
加载(loading):通过一个特定的名字,找到类或接口的二进制表示,并通过这个二进制表示创建一个类或接口的过程. 链接:是获取类或接口并把它结合到JVM的运行时状态中,以让类或接口可以被执行 初始化 ...
- synchronized的实现原理——对象头解密
前言 并发编程式Java基础,同时也是Java最难的一部分,因为与底层操作系统和硬件息息相关,并且程序难以调试.本系列就从synchronized原理开始,逐步深入,领会并发编程之美. 正文 基础稍微 ...
- mysql 安装卸载自动化脚本
#!/bin/sh #mkdir /root/mysql #tar -xvf mysql-5.7.-.el7.x86_64.rpm-bundle.tar -C /root/mysql #cd /roo ...
- 揭秘 Kubernetes attach/detach controller 逻辑漏洞致使 pod 启动失败
前言 本文主要通过深入学习k8s attach/detach controller源码,了解现网案例发现的attach/detach controller bug发生的原委,并给出解决方案. 看完本文 ...
- asterisk PBX 对接中国移动IMS
前提: 最近有项目需求,需要对接移动的IMS,移动的对接同事给出了信息: 用户名:+86750735xxxx@ims.gd.chinamobile.com 密码:123456 (系统导入的号码,默认 ...
- windows 下编译libcurl
因为linux平台采用了libcurl,有一个程序移植到到windows平台,再linux采用libcurl.在windows下准备也采用该库.在网上搜索了几位同行写的,步骤上面有缺失. 本文将以详细 ...
- Kubernetes实战总结 - 阿里云ECS自建K8S集群
一.概述 详情参考阿里云说明:https://help.aliyun.com/document_detail/98886.html?spm=a2c4g.11186623.6.1078.323b1c9b ...
- Python淘宝商品比价定向爬虫
1.项目基本信息 目标: 获取淘宝搜索页面的信息,提取其中的商品名称和价格理解: 淘宝的搜索接口.翻页的处理 很多人学习python,不知道从何学起.很多人学习python,掌握了基本语法过后,不知道 ...