线上服务器cpu占用过高、程序死锁,该如何排查问题?

1,816 阅读3分钟

导读:前天写了一篇关于线上服务器cpu 100%了,该如何排查问题?一些粉丝私信说能不能结合案例来讲解,然后就有了这篇。

假定你已经了解了运行时的数据区域和常用的垃圾回收算法,也了解了Hotspot支持的垃圾回收器

场景一:CPU占用过高

cpu占用过高要分情况讨论,是不是业务上在搞活动,突然有大批的流量进来,而且活动结束后cpu占用率就下降了,如果是这种情况其实可以不用太关心,因为请求越多,需要处理的线程数越多,这是正常的现象。话说回来,如果你的服务器配置本身就差,cpu也只有一个核心,这种情况,稍微多一点流量就真的能够把你的cpu资源耗尽,这时应该考虑先把配置提升吧。

cpu占用率长期过高,这种情况下可能是你的程序有那种循环次数超级多的代码,甚至是出现死循环了,或者死锁的情况。这个时候该怎么排查定位问题?

  • 用top命令查看cpu占用情况

这样就可以定位出cpu过高的进程。在linux下,top命令获得的进程号和jps工具获得的vmid是相同的。

  • 用top -Hp命令查看线程的情况

可以看到是线程id为23835这个线程一直在占用cpu

  • 把线程号转换为16进制

记下这个16进制的数字,下面我们要用

  • 用jstack工具查看线程栈情况 (过程省略)

使用详情可参阅以前文章

  • 用Arthas的thread命令查看线程栈情况

我这里还是用前天的工具去查看检查下使用Arthas 的thread命令查看当前线程的堆栈情况

通过jstack工具输出现在的线程栈,再通过grep命令结合上一步拿到的线程16进制的id定位到这个线程的运行情况,其中jstack后面的23835是第(1)步定位到的进程号,grep后面的是(2)(3)步定位到的线程号。
从输出结果可以看到这个线程处于运行状态

案例代码

场景二:程序死锁

死锁并没有第一种场景那么明显,web应用肯定是多线程的程序,它服务于多个请求,程序发生死锁后,死锁的线程处于等待状态(WAITING或TIMED_WAITING),等待状态的线程不占用cpu,消耗的内存也很有限,而表现上可能是请求没法进行,最后超时了。在死锁情况不多的时候,这种情况不容易被发现。

  • 开启Arthas查看线程

  • 按照CPU使用率查看线程信息

  • 显示指定线程的运行堆

发现了一个死锁,原因也一目了然

案例代码

总结

以上两种严格地说还算不上jvm的调优,只是用了jvm工具把代码中存在的问题找了出来。我们进行jvm的主要目的是尽量减少停顿时间,提高系统的吞吐量。但是如果我们没有对系统进行分析就盲目去设置其中的参数,可能会得到更坏的结果,jvm发展到今天,各种默认的参数可能是实验室的人经过多次的测试来做平衡的,适用大多数的应用场景。如果你认为你的jvm确实有调优的必要,也务必要取样分析,最后还得慢慢多次调节,才有可能得到更优的效果。

作者 | 智哥

原文链接

更多技术干货敬请关注码农架构技术号:码农架构 - 掘金

本文为**码农架构**原创内容,未经允许不得转载。