linux CPU占用率高 排查
1.用top命令查看哪个进程占用CPU高
gateway网关进程14094占用CPU高达891%,这个数值是进程内各个线程占用CPU的累加值。
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
14094 root 15 0 315m 10m 7308 S 891% 2.2 1:49.01 gateway
20642 root 17 0 17784 4148 2220 S 0.5 0.8 2:39.96 microdasys
1679 root 18 0 10984 1856 1556 R 0.3 0.4 0:22.21 sshd
22563 root 18 0 2424 1060 800 R 0.3 0.2 0:00.03 top
1 root 18 0 2156 492 460 S 0.0 0.1 0:01.59 init
2.用top -H -p pid命令查看进程内各个线程占用的CPU百分比
top -H -p 14094
top中可以看到有107个线程,但是下面9个线程占用CPU很高,下面以线程14086为主,分析其为何high CPU
PID USER PR NI VIRT RES SHR S %CPU MEM TIME+ COMMAND
14086 root 25 0 922m 914m 538m R 101 10.0 21:35.46 gateway
14087 root 25 0 922m 914m 538m R 101 10.0 10:50.22 gateway
14081 root 25 0 922m 914m 538m S 99 10.0 8:57.36 gateway
14082 root 25 0 922m 914m 538m R 99 10.0 11:51.92 gateway
14089 root 25 0 922m 914m 538m R 99 10.0 21:21.77 gateway
14092 root 25 0 922m 914m 538m R 99 10.0 19:55.47 gateway
14094 root 25 0 922m 914m 538m R 99 10.0 21:02.21 gateway
14083 root 25 0 922m 914m 538m R 97 10.0 21:32.39 gateway
14088 root 25 0 922m 914m 538m R 97 10.0 11:23.12 gateway
3.使用gstack命令查看进程中各线程的函数调用栈
gstack 14094 > gstack.log
在gstack.log中查找线程ID14086,由于函数栈会暴露函数细节,因此只显示了两个函数桢,线程ID14086对应线程号是37
Thread 37 (Thread 0x4696ab90 (LWP 14086)):
0 0x40000410 in __kernel_vsyscall ()
1 0x40241f33 in poll () from /lib/i686/nosegneg/libc.so.6
4.使用gcore命令转存进程映像及内存上下文
gcore 14094
该命令生成core文件core.14094
5。用strace命令查看系统调用和花费的时间
strace -T -r -c -p 14094
-c参数显示统计信息,去掉此参数可以查看每个系统调用话费的时间及返回值。
% time seconds usecs/call calls errors syscall
99.99 22.683879 3385 6702 poll
0.00 0.001132 0 6702 gettimeofday
0.00 0.000127 1 208 208 accept
0.00 0.000022 22 1 read
0.00 0.000000 0 1 write
0.00 0.000000 0 1 close
0.00 0.000000 0 14 time
0.00 0.000000 0 2 stat64
0.00 0.000000 0 4 clock_gettime
0.00 0.000000 0 7 send
0.00 0.000000 0 10 10 recvfrom
100.00 22.685160 13652 218 total
6.用gdb调试core文件,并线程切换到37号线程
gcore和实际的core dump时产生的core文件几乎一样,只是不能用gdb进行某些动态调试
(gdb) gdb gateway core.14094
(gdb) thread 37
[Switching to thread 37 (Thread 0x4696ab90 (LWP 14086))]#0 0x40000410 in __kernel_vsyscall ()
(gdb) where
0 0x40000410 in __kernel_vsyscall ()
1 0x40241f33 in poll () from /lib/i686/nosegneg/libc.so.6
可以根据详细的函数栈进行gdb调试,打印一些变量值,并结合源代码分析为何会poll调用占用很高的CPU。
因为代码涉及到公司产权,顾不在此做详细分析,需要明白的是分析的流程和使用的命令。
流程为:进程ID->线程ID->线程函数调用栈->函数耗时和调用统计->源代码分析
作者:liutoliu
链接:https://www.jianshu.com/p/0043df923fe1
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
Linux下CPU使用率过高的排查方法
查看CPU使用
在 Linux 系统下,使用 top 命令查看 CPU 使用情况。
%Cpu(s): 0.3 us, 0.1 sy, 0.0 ni, 99.6 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st

us(user):表示 CPU 在用户运行的时间百分比,通常用户 CPU 高表示有应用程序比较繁忙。典型的用户程序有:数据库、Web 服务器等。
sy(sys):表示 CPU 在内核态运行的时间百分比(不包括中断),通常内核态 CPU 越低越好,否则表示系统存在某些瓶颈。
ni(nice):表示用 nice 修正进程优先级的用户进程执行的 CPU 时间。nice 是一个进程优先级的修正值,如果进程通过它修改了优先级,则会单独统计 CPU 开销。
id(idle):表示 CPU 处于空闲态的时间占比,此时,CPU 会执行一个特定的虚拟进程,名为 System Idle Process。
wa(iowait):表示 CPU 在等待 I/O 操作完成所花费的时间,通常该指标越低越好,否则表示 I/O 存在瓶颈,可以用 iostat 等命令做进一步分析。
hi(hardirq):表示 CPU 处理硬中断所花费的时间。硬中断是由外设硬件(如键盘控制器、硬件传感器等)发出的,需要有中断控制器参与,特点是快速执行。
si(softirq):表示 CPU 处理软中断所花费的时间。软中断是由软件程序(如网络收发、定时调度等)发出的中断信号,特点是延迟执行。
st(steal):表示 CPU 被其他虚拟机占用的时间,仅出现在多虚拟机场景。如果该指标过高,可以检查下宿主机或其他虚拟机是否异常。
排查用户 CPU 使用率高
用户 CPU 使用率反映了应用程序的繁忙程度,通常与我们自己写的代码息息相关。
操作步骤:
1)、通过 top 命令找到 CPU 消耗最多的进程号;
2)、通过 top -Hp 进程号命令找到 CPU 消耗最多的线程号(列名仍然为 PID);
3)、通过printf "%x\n" 线程号命令输出该线程号对应的 16 进制数字;
4)、PID进程在内核调用情况。如果是Java应用可通过 jstack 进程号 | grep 16进制线程号 -A 10 命令找到 CPU 消耗最多的线程方法堆栈。
是非 Java 应用可使用 perf
perf top -p 7574
如果提示perf: command not found,使用yum install perf安装。
perf是Linux 2.6+内核中的一个工具,在内核源码包中的位置 tools/perf。
perf利用Linux的trace特性,可以用于实时跟踪,统计event计数(perf stat);或者使用采样(perf record),报告(perf report|script|annotate)的使用方式进行诊断。

浙公网安备 33010602011771号