ITPub博客

首页 > 数据库 > 数据库开发技术 > 干货篇 | 当CPU使用率达到100%该怎么办?

干货篇 | 当CPU使用率达到100%该怎么办?

原创 数据库开发技术 作者:咸鱼运维杂谈 时间:2021-07-08 16:14:00 0 删除 编辑
点击上方"蓝字"
关注我们吧!


不知道大家有没有遇到过服务器的CPU使用率达到了100%的情况,在实际生产环境中如果遇到了这种情况我们该怎么办?


接下来我就跟大家探讨一下:当CPU的使用率达到了100%的时候我们该如何排查、定位、找出问题根源。



01
CPU使用率


Linux作为一个多任务操作系统,将每个CPU的时间划分为很短的时间片,然后在通过调度器轮流分配给各个任务使用,因此造成多任务同时进行的错觉。


CPU使用率:就是CPU处在非空闲状态的时间占总CPU时间的百分比




而CPU使用率中也有很多相关的重要指标,我们可以通过 top 命令简单列举出来




  • user(缩写为 us),代表用户态 CPU 时间。注意,它不包括下面的 nice 时间,但包括了 guest 时间。

  • nice(缩写为 ni),代表低优先级用户态 CPU 时间,也就是进程的 nice 值被调整为 1-19 之间时的 CPU 时间。这里注意,nice 可取值范围是 -20 到 19,数值越大,优先级反而越低。

  • system(缩写为 sys),代表内核态 CPU 时间。

  • idle(缩写为 id),代表空闲时间。注意,它不包括等待 I/O 的时间(iowait)。

  • iowait(缩写为 wa),代表等待 I/O 的 CPU 时间。

  • irq(缩写为 hi),代表处理硬中断的 CPU 时间。

  • softirq(缩写为 si),代表处理软中断的 CPU 时间。

  • steal(缩写为 st),代表当系统运行在虚拟机中的时候,被其他虚拟机占用的 CPU 时间。



02
如何查看CPU使用率

在介绍查看CPU使用率的工具之前,我们先来想一个问题:这些性能工具是怎么计算CPU使用率的?


事实上,为了计算CPU使用率,大多数性能工具一般都会取间隔一段时间(比如3秒)的两次值作差后,再计算出这段时间内的平均CPU使用率



这个公式,就是大多数性能工具所看到的CPU使用率的实际计算方法。所以,在使用这些工具的时候我们要注意间隔时间的设置


top 工具和 ps 工具


top 和 ps 是最常用的性能分析工具,其中:

  • top 显示系统总体的CPU和内存使用情况,以及各个进程的资源使用情况

  • ps 显示每个进程的资源使用情况


sysstat 工具


除了上面这两个最常用的工具之外,我们还可以使用 sysstat 工具中的 pidstat 命令来查看进程的CPU使用率


格式:

pidstat [ 选项 ] [ <时间间隔> ] [ <次数> ]
# 常用选项-u:默认的参数,显示各个进程的cpu使用统计-r:显示各个进程的内存使用统计-d:显示各个进程的IO使用情况-p:指定进程号-w:显示每个进程的上下文切换情况-t:显示选择任务的线程的统计信息外的额外信息



上面这些工具你可以轻松找出哪个CPU使用率较高的进程,但是找到进程还不够,我们还想找出是哪个具体进程或者具体函数占用了如此高的CPU时间,这样才能进行更好的优化、


这里我推荐一个可以在第一时间分析进程的CPU问题的工具——perf


perf top


perf 是一种 Linux 内置的性能分析工具。它以性能事件采样为基础,不仅可以分析系统的各种事件和内核进程,还可以用来分析指定应用程序的性能问题


perf top 类似于 top ,它能够实时显示占用CPU时钟最多的函数或者指令,因此可以查找出热点函数


$ perf topSamples: 833  of event 'cpu-clock', Event count (approx.): 97742399Overhead  Shared Object       Symbol   7.28%  perf                [.] 0x00000000001f78a4   4.72%  [kernel]            [k] vsnprintf   4.32%  [kernel]            [k] module_get_kallsym   3.65%  [kernel]            [k] _raw_spin_unlock_irqrestore


从输出结果我们可以看出:


第一行包含三个数据:采样数(Samples)、事件类型(event)和事件总数量(Event count)。这个例子中 perf 总共采集了833个CPU时钟时间,而总事件数为97742399


