关于linux系统CPU篇--->CPU使用率升高
1.CPU使用率为单位时间内CPU使用情况的统计,以百分比的方式展示。
LINUX作为一个多任务操作系统,将每个CPU的时间划分为很短的时间片,再通过调度器轮流分配给各个任务使用,因此造成多任务同时运行的错觉
2.如何查看CPU使用率?
TOP和PS是最常用的性能分析工具。TOP显示了系统总体的CPU和内存使用情况,以及各个进程的资源使用情况
PS则只显示了每个进程的资源使用情况
pidstat是专门分析每个进程的CPU使用情况的工具
TOP输出:
# 默认每 3 秒刷新一次
$ top
top - 11:58:59 up 9 days, 22:47,  1 user,  load average: 0.03, 0.02, 0.00
Tasks: 123 total,   1 running,  72 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.3 us,  0.3 sy,  0.0 ni, 99.3 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem :  8169348 total,  5606884 free,   334640 used,  2227824 buff/cache
KiB Swap:        0 total,        0 free,        0 used.  7497908 avail Mem
PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
    1 root      20   0   78088   9288   6696 S   0.0  0.1   0:16.83 systemd
    2 root      20   0       0      0      0 S   0.0  0.0   0:00.05 kthreadd
    4 root       0 -20       0      0      0 I   0.0  0.0   0:00.00 kworker/0:0H
TOP默认显示的是所有CPU的平均值,这时候按下1,就可以切换到每个CPU的使用率了
从top的输出中,可以看到,%CPU列展示的就是CPU使用率:
us:代表用户CPU时间,它不包括nice时间,但是包括guest时间
nice(ni):代表低优先级用户态CPU时间,也就是进程的nice值被调整为1-19之间的CPU时间。这里注意,nice可取值范围是-20到19,数值越大,优先级反而越低。
sy:代表内核态CPU时间
id:代表空闲时间,注意,它不包括等待IO的时间
iowait:通常缩写为wa,代表等待IO的CPU时间
irq:代表处理硬中断的CPU时间
si:代表处理软中断的CPU时间
st:代表系统在运行虚拟机中的时候,被其他虚拟机占用的CPU时间
guest:代表通过虚拟化运行其他操作系统的时间,也就是运行虚拟机的CPU时间
guest_nice(gnice):代表以低优先级运行虚拟机的时间
下面的pidstat命令,就间隔1秒,展示了进程的5组CPU使用率,包括:
%usr用户态CPU使用率
%system 系统CPU使用率
%guest 运行虚拟机CPU使用率
%wait 等待IO CPU使用率
%cpu 总的CPU使用率
最后的average部分,还计算了5组数据的平均值
pidstat输出:
# 每隔 1 秒输出一组数据,共输出 5 组
$ pidstat 1 5
15:56:02      UID       PID    %usr %system  %guest   %wait    %CPU   CPU  Command
15:56:03        0     15006    0.00    0.99    0.00    0.00    0.99     1  dockerd
...
Average:      UID       PID    %usr %system  %guest   %wait    %CPU   CPU  Command
Average:        0     15006    0.00    0.99    0.00    0.00    0.99     -  dockerd
3.CPU使用率过高怎么办?
使用top,ps,pidstat等工具,能够轻松找到占用CPU使用率较高(100%)的进程,接下来,你可能想知道占用CPU的是哪个函数呢,找到它,才能更有效,更针对性的进行性能优化。
那么那种工具最适合在第一时间分析进程的CPU问题呢,推荐的是perf。perf是linux2.6.31以后内置的性能分析工具,包含了perf top ,perf record,perf report
第一种:perf top,类似于top,它能够实时显示占用CPU时钟最多的函数或者指令,因此可以用来查找热点函数,使用界面如下:
$ perf top
 Samples: 833  of event 'cpu-clock', Event count (approx.): 97742399
 Overhead  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
