一次线上应用线程过多问题的排查
前言
周一早上刚过来老大就告诉我线上在不停报警,看起来是线程过多引起的报警,查看了下报警邮件,发现确实是线上机器线程过多,大略的看了监控日志没有发现太明显的突破口,临近双11需要立即排查解决。
排查
项目之前一直是好好的,没有报过这类异常,所以第一个想法是可能最近改动了什么代码导致的,但是看了git最近改动的代码,貌似和线程都不搭边儿。
尝试了下jstack
了线上的线程日志,由于日志不能下载下来,直接远程cat查看,查找了下项目对应的所有关键字,发现700k的文件只有两个地方出现,比较郁闷。
通过查看整个日志文件,最后发现一个名字叫做http-connection-cleaner的线程最多,可以肯定这个应该就是罪魁祸首,在项目中尝试搜索这个关键字,但是并没有找到。
线上监控报警显示线程还在不停的增加,所以准备看下到底是什么引起线程的增加
尝试不停的运行下面命令
jstack {pid} | fgrep 'http-connection-cleaner' | wc -l
2521
2754
2987
...
结果显示线程还在不断增加,查看项目的访问日志发现当前正在执行dts任务,
于是又手动触发了一下dts任务,并且实时观察线程数量,发现每执行一次线程就增加200+
可以肯定是dts任务导致的线程问题,review代码,发现在项目中有调用别人的一个http接口服务,并且是循环new一个client,client没有进行关闭操作。
真相大白!之前的都是用同一个client,并且使用bean的方式注入到spring容器中,但是有的地方是老大写的直接new出来的,比如这里,emmmmmmm。
总结
善用单例模式。