报错!-> CPU100%-但是找不到使用cpu的进程

       

                                                                         cpu到达100%   但是找不到使用cpu的进程

 

一般分析cpu使用率:通过使用 topvmstatpidstat 等工具,排查高 CPU 使用率的进程,然后再使用 perf top 工具,定位应用内部函数的问题。

但是!不是所有cpu过高都是这样分析的,这只是一般情况下可以这样分析。什么是一般情况?简单说,通常可以根据工具,就可以找到cpu占有过高的进程!

   通过top命令我们知道,系统cpu使用率基本包括

  • 进程用户状态的运行
  • 内核状态的运行
  • 中断处理的线程
  • 等待I/O的线程
  • 内核线程

以前看到cpu过高时,简单的以为是某一个进程占用过大导致的,其实不一定,系统CPU过高,不一定是进程引起的,还有可能是IO过高或者阻塞引起的,也有可能是中断进程引起的,多方面原因分析

                                                                                                                                                                                                                                                                                                

如下一个案例

使用TOP命令

$ top

top - 04:58:24 up 14 days, 15:47,  1 user,  load average: 3.39, 3.82, 2.74

Tasks: 149 total,   6 running,  93 sleeping,   0 stopped,   0 zombie

%Cpu(s): 77.7 us, 19.3 sy,  0.0 ni,  2.0 id,  0.0 wa,  0.0 hi,  1.0 si,  0.0 st

KiB Mem :  8169348 total,  2543916 free,   457976 used,  5167456 buff/cache

KiB Swap:        0 total,        0 free,        0 used.  7363908 avail Mem

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND

 6947 systemd+  20   0   33104   3764   2340 S   4.0  0.0   0:32.69 nginx

 6882 root      20   0   12108   8360   3884 S   2.0  0.1   0:31.40 docker-containe

15465 daemon    20   0  336696  15256   7576 S   2.0  0.2   0:00.62 php-fpm

15466 daemon    20   0  336696  15196   7516 S   2.0  0.2   0:00.62 php-fpm

15489 daemon    20   0  336696  16200   8520 S   2.0  0.2   0:00.62 php-fpm

 6948 systemd+  20   0   33104   3764   2340 S   1.0  0.0   0:00.95 nginx

15006 root      20   0 1168608  65632  37536 S   1.0  0.8   9:51.09 dockerd

15476 daemon    20   0  336696  16200   8520 S   1.0  0.2   0:00.61 php-fpm

15477 daemon    20   0  336696  16200   8520 S   1.0  0.2   0:00.61 php-fpm

24340 daemon    20   0    8184   1616    536 R   1.0  0.0   0:00.01 stress

24342 daemon    20   0    8196   1580    492 R   1.0  0.0   0:00.01 stress

24344 daemon    20   0    8188   1056    492 R   1.0  0.0   0:00.01 stress

24347 daemon    20   0    8184   1356    540 R   1.0  0.0   0:00.01 stress

...

这次从头开始看 top 的每行输出,Tasks 这一行看起来有点奇怪,就绪队列中居然有 6 Running 状态的进程(6 running),是不是有点多呢?

然后用 pidstat 命令看一下它的 CPU 使用情况:

$ pidstat -p 24344

16:14:55      UID       PID    %usr %system  %guest   %wait    %CPU   CPU  Command

奇怪,居然没有任何输出。难道是 pidstat 命令出问题了吗?我们在终端里运行下面的命令,看看 24344 进程的状态:

# 从所有进程中查找 PID 24344 的进程

$ ps aux | grep 24344

root      9628  0.0  0.0  14856  1096 pts/0    S+   16:15   0:00 grep --color=auto 24344

还是没有输出。现在终于发现问题,原来这个进程已经不存在了,所以 pidstat 就没有任何输出。既然进程都没了,那性能问题应该也跟着没了吧

然后再一次top一下

$ top

...

%Cpu(s): 80.9 us, 14.9 sy,  0.0 ni,  2.8 id,  0.0 wa,  0.0 hi,  1.3 si,  0.0 st

...

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND

 6882 root      20   0   12108   8360   3884 S   2.7  0.1   0:45.63 docker-containe

 6947 systemd+  20   0   33104   3764   2340 R   2.7  0.0   0:47.79 nginx

 3865 daemon    20   0  336696  15056   7376 S   2.0  0.2   0:00.15 php-fpm

  6779 daemon    20   0    8184   1112    556 R   0.3  0.0   0:00.01 stress

...

好像又错了。结果还跟原来一样,用户 CPU 使用率还是高达 80.9%,系统 CPU 接近 15%,而空闲 CPU 只有 2.8%Running 状态的进程有 Nginxstress 等。

可是,刚刚我们看到 stress 进程不存在了,怎么现在还在运行呢?再细看一下 top 的输出,原来,这次 stress 进程的 PID 跟前面不一样了,原来的 PID 24344 不见了,现在的是 6779

那么问题来了,stress这个进程再不断的变换PID,是什么原因呢?

一个进程不断的变换Pid号,无非两种原因  

   第一个原因:进程在不停地崩溃重启,比如因为段错误、配置错误等等,这时,进程在退出后可能又被监控系统自动重启了

   第二个原因:这些进程都是短时进程,也就是在其他应用内部通过 exec 调用的外面命令。这些命令一般都只运行很短的时间就会结束,很难用 top 这种间隔时间比较长的工具发现

通过这两种原因,看来,top命令也不是万能的,也会有些速度快的进程逃过他的检查(天下武功,唯快不破)

回到问题:stress这个进程不断的变换PID,又占用用cpu资源,导致cpu过高,这个时候,找到它的父进程,来进行下一步分析

使用pstree命令来看进程关系,找到它的父进程!

看看是不是父进程里有什么调用问题,看看父进程的源码

一大部分可能是————————————————

由于权限错误,大量的 stress 进程在启动时初始化失败,进而导致用户 CPU 使用率的升高。或者是二进制文件里有对stress有大量的调用循环。

问题总结:

碰到常规问题无法解释的 CPU 使用率情况时,首先要想到有可能是短时应用导致的问题,比如有可能是下面这两种情况

  • 应用里直接调用了其他二进制程序,这些程序通常会运行时间很短,速度非常快,通过top等其他工具不一定能查询的到
  • 应用本身就在不停的崩溃重启,而启动过程的资源初始化,很可能会占用大量的CPU,而且这类进程,PID会不断变更,通常只能通过pstree或者execsnoop找到它的父进程,从父进程所在的应用里查找,找到问题所在,排查问题。
原文地址:https://www.cnblogs.com/123456likun/p/13564691.html