一次詭異的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方法的磁盤操作導致的,找到開發人員,開發人員承認這裡有死循環,修改上線後問題得到解決。


分享到:


相關文章: