问题:
最近手中一个web项目频繁挂掉,tomcat进程跑着跑着就没了,catalina.out里也没有任何相关报错。
项目功能:
该服务有3台物理机,接收client端的rpc调用,本机起hive进程做查询,将hive日志及结果写到一个nfs上,查询结束后将结果写到hdfs上,并将nfs上的临时结果文件删除。
分析:
1、之前该项目经常OOM,后来加大了堆内存(运维同学很任性的帮忙从4G直接改到了20G),再之后没有报过OOM。
2、本来猜想此次也是内存的原因,于是分析了CAT监控信息,剩余内存充足,dump了tomcat的heap之后分析了内存、GC情况,也没有内存泄露的情况,于是开始迷茫。
3、由于没有tomcat挂掉时间点的现场,不好进一步分析。于是各种搜,搜到了开启core dump可以在tomcat异常退出的时候dump内存,于是开启。
4、时间转到下个周一,遇到了CAT和rpc服务都报一台机器上tomcat挂掉了,但是ssh过去看到tomcat进程还在,是个定位问题的好机会,于是jstack了线程信息,发现很多线程block在了hive结果写nfs上面。
这个服务同时在nfs上读写上百个文件,每个hive进程有2个输出线程一直在等待写结果,同时还要读写hive的日志,之前在操作nfs上的文件的时候就非常卡,可能瓶颈就在这里。
5、于是修改逻辑,把hive进程的结果文件写在本地,上线后感觉再操作nfs的时候就流畅很多了,到现在3天了,也没再挂过,之前是工作日每天2台的节奏。
6、顺手做了些其他优化,如之前线程池是默认的命名方式,pool-N-thread-M,调试起来很不方便,参考和,为线程池添加跟功能有关的名字,调整了线程池的大小,jstack每分钟一次(其实CAT中的心跳是有线程信息的,之前没发现),优化结果后续观察中。
总结:
工作以来第一次做这样的问题定位,发现了很多可以学习的点,也更清楚有很多不足哇~