接着我们从列的角度来看:

  • 第一列:Overhead ,是该符号的性能事件在所有采样中的比例,用百分比来表示

  • 第二列::Shared ,是该函数或指令所在的动态共享对象(Dynamic Shared Object),如内核、进程名、动态链接库名、内核模块名等。

  • 第三列 :Object 是动态共享对象的类型。比如 [.] 表示用户空间的可执行程序、或者动态链接库,而 [k] 则表示内核空间。

  • 第四列:Symbol 是符号名,也就是函数名。当函数名未知时,用十六进制的地址来表示。


perf record 、perf report


perf top 虽然实时展示了系统的性能信息,但是它并不能保存数据,就意味着无法用于离线或者后续的分析


而perf record 则提供了保存数据的功能,保存后的数据,需要你用 perf report 解析展示。


$ perf record # 按Ctrl+C终止采样[ perf record: Woken up 1 times to write data ][ perf record: Captured and wrote 0.452 MB perf.data (6093 samples) ]
$ perf report # 展示类似于perf top的报告。有时候还会加上-g参数来开启调用关系的采样


03
案例


下面我将用极客时间里的一个例子,来展现当我们发现CPU使用率过高的问题后,要怎么使用各种性能工具找出异常的进程,又要怎么利用各种工具找出引发性能问题的函数


这次案例里面,我们预先安装了 sysstat、perf、ab 等工具



左边这台用作 Web 服务器,来模拟性能问题;右边用作客户端,来给 Web 服务器增加压力请求


首先运行我们的 web 服务器,运行之后验证一下 Nginx 是否正常开启

$curl 192.168.1.1:80
It works!


接下来我们在客户端测试一下 web 服务器的性能

# 并发10个请求测试Nginx性能,总共测试100个请求$ ab -c 10 -n 100 http://192.168.1.1:80This is ApacheBench, Version 2.3 <$Revision: 1706008 $>Copyright 1996 Adam Twiss, Zeus Technology Ltd, ...Requests per second:    11.63 [#/sec] (mean)Time per request:       859.942 [ms] (mean)...


从ab的输出可以看到,Nginx能承受的每秒平均请求数只有11.63。这个结果说明Nginx 目前的性能不尽人意,我们先用top和pidstat看一下到底是哪里出了问题


运行ab命令,持续给Nginx压力,方便我们使用性能分析工具

#并发10个请求,总共10000个请求$ ab -c 10 -n 10000 http://192.168.1.1:80


运行 top 命令,按下数字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使用率骤升


接下来我们需要找出 php-fpm 进程里面哪个函数导致了CPU使用率的升高


首先运行我们的 perf top 命令,实时分析进程的CPU问题


# -g参数开启调用关系分析,-p指定php-fpm的进程号21515$ perf top -g -p 21515


按方向键切换到php-fpm,再按下回车键开php-fpm的调用关系,你会发现,调用关系最终到了sqrt 和add_ function函数。



找出了函数后我们再查看源码并修改优化


优化后我们再测试一下

$ ab -c 10 -n 10000 http://192.168.1.1:80...Complete requests:      10000Failed requests:        0Total transferred:      1720000 bytesHTML transferred:       90000 bytesRequests per second:    2237.04 [#/sec] (mean)Time per request:       4.470 [ms] (mean)Time per request:       0.447 [ms] (mean, across all concurrent requests)Transfer rate:          375.75 [Kbytes/sec] received


04
总结


CPU使用率是最直观和最常用的系统性能指标,更是我们在排查性能问题时,通常会关注的第一个指标。


碰到CPU使用率升高的问题,可以先借助top,pidstat等工具,确认引发CPU性能问题的来源。


在使用perf等工具,进一步排查引起性能问题的具体函数


  • 用户CPU和Nice CPU高:说明用户态进程占用了较多的CPU时间,应着重排查进程的性能问题

  • 系统CPU高:说明内核态进程占用了较多的CPU时间,应着重排查系统存储是不是出现了I/O问题

  • I/O等待CPU高:说明等待I/O时间较长,应着重排查系统存储是不是出现了I/O问题

  • 软中断和硬中断高:说明软中断或硬中断的处理程序占用了较多的CPU时间,应着重排查内核中的中断服务程序




原文作者:咸鱼运维杂谈;如有侵权,请联系管理员删除。

上一篇: 好久不见
请登录后发表评论 登录
全部评论
最新的技术文章首先发布在微信公众号:咸鱼运维杂谈 擅长Linux系统维护、开源软件维护、自动化运维等领域,博客主要偏向于学习笔记及经历分享

注册时间:2021-05-29

  • 博文量
    193
  • 访问量
    84227