拓展阅读

JVM FULL GC 生产问题 I-多线程通用实现

JVM FULL GC 生产问题 II-如何定位内存泄露? 线程通用实现

JVM FULL GC 生产问题 III-多线程执行队列的封装实现,进一步抽象

jvisualvm java 性能分析工具

jvm-44-jvm 内存性能分析工具 Eclipse Memory Analyzer Tool (MAT) / 内存分析器 (MAT)

jvm-45-jvm dump 文件内存介绍+获取方式+堆内存可视分析化工具

jvm-46-jvm Thread Dump 线程的堆栈跟踪信息+获取方式+可视分析化工具 FastThread

jvm-47-jvm GC 日志获取方式+可视分析化工具 GcViewer

jvm-48-java 变更导致压测应用性能下降,如何分析定位原因?

jvm-49-linux 服务器 cpu 使用率升高应该如何排查分析?

前言

大家好,我是老马。

有时候我们监控了应用的 cpu 使用率,过高的时候需要分析排查,那么一般的分析流程应该是什么样的?

应用方面

我们首先要看一下应用层面是否最近发生过变更,比如配置变更+应用发布。

或者是存在定时的跑批等。

如果是周期性的,可以考虑忽略,或者调整对应报警的阈值。

业务流量

可能存在一些特别大的任务处理/查询之类的,可以通过应用日志确认。

可能应用业务量飙升,首先看请求网络流量/CAT请求统计是否升高;

或者应用本身的服务是否正常,导致每一台的处理压力上升?

linux 机器方面

当 Linux 服务器的 CPU 使用率升高时,可能有多种原因,排查问题需要系统地分析。

以下是一些常见的排查步骤:

检查整体 CPU 使用情况

首先,你可以使用一些常用的命令查看系统整体的 CPU 使用率:

  • top:查看实时的系统资源使用情况。
    • 1 键查看每个 CPU 核心的使用情况。
  • htop:类似于 top,但是提供了更友好的界面,能显示更多的信息(如果未安装,可以使用 sudo apt install htop 安装)。
  • uptimew:查看系统负载(1、5、15 分钟的平均负载)。

top 效果

我们以 WSL 为例

