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