...
输出结果中,第一行包含三个数据,分别是采样数,事件类型和事件总数量,输出中可以看到perf采集了833个CPU时钟事件,而总事件数则为97742399
如果输出结果中,采样数(Samples)只有10几个,那下面的排序和百分比就没什么实际参考价值
Overhead:该符号的性能事件,在所有采样中的比例,用百分比来展示
Shared:该函数或指令所在的动态共享对象(Dynamic Shared Object),如内核,进程名,动态连接库名,内核模块名等
Object:动态共享对象的类型。比如[.]表示用户空间的可执行程序,或者动态链接库,而[k]则表示内核空间
Symbol:是符号名,也就是函数名。当函数名未知时,用十六进制地址表示
从上面的输出中可以看到,占用CPU最多的是perf工具自身,不过它的比例也只有7.28%,说明系统并没有CPU性能问题。
第二种常见用法:也就是perf record和perf report
perf record 提供了保存数据的功能,保存后的数据,可以用perf report 解析展示
4.案例分析:
(1).使用两台linux虚拟机,其中一台用作web服务器,模拟性能问题。需要安装docker,nginx,perf,sysstat等工具
另外一台用作客户端,需要安装ab,curl
(2).在第一台虚拟机中执行下面命令运行nginx和php应用:
docker run --name nginx -p 10000:80 -itd feisky/nginx
docker run --name phpfpm -itd --network container:nginx feisky/php-fpm
(3).在第二台虚拟机(客户端)执行curl 命令,确认nginx已经正常启动:
# 192.168.0.10 是第一台虚拟机的 IP 地址
$ curl http://192.168.0.10:10000/
It works!
(4).测试nginx服务的性能:
# 并发 10 个请求测试 Nginx 性能,总共测试 100 个请求
 $ ab -c 10 -n 100 http://192.168.0.10:10000/
 This 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.性能比较差
(5)继续执行ab,将请求数增加到10000,这样在第一个终端使用性能分析工具时,nginx压力还是继续
ab -c 10 -n 10000 http://192.168.0.10:10000/
(6).回到第一个终端运行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+ COMMAND
21514 daemon    20   0  336696  16384   8712 R  41.9  0.2   0:06.00 php-fpm
21513 daemon    20   0  336696  13244   5572 R  40.2  0.2   0:06.08 php-fpm
21515 daemon    20   0  336696  16384   8712 R  40.2  0.2   0:05.67 php-fpm
21512 daemon    20   0  336696  13244   5572 R  39.9  0.2   0:05.87 php-fpm
21516 daemon    20   0  336696  16384   8712 R  35.9  0.2   0:05.61 php-fpm
发现占用CPU最多的是PHP-fpm进程
(7).怎么知道是php-fpm的那个函数导致了CPU使用率升高呢,我们来用perf分析一下。在第一个终端运行下面的perf命令
# -g 开启调用关系分析,-p 指定 php-fpm 的进程号 21515
  $ perf top -g -p 21515
(8).按方向键切换到php-fpm,再按下会车键展开php-fpm的调用关下,发现调用关系最终到了sqrt和add_function

(9).拷贝出nginx应用的源码,看看是不是调用了这两个函数:
# 从容器 phpfpm 中将 PHP 源码拷贝出来
$ docker cp phpfpm:/app .
# 使用 grep 查找函数调用
$ grep sqrt -r app/ # 找到了 sqrt 调用
app/index.php:  $x += sqrt($x);
$ grep add_function -r app/ # 没找到 add_function 调用,这其实是 PHP 内置函数
原来只有sqrt函数在ap/idex.php文件中调用了。看看这个文件的源码:
$ cat app/index.php
<?php
// test only.
$x = 0.0001;
for ($i = 0; $i <= 1000000; $i++) {
  $x += sqrt($x);
}
echo "It works!"
发现原来是测试代码没删就直接发布应用了。
(10).优化:
# 停止原来的应用
$ docker rm -f nginx phpfpm
# 运行优化后的应用
$ docker run --name nginx -p 10000:80 -itd feisky/nginx:cpu-fix
$ docker run --name phpfpm -itd --network container:nginx feisky/php-fpm:cpu-fix
(11).重新在第二台虚拟机中测试nginx性能:
$ ab -c 10 -n 10000 http://10.240.0.5:10000/
...
Complete requests:      10000
Failed requests:        0
Total transferred:      1720000 bytes
HTML transferred:       90000 bytes
Requests 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
...
从这里可以发现,现在每秒的请求数,已经从原来的11变成了2237
总结:
CPU使用率是最直观和最常用的系统性能指标,更是我们在排查系统性能问题时。通常会关注的第一个指标。所以我们要熟悉它的含义,尤其要弄清楚用户(user%)、NIce(%nice)、系统(%system),等待IO(%iowait),中断(%irq),软中断(%softirq)
这几种不同的CPU使用率。
(1).用户和Nice CPU高,说明用户进程占用了较多的CPU,所以应该着重排查进程的性能问题
(2).系统CPU高,说明内核态占用了较多的CPU,所以应该着重排查内核线程或系统调用的性能问题
(3).IO等待CPU高,说明等待IO的时间比较长,应该着重排查系统存储是不是出现了IO问题
(4).软中断和硬中断高,说明软中断或硬中断处理程序占用了较多的CPU,所以应该着重排查内核中的中断服务程序
碰到CPU使用率升高的问题,可以借助TOP,pidstat等工具,确认引发CPU性能问题的来源,再使用perf等工具,排查出引起性能问题的具体函数
关于linux系统CPU篇--->CPU使用率升高的更多相关文章
- 操作系统复习——如何查看一个进程的详细信息,如何追踪一个进程的执行过程 ,如何在 Linux 系统下查看 CPU、内存、磁盘、IO、网卡情况?epoll和select区别?
		1. 如何查看一个进程的详细信息,如何追踪一个进程的执行过程 通过pstree命令(根据pid)进行查询进程内部当前运行了多少线程:# pstree -p 19135(进程号) 使用top命令查看(可 ... 
- Linux系统排查2——CPU负载篇
		本随笔介绍CPU负载的排查手段. 查看系统负载的工具:uptime,w,都能查看系统负载,系统平均负载是处于运行或不可打扰状态的进程的平均数, 可运行:运行态,占用CPU,或就绪态,等待CPU调度. ... 
- 查看Linux系统内存、CPU、磁盘使用率和详细信息
		一.查看内存占用 1.free # free -m 以MB为单位显示内存使用情况 [root@localhost ~]# free -m total used free shared buff/cac ... 
- Linux系统调优——CPU(一)
		(1).系统调优思路 性能优化就是找到系统处理中的瓶颈以及去除这些的过程,性能优化其实是对OS 各子系统达到一种平衡的定义.具体步骤如下: 1. 系统的运行状况: CPU -> MEM -& ... 
- 监测linux系统负载与CPU、内存、硬盘、用户数的shell脚本
		本节主要内容: 利用Shell脚本来监控Linux系统的负载.CPU.内存.硬盘.用户登录数. 一.linux系统告警邮件脚本 # vim /scripts/sys-warning.sh #!/bin ... 
- Linux系统如何查看CPU型号等
		有时候在下载jdk或其它用图的时候,可能需要查看一下这个cpu的型号 [root@subvm ~]# less /proc/cpuinfo |grep modelmodel : 4 ... 
- Linux系统下的CPU、内存、IO、网络的压力测试
		本文转载自:小豆芽博客 一.对CPU进行简单测试: 1.通过bc命令计算特别函数 例:计算圆周率 echo "scale=5000; 4*a(1)" | bc -l -q MATH ... 
- Linux系统发现占用CPU达100%的进程并处理
		转至:https://blog.csdn.net/xinxin_2011/article/details/84936581 服务器使用的是Centos7.2 64位系统.发现服务器异常,一般先想到用t ... 
- Linux下java获取CPU、内存、磁盘IO、网络带宽使用率
		一.CPU 使用proc文件系统,"proc文件系统是一个伪文件系统,它只存在内存当中,而不占用外存空间.它以文件系统的方式为访问系统内核数据的操作提供接口.用户和应用程序可以通过proc得 ... 
随机推荐
- [LeetCode] Domino and Tromino Tiling 多米诺和三格骨牌
			We have two types of tiles: a 2x1 domino shape, and an "L" tromino shape. These shapes may ... 
- [LeetCode] Design Circular Deque 设计环形双向队列
			Design your implementation of the circular double-ended queue (deque). Your implementation should su ... 
- java反射机制的简单使用
			java 反射机制 反射机制简介 参考地址 什么是反射机制 反射机制指程序在运行时能够获取自身的信息.在java中只要给定类的名字,就可以通过反射机制获得类的所有信息 反射机制的优缺点 首先了解一下动 ... 
- new image()
			在js中 新建一个new image()对象,image.src图片地址,这个是io读取是异步的,解决方法 image.onload=function(){ } 
- CSS---光标cursor设置、浮动布局与clear的关系
			光标设置 {cursor:auto;}--光标根据需要自动变化. {cursor:crosshair;}--光标变成“+”. {cursor:pointer;}--光标变成手指模式. {cursor: ... 
- java中String常量的存储原理
			相关题目(运行结果在代码注释后面) 1. package StringTest; public class test1 { public static void main(String[] args) ... 
- 是否能设计一种DNN的特定网络结构来改善DNN,使得其学习起来更加高效
			小结: 1. 是否能设计一种DNN的特定网络结构来改善DNN,使得其学习起来更加高效 https://mp.weixin.qq.com/s/lF_WLAn6JyQqf10076hsjA Deep &a ... 
- js基础--数据类型
			1,数据类型 Number:包括小数与整数,负数,NaN ,Infinity无限大String字符串:‘abc’Boolean布尔值:true or falsenull 空undefined 未定义 ... 
- LeetCode 169 Majority Element 解题报告
			题目要求 Given an array of size n, find the majority element. The majority element is the element that a ... 
- pandas(一)
			import numpy as py import pandas as pd Series对象 data= pd.Series([0.25,0.5,0.75,1.0]) 默认索引是数字 data= ... 
