记一次服务器高CPU的排查思路

现象

排查思路

另一台服务器CPU正常,由于消息中心有部分老接口是域名调用的,网关已做负载均衡,并且pinpoint上的两台服务器gc如图,初步猜测是否是负载不均衡导致。

经运维调试nginx权重无效,证明与负载均衡无关。那么先看子线程,这种情况必定由某几个线程引起

ps -mp pid -o THREAD,tid,time命令查看子线程,如图

这个数据上,分两部分看,1、有3个占用高的线程,2、执行时间可以注意到分别是4天,1天,23小时。说明线程出于某种情况,死锁,死循环。

由于这时候jstack操作可能引起内存溢出,应用直接挂掉,由运维操作下载日志。

jstack pid |grep tid

由上述子线程pid转化十六进制查询对应日志。如下:

"[email protected]" #124521 prio=5 os_prio=0 tid=0x00007f2c7c042800 nid=0x1c4a runnable [0x00007f2c5e9c1000]

java.lang.Thread.State: RUNNABLE

at sun.nio.ch.EPollArrayWrapper.interrupt(Native Method)

at sun.nio.ch.EPollArrayWrapper.interrupt(EPollArrayWrapper.java:317)

at sun.nio.ch.EPollSelectorImpl.wakeup(EPollSelectorImpl.java:207)

- locked <0x000000008658afa0> (a java.lang.Object)

at java.nio.channels.spi.AbstractSelector$1.interrupt(AbstractSelector.java:213)

at java.nio.channels.spi.AbstractSelector.begin(AbstractSelector.java:219)

at sun.nio.ch.EPollSelectorImpl.doSelect(EPollSelectorImpl.java:92)

at sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:86)

- locked <0x0000000086587170> (a sun.nio.ch.Util$2)

- locked <0x000000008658ad40> (a java.util.Collections$UnmodifiableSet)

- locked <0x000000008658ab98> (a sun.nio.ch.EPollSelectorImpl)

at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:97)

at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:101)

at org.eclipse.jetty.io.ManagedSelector$SelectorProducer.select(ManagedSelector.java:385)

at org.eclipse.jetty.io.ManagedSelector$SelectorProducer.produce(ManagedSelector.java:326)

at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.produceTask(EatWhatYouKill.java:342)

at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:189)

at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.tryProduce(EatWhatYouKill.java:175)

at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.produce(EatWhatYouKill.java:139)

at org.eclipse.jetty.io.ManagedSelector$$Lambda$106/586427179.run(Unknown Source)

at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:754)

at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:672)

at java.lang.Thread.run(Thread.java:745)

可以看到由多个locked操作,可以看到有引用org.eclipse.jetty.io及sun.nio.ch.,但是我们的代码里并没有用到这两个jar包内容。

代码内maven引用反推,可以看到jetty包是由定时任务xxl-job引入的,那么可以判断这个问题是由xxl-job引起的,但是这么多应用都在使用定时任务,为什么只有消息中心有问题?这里抛出这个问题。

查看定时任务的设置,在定时任务配置方向和其他应用有什么不同。

如下可以看到消息中心一共配了17个任务,而其他应用任务最多不超过4个。并且由上面jstack日志所示,有使用到NIO的异步线程EPoll,难道是因为线程池耗尽了,出于某种原因导致死锁?

那么看下NIO有什么坑吧。下面是我查到的官方原文:

简单来说,就是epoll这个异步线程是一个复用型线程,他的使用过程是socket协议——开启通道——执行——关闭通道——socket协议关闭,

但是本来应该被移除的fd,被后来的线程给注册上了,导致这个线程进入死循环。这也可以解释为什么只有3个线程死锁,并没有出现大面积死锁,因为这是一个并发导致的隐藏问题。

然后再看这三个子线程,按当时时间反推,毛估估刚好是整点触发,猜测是不是由于17个定时任务,在某个时间同时触发导致这个问题?这个没有证据能够证明他是这个原因导致的。

但是在看源码的时候可以注意到,jetty里有一个httpclient有使用到epoll的异步线程,刚好这也是消息中心的定时任务与其他应用的不同之处。

由于.net应用没有定时任务,即通过xxl-job的GLUE方式使用jetty的httpclient基于消息中心服务器请求接口。

那么可以大概断定,大概率是这里导致的死锁,去xxl-job的github上也可以看到作者将这种方式改成了java.net.HttpURLConnection方式请求。改完配置,重新发布,已观察两天没有问题。后续若再发现类似问题,继续跟进

原文地址:https://www.cnblogs.com/EchoXian/p/11584505.html

时间: 2024-11-06 07:45:22

记一次服务器高CPU的排查思路的相关文章

Java应用程序高CPU故障诊断(troubleshooting)思路

系统运行出现高CPU报警,一般可以通过top或者任务管理器找到哪些进程在使用CPU,但这个粒度不能让我们知道得更多,我们需要找到程序的哪部分在占用CPU并且在占用CPU做什么,这样才有利于我们以后调优,下面介绍一种可行的思路: 找到占用CPU高的进程p 找到进程p中占用CPU高的线程t 找到线程t在做什么 本文以Linux下Java应用程序为例,其他环境或程序可参照该思路,只要思路清晰就好办了 打开top,在top中按shift+p按照CPU使用量倒序显示进程,找到占用CPU较高的进程号pid,

