zoukankan      html  css  js  c++  java
  • 记一次上线就跪的故障排查案例

    这个是我很早以前解决的一个案例,其现象是系统每次上线后,20多台机器,总有两三机器,出现假死的情况。如何判断出系统假死?借助的是一个第三方公司运维监控平台;这种情况,前同事称之为的“假死”,需要重新启动系统才能恢复。因为我是新来乍到,觉得这种情况不正常,而且对研发(在这边是研发上线)来说,是一个非常大的上线负担;于是我决定解决一下这个“百年难题”。

    我亲自上线,果然很快就碰到了假死的机器。我看到机器的CPU,内存和磁盘IO都很正常,根本不像出问题的机器。直觉告诉我,先用jstack打印个堆栈看看当前tomcat在做什么吧,于是叫上支持上线的运维小哥给打印了一个,然后手工重新部署了一下有问题的机器(记住出问题一定要先止损)。

    拿到手的堆栈,第一眼就发现了一些问题。前几行如下:

     

    可以看到tomcat的线程号已经到了215,而tomcat默认最大处理数为200,已经到了饱和状态。后续的请求就只能排队了。

    堆栈中,有很多waiting to lock <0x0000000784588098>的线程,从执行堆栈看,应该是CXF要调用.NET的webservice。调用的业务方法各不相同。

    继续往下看,在堆栈的后半部分(注意行数),打印了一个死锁的提示。

     

    我们进一步分析,为了方便大家阅读,我对上面的死锁线程画了一个依赖图,可以看出,线程25和线程48形成了死锁。这4个线程的等待关系如下:

     

    继续分析,什么导致的死锁;

    线程25的堆栈如下:

     

    线程48的堆栈:

     

    线程持有锁和堆栈中提示的锁信息正好照应

     

    从上面堆栈可以分析出,gson和第三方的agent发生了循环死锁。至此问题的解决方法已经有了,要不去掉gson,要不就去掉那个第三方agent。

    除了上面的解决方法外,我们还在系统中增加了一个容器探活的接口(这个功能从监控来看,非常有意义)。即在controller中写一个方法,直接返回一个字符串。这样在外部定时的去调用接口(也可以手工使用curl来探测),就知道这个服务是否还存活,也不用第三方监控系统来判断了;

    经验教训:

    1、系统需从容器级别支持外部探测,以证明自身健康

    2、不要轻易引入外部agent

    知识点:

    1、tomcat(BIO)默认最大线程数200

    关注我的微信公众号,获取最新故障案例分析;



  • 相关阅读:
    个人总结05
    微软拼音的用户体验
    个人总结04
    典型用户和用户场景模式
    个人总结03
    个人总结02
    构建之法阅读笔记06
    个人总结01
    学习进度条——第七周
    WebApi学习总结系列第五篇(消息处理管道)
  • 原文地址:https://www.cnblogs.com/donlianli/p/10795310.html
Copyright © 2011-2022 走看看