社区应用 最新帖子 精华区 社区服务 会员列表 统计排行
  • 51阅读
  • 5回复

[分享]Linux系统下CPU性能问题分析案例(上)

楼层直达
z3960 
级别: 茶馆馆主
发帖
770867
飞翔币
207694
威望
215657
飞扬币
2511646
信誉值
8



某个应用的CPU使用率居然达到100%,我该怎么办?


[size=; font-size: 1.059em,1.059em]分析过程
  • 使用观察系统CPU使用情况(并按下数字 1 ,切换到每个 CPU 的使用率
$ top...%Cpu0 : 98.7 us, 1.3 sy, 0.0 ni, 0.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st%Cpu1 : 99.3 us, 0.7 sy, 0.0 ni, 0.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st...PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND21514 daemon 20 0 336696 16384 8712 R 41.9 0.2 0:06.00 php-fpm21513 daemon 20 0 336696 13244 5572 R 40.2 0.2 0:06.08 php-fpm21515 daemon 20 0 336696 16384 8712 R 40.2 0.2 0:05.67 php-fpm21512 daemon 20 0 336696 13244 5572 R 39.9 0.2 0:05.87 php-fpm21516 daemon 20 0 336696 16384 8712 R 35.9 0.2 0:05.61 php-fpm
这里可以看到,系统中有几个 php-fpm 进程的 CPU 使用率加起来接近 200%;而每个 CPU 的用户使用率(us)也已经超过了 98%,接近饱和。这样,我们就可以确认,正是用户空间的 php-fpm 进程,导致 CPU 使用率骤升
  • 使用perf在进一步定位程序的函数调用开销
# -g开启调用关系分析,-p指定php-fpm的进程号21515$ perf top -g -p 21515
按方向键切换到 php-fpm,再按下回车键展开 php-fpm 的调用关系,你会发现,调用关系最终到了 sqrt 和 add_function


[size=; font-size: 1.059em,1.059em]总结
CPU 使用率是最直观和最常用的系统性能指标,更是我们在排查性能问题时,更要熟悉它每个指标的的含义,尤其要弄清楚用户(%user)、Nice(%nice)、系统(%system) 、等待 I/O(%iowait) 、中断(%irq)以及软中断(%softirq)这几种不同 CPU 的使用率。比如说:
  • 用户 CPU 和 Nice CPU 高,说明用户态进程占用了较多的 CPU,所以应该着重排查进程的性能问题。
  • 系统 CPU 高,说明内核态占用了较多的 CPU,所以应该着重排查内核线程或者系统调用的性能问题。
  • I/O 等待 CPU 高,说明等待 I/O 的时间比较长,所以应该着重排查系统存储是不是出现了 I/O 问题。
  • 软中断和硬中断高,说明软中断或硬中断的处理程序占用了较多的 CPU,所以应该着重排查内核中的中断服务程序。

碰到 CPU 使用率升高的问题,你可以借助 top、pidstat 等工具,确认引发 CPU 性能问题的来源;再使用 perf 等工具,排查出引起性能问题的具体函数。

系统的 CPU 使用率很高,但为啥却找不到高 CPU 的应用?


[size=; font-size: 1.059em,1.059em]分析过程
  • 依然是使用top,观察系统CPU使用情况
$ top...%Cpu(s): 80.8 us, 15.1 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+ COMMAND6882 root 20 0 8456 5052 3884 S 2.7 0.1 0:04.78 docker-containe6947 systemd+ 20 0 33104 3716 2340 S 2.7 0.0 0:04.92 nginx7494 daemon 20 0 336696 15012 7332 S 2.0 0.2 0:03.55 php-fpm7495 daemon 20 0 336696 15160 7480 S 2.0 0.2 0:03.55 php-fpm10547 daemon 20 0 336696 16200 8520 S 2.0 0.2 0:03.13 php-fpm10155 daemon 20 0 336696 16200 8520 S 1.7 0.2 0:03.12 php-fpm10552 daemon 20 0 336696 16200 8520 S 1.7 0.2 0:03.12 php-fpm15006 root 20 0 1168608 66264 37536 S 1.0 0.8 9:39.51 dockerd4323 root 20 0 0 0 0 I 0.3 0.0 0:00.87 kworker/u4:1
通过以上输出分析
  • 系统的整体 CPU 使用率是比较高的: 用户CPU到了80%,系统CPU为15.1%,空闲CPU只有2.8%。(用户CPU使用率高,肯定是有用户进程占用CPU导致
  • CPU 使用率最高的进程也只不过才 2.7%,并不高
  • 观察进程状态发现:Nginx 和所有的 php-fpm 都处于 Sleep(S)状态,而真正处于 Running(R)状态的,却是几个 stress 进程

  • 使用pidstat命令分析stress进程
# 使用 -p 选项指定stress进程的 PID$ pidstat -p 2434416:14:55      UID       PID    %usr %system  %guest   %wait    %CPU   CPU  Command
没有任何输出。现在终于发现问题,原来这个进程已经不存在了,所以 pidstat 就没有任何输出,而且从top的输出我们看到stress的PID一直在变化,出现这种情况的无非就两个原因:
  • 第一个原因,进程在不停地崩溃重启,比如因为段错误、配置错误等等,这时,进程在退出后可能又被监控系统自动重启了。
  • 第二个原因,这些进程都是短时进程,也就是在其他应用内部通过 exec 调用的外面命令。这些命令一般都只运行很短的时间就会结束,你很难用 top 这种间隔时间比较长的工具发现(上面的案例,我们碰巧发现了)。

  • 使用pstree查询下stress进程的父进程
$ pstree | grep stress|-docker-containe-+-php-fpm-+-php-fpm---sh---stress|         |-3*[php-fpm---sh---stress---stress]
从这里可以看到,stress 是被 php-fpm 调用的子进程,并且进程数量不止一个(这里是 3 个),接下来就是去看php-fpm的内部代码逻辑了,不在展开
  • 使用perf继续分析下stress的cpu占用函数
# 记录性能事件,等待大约15秒后按 Ctrl+C 退出$ perf record -g# 查看报告$ perf report


perf输出分析:
  • stress 占了所有 CPU 时钟事件的 77%,而 stress 调用调用栈中比例最高的,是随机数生成函数 random(),看来它的确就是 CPU 使用率升高的元凶了。


[size=; font-size: 1.059em,1.059em]总结
碰到常规问题无法解释的 CPU 使用率情况时,首先要想到有可能是短时应用导致的问题,比如有可能是下面这两种情况。
  • 第一,应用里直接调用了其他二进制程序,这些程序通常运行时间比较短,通过 top 等工具也不容易发现。
  • 第二,应用本身在不停地崩溃重启,而启动过程的资源初始化,很可能会占用相当多的 CPU。

对于短时进程,我们可以通过pstree命令找到它们的父进程,再从父进程所在的应用入手,排查问题的根源
关键词: bot 系统 CPU
 
我不喜欢说话却每天说最多的话,我不喜欢笑却总笑个不停,身边的每个人都说我的生活好快乐,于是我也就认为自己真的快乐。可是为什么我会在一大群朋友中突然地就沉默,为什么在人群中看到个相似的背影就难过,看见秋天树木疯狂地掉叶子我就忘记了说话,看见天色渐晚路上暖黄色的灯火就忘记了自己原来的方向。
z3960 
级别: 茶馆馆主
发帖
770867
飞翔币
207694
威望
215657
飞扬币
2511646
信誉值
8

只看该作者 1 发表于: 01-14

在前一篇文章 Linux系统下CPU性能问题分析案例(上)中我们看到的系统CPU使用率高的表现都是用户态(us)下使用率过高场景的排查过程,关于CPU使用率相关重要指标,我们经常在使用top、dstat、vmstat等工具看到,这里解读一下:

  • [size=; font-size: 1.059em,1.059em]user(通常缩写为us),代表用户态CPU时间
  • nice(通常缩写为ni),代表低优先级用户态CPU时间,nice可取值范围是-20到19,数值越大,优先级反而越低,默认值是0
  • [size=; font-size: 1.059em,1.059em]system(通常缩写为sys),代表内核态CPU时间
  • [size=; font-size: 1.059em,1.059em]idle(通常缩写为id),代表空闲时间。注意,它不包括等待I/O的时间(iowait)
  • [size=; font-size: 1.059em,1.059em]iowait(通常缩写为wa),代表等待 I/O的CPU时间
  • irq(通常缩写为hi),代表处理硬中断的CPU时间
  • softirq(通常缩写为si),代表处理软中断的CPU时间
  • steal(通常缩写为st),代表当系统运行在虚拟机中的时候,虚拟机占用的CPU时间
  • guest(通常缩写为guest),代表通过虚拟化运行其他操作系统的时间,也就是运行虚拟机的CPU时间
  • guest_nice(通常缩写为gnice),代表以低优先级运行虚拟机的时间

CPU的iowait突然升高,我该怎么处理?

[size=; font-size: 1.059em,1.059em]分析过程

从上面的介绍可以看出,iowait升高,第一反应会想到查看系统的 I/O情况,I/O又分为磁盘I/O和网络I/O,这里先分析磁盘I/O

1.运行 dstat 命令,观察 CPU 和 I/O 的使用情况

  • 结果分析
  • 在iowait升高(wai)时,磁盘的读请求(read)都很高,最高时1271M
  • 充分说明iowait的升高是磁盘I/O导致的,确切的说,是大量读磁盘导致

2.通过pidstat查询进程的I/O情况# -d:统计进程的磁盘使用情况 1: 采集周期1s  10: 采集10次pidstat -d 1 10

  • 结果分析
  • 大量读磁盘的进程名称是app,而且app进程的pid在不停变化(短时进程?)

3.使用ps命令查看下app进程

  • 结果分析
  • 进程的状态是Z+,命令行参数<defunct>,进程变成僵尸进程了
  • 僵尸进程的产生和处理方法,这里暂不展开,有想了解的可以评论留言或者自行学习
  • app的是谁创建的,是下一步分析的重点

4.查询app进程的父进程

  • 结果分析
  • pid为51780的父进程id是51688,进程名称也是app

5.使用perf命令采集性能事件分析app函数调用# 录制全局性能事件,如果只想录制某个进程的,可以使用-p指定# perf record -ag -p {pid} -- sleep 10 #采集指定pid所有cpu的性能事件,周期是10sperf record -g# 分析报告perf report

  • 分析结果
  • app进程正在对磁盘进行直接读,也就是绕过了系统缓存,每个读请求都会从磁盘直接读

思路总结

  • 使用dstat命令查看系统I/O情况(dstat可以同时观察cpu和磁盘的情况
  • 使用pidstat命令可以定位到进程维度的磁盘读写情况,找出可疑进程
  • 使用ps、top等命令可以观测到进程的状态(D、R、S、Z、T等)
  • 使用pstree命令我们找出了app进程的父进程(子进程的pid一直在变)
  • 使用perf命令就可以对进程的函数调用关系分析了
  • 没啥需要使用的啦。哈哈,点赞+收藏

知识补充

  • 进程状态
  • R 是Running或Runnable 的缩写,表示进程在CPU的就绪队列中,正在运行或者正在等待运行
  • D 是Disk Sleep的缩写,也就是不可中断状态睡眠(Uninterruptible Sleep),一般表示进程正在跟硬件交互,并且交互过程不允许被其他进程或中断打断。
  • Z 是Zombie的缩写,进程实际上已经结束了,但是父进程还没有回收它的资源(比如进程的描述符、PID 等)
  • S 是Interruptible Sleep的缩写,也就是可中断状态睡眠,表示进程因为等待某个事件而被系统挂起。当进程等待的事件发生时,它会被唤醒并进入R状态
  • I 是Idle的缩写,也就是空闲状态,用在不可中断睡眠的内核线程上
  • T 或者 t,也就是Stopped或Traced的缩写,表示进程处于暂停或者跟踪状态

  • 僵尸进程
  • 一旦父进程没有处理子进程的终止,还一直保持运行状态,那么子进程就会一直处于僵尸状态
  • 大量的僵尸进程会用尽PID进程号,导致新进程不能创建
  • 僵尸进程在父进程回收它的资源后就会消亡,或者在父进程退出后,由init进程回收后也会消亡

我不喜欢说话却每天说最多的话,我不喜欢笑却总笑个不停,身边的每个人都说我的生活好快乐,于是我也就认为自己真的快乐。可是为什么我会在一大群朋友中突然地就沉默,为什么在人群中看到个相似的背影就难过,看见秋天树木疯狂地掉叶子我就忘记了说话,看见天色渐晚路上暖黄色的灯火就忘记了自己原来的方向。
级别: 超级版主
发帖
835650
飞翔币
226827
威望
224673
飞扬币
2454463
信誉值
0

只看该作者 2 发表于: 01-15
来看一下
级别: 超级版主
发帖
835650
飞翔币
226827
威望
224673
飞扬币
2454463
信誉值
0

只看该作者 3 发表于: 01-15
不错,了解了
srwam 
级别: 超级版主
发帖
636486
飞翔币
196
威望
25287
飞扬币
2870039
信誉值
0

只看该作者 4 发表于: 01-22
来看看
srwam 
级别: 超级版主
发帖
636486
飞翔币
196
威望
25287
飞扬币
2870039
信誉值
0

只看该作者 5 发表于: 01-22
了解一下