【转载】php-fpm的高CPU使用率排查方法

1.CPU使用率监控 sar -P ALL 1 100 输出结果如下:CPU %user %nice %system %iowait %steal %idleall 85.54 0.00 5.69 0.00 0.00 8.76 0 74.75 0.00 25.25 0.00 0.00 0.00 1 98.00 0.00 2.00 0.00 0.00 0.00 2 89.22 0.00 3.92 0.00 0.00 6.86 3 91.00 0.00 2.00 0.00 0.00 7.00 4 7

记一次php高负载问题排查经历

在最近一次项目中,后台跑了deamon来处理任务.之前一直没什么问题,在一次增加任务处理时间等监控上报后,deamon的机器出现高负载,平均在20以上,任务出现积压. 第一步先使用strace查看系统调用情况: strace -tt -T -c -p 31420 strace -c发现,系统时间主要耗费在rt_sigprocmask上,该函数是系统的信号屏蔽函数,一般使用在信号处理程序中,对信号进行屏蔽,保证信号处理程序不被打断.rt_sigprocmask为linux的系统调用函数,不对外直接

云服务器 ECS Linux 系统 CPU 占用率较高问题排查思路

https://help.aliyun.com/knowledge_detail/41225.html?spm=5176.7841174.2.2.ifP9Sc 注意:本文相关配置及说明已在 CentOS 6.5 64 位操作系统中进行过测试.其它类型及版本操作系统配置可能有所差异,具体情况请参阅相应操作系统官方文档. 如果云服务器 ECS Linux 系统的 CPU 持续跑高,则会对系统稳定性和业务运行造成影响.本文对 CPU 占用率较高问题的排查分析做简要说明. CPU 负载查看方法 使用 v

记一次erlang 节点CPU严重波动排查过程

新服务上线后观察到,CPU在10 ~ 70%间波动严重,但从每秒业务计数器看业务处理速度很平均. 接下来是排查步骤: 1. dstat -tam 大概每10s一个周期,网络流量开始变得很小,随后突然增大,CPU也激增. 网络流量变化和从性能计数器结果上并不符合,服务相关业务较为复杂,先找出那个业务占用网络流量. 2. iftop 找出流量最大的几个目标IP,并且周期的流量变为0随后激增. 通过IP 知道是外部http接口地址,因为接口调用是异步进行的,性能计算是执行开始记录的,而不是结束记录,因

记一次查内存异常问题(续《记一次Web应用CPU偏高》)

继上一次查应用的CPU飙高问题(http://www.cnblogs.com/hzmark/p/JVM_CPU.html)过去10天了.上次只是定位到了是一个第三方包占用了大量的CPU使用,但没有细致的去查第三方包为什么占用了这么高的CPU,并且内存为什么如此诡异.总的来说上一次排查带来的收获是熟悉了JVM的工具使用和大致定位到了问题. 在上次排查问题之后,应用出现异常的频率还是较高,终下定决心再查一次,而这次排查的重点落在内存方面.因为怀疑CPU偏高是因为内存的异常导致频繁的GC引起的. 首先

生产环境下JAVA进程高CPU占用故障排查

问题描述:生产环境下的某台tomcat7服务器,在刚发布时的时候一切都很正常,在运行一段时间后就出现CPU占用很高的问题,基本上是负载一天比一天高. 问题分析:1,程序属于CPU密集型,和开发沟通过,排除此类情况.2,程序代码有问题,出现死循环,可能性极大. 问题解决:1,开发那边无法排查代码某个模块有问题,从日志上也无法分析得出.2,记得原来通过strace跟踪的方法解决了一台PHP服务器CPU占用高的问题,但是通过这种方法无效,经过google搜索,发现可以通过下面的方法进行解决,那就尝试下

记一次服务器IO过高处理过程

一.背景 在一次上线升级后,发现两台tomcat服务器的IOwait一直超过100ms,高峰时甚至超过300ms,检查服务器发现CPU负载,内存的使用率都不高.问题可能出现在硬盘读写,而且那块硬盘除了写日志外,没有其他的IO操作.最后发现是应用打印的日志信息太多,导致磁盘IO负载过高. 二.寻求解决过程 通过查找资料发现,Linux是用pdflush进程把数据从缓存页写入硬盘的,那么通过修改pdflush的一些参数应该可以改善IO负载问题. pdflush的行为受/proc/sys/vm中的参数

记一次Web应用CPU偏高

LZ开发的一个公司内部应用供查询HIVE数据使用.部署上线后总是会出现CPU偏高的情况,而且本地测试很难重现.之前出现几次都是通过直接重启后继续使用,因为是内部使用,重启一下也没有很大影响(当然,每次重启都是顺带改改BUG,添加一些监控,或者修改了一些参数). 今天再次发生占用CPU偏高的情况(机器是16核的),跑了几天后出现占用到200-300CPU的情况,之后快速升高,占用到700-1000.随机对应用状态状态尽兴了检查. 首先看了GC情况,看是否在进行FGC. (在CPU刚开始飙高的时候F