设置请求超时时长导致的线上故障
设置超时时长这是一个很常见的动作,因为分布式系统中,经常要发起RPC调用,肯定是需要和其他系统交互的。
前段时间遇到一个关于超时时长的问题(非本人设置),可以引以为戒
背景
1、应用在创建Http请求的时候使用SimpleClientHttpRequestFactory,相当于给Http请求配置了一个默认的参数,但是其中超时时间设置了较大的数字60秒钟。
2、应用使用一个高并发工具Akka,Akka的特点:
- 去掉了并非中的锁和原子性等概念;
- 系统间所以得通信都使用Actor,包括跨机器之间的调用方式。
好处就是高并发能力更强,代码只需要要维护Actor,同一个集群内(都使用Akka)的调用方式统一。Akka文档:doc.akka.io/docs/akka-h…
3、由于和外部系统交互,但是外部的一个东西只能通过Http调用,所以还是需要处理Http相关的逻辑。
问题表现
- 上线没有什么问题,但是过几天或者半个月系统就抽风卡死了, 表现是某个业务请求一直没有结果;
- 出现了2~3次之后,可以猜测到肯定是代码中的某个地方有问题... 第一次以为是偶然,第二次卡死一会自动恢复
问题排查
1、再次出现这个卡死问题的时候,火速登录机器,使用jstack打印线程堆栈。
2、分析线程堆栈,发现某个异常点... 堆栈中看起来都在socket.read
定位原因
1、根据堆栈到代码中查看,发现Http请求的超时参数设置的读取超时时长为60秒钟。(不是我写的)
2、然后搜索Akka的文档, 里面有说明:使用Akka一定要注意actor的阻塞问题,不要再其中做IO操作,如果非要做,另起一个线程池。最后记得设置超时时间
Blocking APIs should also be avoided if possible. Try to find or build Reactive APIs, such that blocking is minimised, or moved over to dedicated dispatchers.
3、模拟发现一旦涉及到阻塞,Akka中所谓的线程调度Actor基本上都不起作用了,Akka上是一个线程运行了多个Actor,但是如果线程阻塞了,后续的Actor逻辑也会有问题。
经验总结
1、使用RPC调用一定要设置好合理的超时时长,否则一旦线程全部阻塞,系统基本上无法使用,默认最长时间一般为3秒钟。 如果是C段用户流量要求在50ms之内;
2、对一些高大上的技术或者框架,一种是边被教训边学习,另一种是吃透了再拿来用
- 对于一些不成熟的业务或者用来实验的业务可以考虑用新技术,主要用于个人学习..
- 但是对于成熟稳定的业务,不要贸然引入新技术,一般老板也不同意。
3、参数设置是一个比较神奇的事情,一些影响到全局的参数设置前,可以找几个人一块校验下.
这是早些时间遇到的一个问题,分享一下,希望能对大家有所参考;
其他:
- Akka文档:doc.akka.io/docs/akka-h…
- Java排查线上问题:juejin.cn/post/684490…
转载自:https://juejin.cn/post/7148235260445065229