HttpClient未设置connectTimeout导致线程池耗尽
一、背景
某商家反馈昨天晚上下单失败,研发查询网关日志后发现是edi集群的线程池耗尽,导致商家失败。
1 | // 异常信息 |
二、可能原因分析
- 业务代码没有问题,但是瞬时流量加大,达到资源瓶颈;
- 业务代码有问题,使线程阻塞,长期占用线程,无法归还线程池;
三、定位过程
- 查询网关,定位线程池耗尽的服务器IP;
- 查询该IP上该时间段的流量,发现流量为0;
以上确定是由于业务代码有问题导致的;此时可通过如下两种方式继续定位问题:
- 精确定位: 在该机器上执行
jstack pid
,查看线程堆栈里jsf线程阻塞到哪行代码了; - 范围定位: 在该机器上找到当时的日志,查看该线程最后执行的业务逻辑;
由于中间重启过集群,故采取第二种方法定位问题。
日志最终定位到是http请求节点阻塞,然后查看http节点的属性发现没有设置connectTimeout。我们使用的是httpclient-4.5.6,如果不设置connectTimeout则默认无限等待;
四、结论
- 使用第三方插件时,最好调研下常用配置,并全部配置上去。
- 避免出现默认值不符合预期时导致程序不健壮。