一次诡异的Linux服务器Load高的问题定位

一次诡异的Linux服务器Load高的问题定位

收到线上kubenetes集群一台node节点负载报警,5分钟负载达到180+,此服务器为32核配置,说明此时进程已经有排队情况。

~# uptime
14:46:06 up 1011 days, 7 min, 1 user, load average: 182.52, 185.10, 188.82

在查看问题之前我们先了解下load average的含义:

man uptime后有这样一段描述

System load averages is the average number of processes that are either in a runnable or uninterruptable state. A process in a runnable state is either
using the CPU or waiting to use the CPU. A process in uninterruptable state is waiting for some I/O access, eg waiting for disk. The averages are taken
over the three time intervals. Load averages are not normalized for the number of CPUs in a system, so a load average of 1 means a single CPU system is
loaded all the time while on a 4 CPU system it means it was idle 75% of the time.

翻译过来就是系统负载是运行在runnable和uninerruptable状态的平均进程数。 load average: 182.52, 185.10, 188.82分别表示1分钟、5分钟、15分钟的平均负载。那什么是runnable和uninerruptable状态呢?

上面也说了,runnable就是正在使用CPU或者等待使用CPU的进程的状态,也就是R状态进程。uninerruptable就是等待I/O,比如磁盘I/O,不能被中断的进程。

根据上面的描述我们就知道了排查问题的主要思路就是查看CPU和I/O的使用情况,使用top命令查看,诡异的问题出现了,也就是D状态进程。

%Cpu(s): 3.6 us, 1.8 sy, 0.0 ni, 94.4 id, 0.0 wa, 0.0 hi, 0.1 si, 0.0 st

从top命令显示看cpu使用率( 94.4 id)和iowait(0.0 wa)都很低,使用iostat命令查看磁盘I/O状态也很空闲.这就很奇怪了,接下来该怎么入手呢?

既然官方给的解释就是R状态和D状态的平均进程数,那么我就想是否可以从这两个状态入手呢,我们不妨打印出R状态和D状态的进程数。

ps -eTo stat,pid,tid,ppid,comm --no-header | sed -e 's/^ \\*//' | perl -nE 'chomp;say if (m!^\\S*[RD]+\\S*!)'

通过以上命令可以打印出R状态和D状态的进程数。

当运行这个命令后真相就浮现出来了

一次诡异的Linux服务器Load高的问题定位

从这里可以看到有大量的处在D状态的线程,而这些都属于16231的java进程。既然找到导致服务器进程高的进程,我还想进一步追查什么原因导致的大量线程处于D状态。可以通过jstack -p 16231

Jstack是Jdk自带的线程跟踪工具,用于打印指定Java进程的线程堆栈信息。

一次诡异的Linux服务器Load高的问题定位

从以上可以看出是xxxxDisk方法的磁盘操作导致的,找到开发人员,开发人员承认这里有死循环,修改上线后问题得到解决。


分享到:


相關文章: