CPU利用率

什么是CPU使用率

Linux是一个典型的分时操作系统,他将每个 CPU 的时间划分为很短的时间片,再通过调度器轮流分配给各个任务使用。Linux 通过事先定义的节拍率(内核中表示为 HZ),触发时间中断,并使用全局变量 Jiffies 记录了开机以来的节拍数。每发生一次时间中断,Jiffies 的值就加 1。节拍率 HZ 是内核的可配选项,可以设置为 100、250、1000 等。可以通过如下命令查看HZ:

root@ubuntu:~# grep 'CONFIG_HZ=' /boot/config-$(uname -r)
CONFIG_HZ=250

 Linux 通过 /proc 虚拟文件系统,向用户空间提供了系统内部状态的信息。而 /proc/stat 提供的就是系统的 CPU 和任务统计信息。比方说,如果你只关注 CPU 的话,可以执行下面的命令:

root@ubuntu:~# cat /proc/stat | grep ^cpu
cpu  58559 723 270633 3250694 69925 0 84380 0 0 0
cpu0 20963 224 77260 742687 4446 0 25589 0 0 0
cpu1 15048 84 59044 843551 22039 0 16268 0 0 0
cpu2 10823 14 64387 837617 21930 0 19589 0 0 0
cpu3 11724 400 69940 826837 21508 0 22932 0 0 0

含义:

  • 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 时间。

  • guest(通常缩写为 guest),代表通过虚拟化运行其他操作系统的时间,也就是运行虚拟机的 CPU 时间。

  • guest_nice(通常缩写为 gnice),代表以低优先级运行虚拟机的时间。

CPU 使用率,就是除了空闲时间外的其他时间占总 CPU 时间的百分比,用公式来表示就是:

 

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

这个公式,就是我们用各种性能工具所看到的 CPU 使用率的实际计算方法。

 

Linux 也给每个进程提供了运行情况的统计信息,也就是 /proc/[pid]/stat。

如何观察CPU使用率

使用top命令查看CPU使用率:

root@ubuntu:~# top
top - 09:06:01 up  2:55,  4 users,  load average: 1.30, 0.31, 0.39
Tasks: 250 total,   3 running, 247 sleeping,   0 stopped,   0 zombie
%Cpu0  : 18.0 us, 62.5 sy,  0.0 ni, 14.0 id,  2.6 wa,  0.0 hi,  2.9 si,  0.0 st
%Cpu1  :  4.4 us, 13.0 sy,  0.0 ni, 65.9 id, 10.9 wa,  0.0 hi,  5.8 si,  0.0 st
%Cpu2  : 13.3 us, 17.7 sy,  0.0 ni, 56.3 id,  8.2 wa,  0.0 hi,  4.4 si,  0.0 st
%Cpu3  :  6.8 us, 38.1 sy,  0.0 ni, 44.6 id,  4.1 wa,  0.0 hi,  6.5 si,  0.0 st
MiB Mem :   7903.8 total,   5885.4 free,    400.1 used,   1618.3 buff/cache
MiB Swap:      0.0 total,      0.0 free,      0.0 used.   7219.7 avail Mem

    PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
   4256 root      20   0   58072    848      0 R  92.4   0.0   0:23.00 stress-ng
   4213 root      20   0       0      0      0 R  34.1   0.0   0:20.85 kworker/u256:0+flush-253:0
   4255 root      20   0   58072    848      0 D  32.1   0.0   0:05.98 stress-ng
   4224 root      20   0       0      0      0 I  12.6   0.0   0:04.28 kworker/u256:2-ext4-rsv-conversion
   4234 root      20   0       0      0      0 I  10.3   0.0   0:05.87 kworker/u256:1-events_power_efficient
    472 root      20   0       0      0      0 S   4.3   0.0   1:36.52 jbd2/dm-0-8
    759 root      20   0  314836   9128   7548 S   1.3   0.1   1:17.64 vmtoolsd

第一行:系统启动时间,平均负载

第二行:系统进程(任务)统计信息

第三-六行:各CPU使用统计信息

第七行:内存使用统计信息

第八行:swap内存使用统计

剩余部分:各进程占用资源统计信息

 

使用pidstat查看CPU统计信息:

root@ubuntu:~# pidstat -u 3
Linux 5.15.0-78-generic (ubuntu)        08/14/2023      _x86_64_        (4 CPU)

09:08:49 AM   UID       PID    %usr %system  %guest   %wait    %CPU   CPU  Command
09:08:52 AM     0        14    0.00    2.63    0.00    0.33    2.63     1  rcu_sched
09:08:52 AM     0       152    0.00    1.64    0.00    0.00    1.64     1  kworker/1:1H-kblockd
09:08:52 AM     0       197    0.00    1.64    0.00    0.66    1.64     3  kworker/3:1H-kblockd
09:08:52 AM     0       272    0.00    0.99    0.00    0.33    0.99     2  kworker/2:1H-kblockd
09:08:52 AM     0       472    0.00    6.91    0.00    1.97    6.91     1  jbd2/dm-0-8
09:08:52 AM     0       759    0.66    0.33    0.00    0.00    0.99     3  vmtoolsd
09:08:52 AM     0       936    0.00    0.33    0.00    0.00    0.33     0  containerd
09:08:52 AM     0      3500    0.00    0.33    0.00    0.00    0.33     3  kworker/3:0-mm_percpu_wq
09:08:52 AM     0      3505    0.00    0.33    0.00    0.00    0.33     2  kworker/2:0-mm_percpu_wq
09:08:52 AM     0      3521    0.00    0.33    0.00    0.00    0.33     0  kworker/0:2-mm_percpu_wq
09:08:52 AM     0      3942    0.00    0.33    0.00    0.00    0.33     1  kworker/1:1-mm_percpu_wq
09:08:52 AM     0      4213    0.00    2.63    0.00    0.00    2.63     2  kworker/u256:0-flush-253:0
09:08:52 AM     0      4234    0.00    8.22    0.00    0.99    8.22     2  kworker/u256:1-writeback
09:08:52 AM     0      4255    3.95   24.67    0.00    4.28   28.62     2  stress-ng
09:08:52 AM     0      4256   37.50   55.59    0.00    0.66   93.09     0  stress-ng
09:08:52 AM     0      4258    0.00   17.43    0.00    0.66   17.43     2  kworker/u256:4-flush-253:0
09:08:52 AM     0      4259    0.00   24.34    0.00    1.64   24.34     3  kworker/u256:5-ext4-rsv-conversion
09:08:52 AM     0      4261    0.33    0.99    0.00    0.00    1.32     1  pidstat

CPU使用率过高怎么办

1. 使用top或者pidstat观察 是否能找出占用cpu的进程,如果不能找出,就怀疑是大量临时任务或进程在占用cpu,从而导致top或pidstat无法观察到。

2. 如果能找出对应的进程,则使用perf工具 对进程进行采样,分析(Java可采用arthas生成火焰图),找出占用CPU的代码。

 使用perf record -g -p xxx 进行采样(xxx为进程ID),-g表示启用调用关系分析。采样一段时间后,停止。然后使用perf report命令进行分析。

Samples: 5K of event 'cpu-clock:pppH', Event count (approx.): 1433750000
  Children      Self  Command  Shared Object       Symbol
+   95.80%     0.00%  php-fpm  [unknown]           [k] 0x5706258d4c544155
+   95.80%     0.00%  php-fpm  libc-2.24.so        [.] __libc_start_main
+   39.70%     0.00%  php-fpm  [kernel.kallsyms]   [k] entry_SYSCALL_64_after_hwframe
+   39.02%     0.07%  php-fpm  [kernel.kallsyms]   [k] do_syscall_64
+   25.09%     0.00%  php-fpm  php-fpm             [.] 0x0000557e39dca8af
+   24.62%     0.31%  php-fpm  php-fpm             [.] php_request_startup
+   23.54%     0.00%  php-fpm  php-fpm             [.] 0x0000557e39dcad0d
+   23.16%     0.10%  php-fpm  php-fpm             [.] php_request_shutdown
+   19.63%     0.00%  php-fpm  php-fpm             [.] 0x0000557e39dcabf5
+   16.79%     0.44%  php-fpm  php-fpm             [.] php_execute_script
+   15.92%     0.03%  php-fpm  php-fpm             [.] sapi_deactivate
+   15.66%     0.00%  php-fpm  php-fpm             [.] 0x0000557e39dc7e8c
+   13.55%     0.00%  php-fpm  php-fpm             [.] 0x0000557e39dca8a0
+   10.74%     0.09%  php-fpm  php-fpm             [.] tsrm_realpath
+   10.71%     0.00%  php-fpm  php-fpm             [.] 0x0000557e39dc8792
  • Overhead ,是该符号的性能事件在所有采样中的比例,用百分比来表示。

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

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

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

  • Self 是最后一列的符号(可以理解为函数)本身所占比例;

  • Children 是这个符号调用的其他符号(可以理解为子函数,包括直接和间接调用)占用的比例之和。

posted @ 2023-08-15 08:51  小张同学哈  阅读(145)  评论(0)    收藏  举报