linux top 介绍

  [plaintext]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$ top top - 17:37:38 up 6 min, 1 user, load average: 0.04, 0.13, 0.08 Tasks: 38 total, 1 running, 37 sleeping, 0 stopped, 0 zombie %Cpu(s): 0.1 us, 0.1 sy, 0.0 ni, 99.8 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st MiB Mem : 15962.4 total, 14373.8 free, 932.2 used, 656.4 buff/cache MiB Swap: 4096.0 total, 4096.0 free, 0.0 used. 14765.8 avail Mem PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 1 root 20 0 167068 12564 8220 S 2.0 0.1 0:06.03 systemd 325 mysql 20 0 2308084 403664 35500 S 1.0 2.5 0:02.99 mysqld 611 root 20 0 43372 36876 10276 S 0.7 0.2 0:03.56 python3 497 root 20 0 154392 69488 18200 S 0.3 0.4 0:03.83 python3.10 2 root 20 0 2616 1444 1320 S 0.0 0.0 0:00.00 init-systemd(Ub 9 root 20 0 2616 4 0 S 0.0 0.0 0:00.00 init 44 root 19 -1 47836 15480 14396 S 0.0 0.1 0:00.13 systemd-journal 69 root 20 0 22224 6104 4560 S 0.0 0.0 0:00.24 systemd-udevd 88 root 20 0 4496 204 56 S 0.0 0.0 0:00.00 snapfuse 94 root 20 0 4628 176 24 S 0.0 0.0 0:00.00 snapfuse

具体 cpu 效果

按下 1

  [plaintext]
1
2
3
4
5
6
7
8
9
10
11
12
$ top top - 17:59:36 up 28 min, 1 user, load average: 0.05, 0.05, 0.06 Tasks: 39 total, 1 running, 36 sleeping, 2 stopped, 0 zombie %Cpu0 : 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st %Cpu1 : 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st %Cpu2 : 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st %Cpu3 : 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st %Cpu4 : 0.0 us, 0.3 sy, 0.0 ni, 99.7 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st %Cpu5 : 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st ... MiB Mem : 15962.4 total, 14659.2 free, 963.8 used, 339.3 buff/cache MiB Swap: 4096.0 total, 4096.0 free, 0.0 used. 14735.0 avail Mem

按照 %CPU% 排序

top 界面中,按 P 键(大写的 P)来按 CPU 使用率排序。

默认情况下,top 是按照进程 ID 排序的,通过按 P 键,你可以切换到按照 CPU 使用率(%CPU)排序。

  • P 键后,进程会按照 %CPU 由高到低进行排序,进程使用 CPU 的百分比会显示在 %CPU 列中。

  • q 键退出 top 命令的交互界面。

效果:

  [plaintext]
1
2
3
4
5
6
7
8
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 1 root 20 0 167068 12568 8220 S 2.0 0.1 0:29.47 systemd 325 mysql 20 0 2308084 421892 35500 S 1.0 2.6 0:12.09 mysqld 611 root 20 0 43372 37364 10276 S 1.0 0.2 0:12.41 python3 2 root 20 0 2616 1444 1320 S 0.0 0.0 0:00.00 init-systemd(Ub 9 root 20 0 2616 4 0 S 0.0 0.0 0:00.00 init 44 root 19 -1 47836 15508 14424 S 0.0 0.1 0:00.14 systemd-journal 69 root 20 0 22224 6104 4560 S 0.0 0.0 0:00.24 systemd-udevd

分析高 CPU 使用的进程

如果发现某个进程使用了大量 CPU,进一步分析该进程的原因:

  • 检查该进程是否为正常进程,是否是你期望运行的服务。

  • 如果是某个应用程序或服务导致的,查看该应用的日志文件(通常位于 /var/log/ 或应用特定的日志目录)。

系统日志

查看系统日志文件,可能会发现一些错误信息,帮助排查原因:

  • /var/log/syslog/var/log/messages:一般的系统日志。

  • /var/log/dmesg:内核日志,特别是硬件相关的问题。

  • /var/log/auth.log:检查是否有未授权的访问。

检查 I/O 操作

过度的磁盘 I/O 或网络 I/O 也可能导致 CPU 使用率升高。

你可以使用以下命令进行检查:

  • iostat:查看磁盘的 I/O 情况。

  • iotop:实时监控磁盘 I/O(需要 root 权限)。

  • netstat -tulnss -tuln:查看当前的网络连接,判断是否有大量的网络通信导致 CPU 占用增加。

iostat 效果

linux iostat 介绍

  [plaintext]
1
2
3
$ iostat Command 'iostat' not found, but can be installed with: sudo apt install sysstat

提示没安装,我们安装一下

  [plaintext]
1
sudo apt install sysstat

再次执行:

  [plaintext]
1
2
3
4
5
6
7
8
9
10
$ iostat Linux 5.15.167.4-microsoft-standard-WSL2 (PC-20230404XHIO) 11/30/24 _x86_64_ (20 CPU) avg-cpu: %user %nice %system %iowait %steal %idle 0.19 0.01 0.13 0.08 0.00 99.60 Device tps kB_read/s kB_wrtn/s kB_dscd/s kB_read kB_wrtn kB_dscd sda 0.44 29.22 0.00 0.00 78933 0 0 sdb 0.04 0.82 0.00 0.00 2228 4 0 sdc 7.03 209.14 51.84 172.57 564925 140028 466136

检查内存是否充足

如果系统内存不足,可能会导致大量的交换(swap)操作,进而增加 CPU 使用率。

使用以下命令查看内存使用情况:

  • free -h:查看内存和交换空间的使用情况。

  • vmstat:查看内存的交换(swap)情况。

free 效果

这个是很常用的一个命令:

  [plaintext]
1
2
3
4
$ free -h total used free shared buff/cache available Mem: 15Gi 961Mi 14Gi 3.0Mi 398Mi 14Gi Swap: 4.0Gi 0B 4.0Gi

linux free 命令

vmstat 效果

  • vmstat 1:每秒显示一次系统的虚拟内存统计信息,包含 CPU 使用、进程、内存等数据。

下面的命令是 2S 一次,共计 5 次。

  [plaintext]
1
2
3
4
5
6
7
8
$ vmstat 2 5 procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu----- r b swpd free buff cache si so bi bo in cs us sy id wa st 0 0 0 15061208 2616 302412 0 0 31 8 11 47 0 0 99 0 0 0 0 0 15060708 2616 302412 0 0 0 0 60 531 0 0 100 0 0 0 0 0 15062192 2616 302412 0 0 0 0 76 542 0 0 100 0 0 0 0 0 15061940 2616 302412 0 0 0 0 63 535 0 0 100 0 0 0 0 0 15062192 2616 302412 0 0 0 0 59 531 0 0 100 0 0

linux vmstat 介绍

其他

如果上面都分析了一遍,下面的也可作为一种思路参考,但是一般可能性比较低。

检查是否存在恶意进程

如果系统中出现了不明进程,可能是被攻击或有恶意软件。

你可以:

  • 使用 pstop 查找不明进程。

  • 检查异常进程的启动时间和路径,判断是否是恶意软件或病毒。

检查定时任务和后台进程**

定时任务(如 cron)或后台服务(如守护进程)可能会在特定时间执行大量计算或其他操作。

检查是否有定时任务异常:

  • crontab -l:查看当前用户的定时任务。

  • sudo crontab -l:查看 root 用户的定时任务。

这种一般比较少,不过还是有一些系统通过 cron 实现调度的。

检查系统资源限制

可能存在系统资源限制导致某些进程被迫大量占用 CPU。

可以检查以下参数:

  • ulimit -a:查看当前用户的资源限制。

  • sysctl -a:查看系统的内核参数配置,尤其是与进程调度和资源限制相关的参数。

小结

可以发现,如果我们没有统一的监控平台,可能还是要对 linux 的命令比较熟悉。

有一些统一监控系统,比如普米/zabbix,问题排查会更加直观一些。但是排查思路是一样的。

希望本文对你有所帮助,如果喜欢,欢迎点赞收藏转发一波。

我是老马,期待与你的下次相遇。