不知道大家有没有遇到过服务器。CPU如果利用率达到100%,在实际生产环境中遇到这种情况该怎么办?
接下来,我将与您讨论:当CPU当利用率达到100%时,我们应该如何调查、定位和找出问题的根源。
CPU使用率
Linux作为一个多任务操作系统,每个任务操作系统都将被使用CPU时间分为短时间片,然后通过调度器轮流分配给每个任务,造成多任务同时进行的错觉。
CPU利用率:是的CPU非空闲时间占总时间CPU时间百分比
而CPU利用率也有许多重要的指标,我们可以通过 top 简单列出命令
user(缩写为 us),代表用户态 CPU 时间。注意,它不包括以下内容 nice 但包括时间 guest 时间。注意,它不包括以下内容 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 时间。
如何查看CPU使用率
在介绍查看CPU在使用工具之前,让我们考虑一个问题:如何计算这些性能工具?CPU使用率的?
实际上,为了计算CPU在利用率方面,大多数性能工具通常在间隔一段时间(如3秒)的两次值之后,然后计算这段时间内的平均值CPU使用率
这个公式是大多数性能工具所看到的CPU实际计算利用率的方法。因此,在使用这些工具时,我们应该注意间隔时间的设置
top 工具和 ps 工具
top 和 ps 是最常用的性能分析工具,其中:
top 显示系统总体的CPU和内存使用情况,以及各个进程的资源使用情况
ps 显示每个进程的资源使用情况
sysstat 工具
除了上面这两个最常用的工具之外,我们还可以使用 sysstat 工具中的 pidstat 命令来查看进程的CPU使用率
上面这些工具你可以轻松找出哪个CPU使用率较高的进程,但是找到进程还不够,我们还想找出是哪个具体进程或者具体函数占用了如此高的CPU时间,这样才能进行更好的优化、
这里我推荐一个可以在第一时间分析进程的CPU问题的工具——perf
perf top
perf 是一种 Linux 内置的性能分析工具。它以性能事件采样为基础,不仅可以分析系统的各种事件和内核进程,还可以用来分析指定应用程序的性能问题
perf top 类似于 top ,它能够实时显示占用CPU时钟最多的函数或者指令,因此可以查找出热点函数
从输出结果我们可以看出:
第一行包含三个数据:采样数(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 解析展示。
案例
下面我将用极客时间里的一个例子,来展现当我们发现CPU使用率过高的问题后,要怎么使用各种性能工具找出异常的进程,又要怎么利用各种工具找出引发性能问题的函数
这次案例里面,我们预先安装了 sysstat、perf、ab 等工具
左边这台用作 Web 服务器,来模拟性能问题;右边用作客户端,来给 Web 服务器增加压力请求
首先运行我们的 web 服务器,运行之后验证一下 Nginx 是否正常开启
接下来我们在客户端测试一下 web 服务器的性能
从ab的输出可以看到,Nginx能承受的每秒平均请求数只有11.63。这个结果说明Nginx 目前的性能不尽人意,我们先用top和pidstat看一下到底是哪里出了问题
运行ab命令,持续给Nginx压力,方便我们使用性能分析工具
运行 top 命令,按下数字1,切换到每个CPU使用情况(单核系统不需要按)
这里我们可以看到:
系统中这几个php-fpm进程的CPU使用率加起来将近200%;而每个CPU的用户态使用率(us)也已经超过了98%
所以我们可以得出结论:用户空间的php-fpm进程,导致了CPU使用率骤升
接下来我们需要找出 php-fpm 进程里面哪个函数导致了CPU使用率的升高
首先运行我们的 perf top 命令,实时分析进程的CPU问题
按方向键切换到php-fpm,再按下回车键开php-fpm的调用关系,你会发现,调用关系最终到了sqrt 和add_ function函数。
找出了函数后我们再查看源码并修改优化
优化后我们再测试一下