java应用线上一次故障诊断分析

今天项目发布,在预发布机器上居然出现应用启动不到10分钟 CPU使用率从不到1%飙升到95以上,load从不到1升到15以上,然后当然应用就不可用了,第一次还奇怪为什么10分钟后就变成这样,然后找不到原因,异常还一堆其他的异常,而且还有其他的需求一起发布,所以还怀疑其他需求的问题,然后就单独发布自己的需求代码,重新发布后大概10分钟后又出现这个问题,想了想,一堆的超时,应用访问也是超时,开始怀疑线程的问题,通过jstack dump java进程的线程栈信息,通过分析日志发现了 34个线程有16个线程的状态处于同样一处代码上的runnable状态,

 

"qtp1041301507-215" prio=10 tid=0x000000005aa2a800 nid=0x741d runnable [0x0000000044598000]
   java.lang.Thread.State: RUNNABLE
        at java.lang.Long.valueOf(Long.java:557)
        at com.alibaba.china.biz.viewcache.tree.NestTree.getNode(NestTree.java:188)
        at com.alibaba.china.biz.viewcache.ViewCacheTool.retrieveDisplayCategory(ViewCacheTool.java:802)
        at com.alibaba.apps.saleoffer.module.control.spuIndustry.SpuIndustryOfferResultMro.getIndustryMroAttributes(SpuIndustryOffer
ResultMro.java:113)

才访问了几次这个代码对应的url,就出现该请求对应的处理线程一直在runnable状态,而且应用的url显示超时了。

 

好吧,再查下代码

while (true) {
            DisplayCategory offerCategory = viewCacheTool.retrieveDisplayCategory(curCategoryId);
            if (offerCategory != null && offerCategory.getAttributes() != null && offerCategory.getAttributes().size() > 0) {
                for (int i = 0; i < offerCategory.getAttributes().size(); i++) {
  ...}
curCategoryId = offerCategory.getSuperCategoryId1();}
......}

这段代码再执行过程中由于 viewCacheTool.retrieveDisplayCategory的生产环境和测试环境的数据源不同导致在测试环境没有出现问题,而线上处理过程由于curCategoryId = offerCategory.getSuperCategoryId1();在递归过程中

由于没有进入if程序块,导致死循环。

 

第一次遇到cpu和load飙升这么高,很有可能还真是死循环引起的,跟线程一直在执行有关。


原文地址:https://www.cnblogs.com/secbook/p/2655159.html