凌峰创科服务平台

Linux服务器CPU100%如何快速定位原因?

找到元凶 -> 分析原因 -> 解决问题

Linux服务器CPU100%如何快速定位原因?-图1
(图片来源网络,侵删)

下面我将为你提供一个详细的、分步的排查和解决方案。


第一步:应急处理

如果服务器已经完全无响应,你可能需要通过其他方式登录,

  • 物理控制台:直接在机房连接显示器和键盘。
  • 带外管理:通过 iDRAC, iLO, IPMI 等远程管理卡。
  • SSH 强制连接:有时 SSH 仍能连接,但会非常慢。

第二步:找到占用 CPU 100% 的元凶

一旦能登录到服务器,我们需要找到是哪个进程在作怪,主要使用 tophtop 命令。

使用 top 命令(经典方法)

  1. 输入 top 并回车,你会看到一个实时更新的进程列表。
  2. P:确保进程列表是按照 %CPU(CPU 使用率)从高到低排序的。
  3. 观察列表顶部的进程:找到 CPU% 列最高的那个进程,这就是你的“元凶”。

top 命令输出关键信息解读:

Linux服务器CPU100%如何快速定位原因?-图2
(图片来源网络,侵删)
top - 10:30:00 up 10 days,  2:15,  1 user,  load average: 5.45, 5.12, 4.98
Tasks: 123 total,   2 running, 121 sleeping,   0 stopped,   0 zombie
%Cpu(s): 99.3% us,  0.2% sy,  0.0% ni,  0.5% id,  0.0% wa,  0.0% hi,  0.0% si,  0.0% st
KiB Mem : 16384000 total,   2048000 free,   8192000 used,   6144000 buff/cache
KiB Swap:      0 total,        0 free,        0 used.   8192000 avail Mem
  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
12345 nginx     20   0  123456  78910  12345 R  99.9  0.5   10:30:01 httpd  # <-- 这就是元凶!
67890 mysql     20   0  987654  543210 98765 S  0.1  3.2 120:45:67 mysqld
...
  • PID:进程 ID,这是最重要的信息,用于后续操作。
  • %CPU:该进程的 CPU 使用率。
  • COMMAND:进程名。

使用 htop 命令(更直观)

如果你的系统安装了 htopyum install htopapt install htop),它比 top 更好用。

  1. 输入 htop 并回车
  2. 默认就是按 CPU 使用率排序。
  3. 用鼠标或方向键选中占用 CPU 最高的进程,按 F9 可以直接杀死它,非常方便。

第三步:深入分析元凶

找到 PID 和进程名后,你需要判断它为什么会占用如此高的 CPU。

场景1:可以立即杀死的进程

如果进程是一个临时性、非关键的任务,比如一个编译脚本、一个跑飞的 Python 脚本等,最直接的方法就是杀死它。

  • 正常杀死

    kill <PID>

    kill 12345

  • 强制杀死(如果正常杀死无效):

    kill -9 <PID>

    kill -9 12345 警告kill -9 是强制终止,进程无法做任何清理工作,可能会导致数据损坏或文件锁定,请谨慎使用,仅在必要时使用。

场景2:需要分析的顽固进程

如果进程是核心服务(如 nginx, httpd, mysqld, java 等),不能轻易杀死,你需要分析它到底在做什么。

步骤 1:查看进程启动命令和参数

# 使用 ps 命令
ps -ef | grep <PID>
# 或者
ps -p <PID> -o pid,ppid,cmd,etime,lstart

这能告诉你这个进程是如何被启动的,它的完整命令行是什么。

步骤 2:查看进程正在执行的代码(最关键的一步)

使用 straceperf 工具来跟踪进程的系统调用或行为。

  • 使用 strace 跟踪系统调用strace 可以告诉你进程在等待什么、在读写什么文件、在执行什么系统调用,这对于发现 I/O 瓶颈或异常行为非常有用。

    # -p 指定 PID, -f 跟踪子进程, -s 显示字符串长度, -o 输出到文件
    strace -p <PID> -f -s 999 -o /tmp/strace.log

    然后观察终端输出或 /tmp/strace.log 文件,如果看到大量的 read, write, open 等调用,说明可能在进行大量 I/O,如果看到 poll, select, epoll_wait,说明可能在等待网络或 I/O 事件。

  • 使用 perf 分析 CPU 性能(推荐) perf 是 Linux 系统自带的强大性能分析工具,可以帮你定位到具体的函数代码。

    # 采样 30 秒,将结果存入 perf.data
    perf record -g -a -- sleep 30
    # 分析结果
    perf report

    perf report 会生成一个交互式报告,你可以展开调用栈,看到是哪个函数(甚至哪一行代码)消耗了最多的 CPU,这对于定位有问题的代码(如死循环、低效算法)是致命的。

步骤 3:查看进程的线程

一个高 CPU 占用是由其某个子线程引起的,而不是主进程。

  • 使用 top 查看线程: 在 top 界面,按 H 键,会切换到线程视图,你会看到很多 /<进程名> 的条目,这些就是线程,找到其中 CPU 占用最高的那个线程。

  • 将线程 ID 转换为十六进制: 假设你找到了一个占用 CPU 很高的线程 ID 是 12346

    printf "%x\n" 12346  # 假设输出结果是 3042
  • 使用 jstack(针对 Java)或 gdb 分析线程栈

    • 对于 Java 进程

      # jstack 需要安装 JDK
      jstack <PID> > /tmp/jstack.log

      然后用 grep 搜索你刚才得到的十六进制线程 ID 3042,就能看到该线程完整的调用栈,知道它在执行什么任务。

    • 对于其他进程(如 C/C++): 使用 gdb

      gdb -p <PID>
      # (gdb) info threads  # 查看所有线程
      # (gdb) thread <TID>  # 切换到高 CPU 的线程
      # (gdb) bt            # 打印调用栈

第四步:常见原因与解决方案

通过以上分析,你通常会找到以下几种情况:

原因现象 可能原因 解决方案
某个 Web 服务进程 (httpd, nginx) 某个 PHP/Python/Java 应用有死循环、正则表达式灾难、数据库慢查询。 使用 strace/perf 定位问题脚本。
检查网站日志,找到是哪个 URL 或请求导致的问题。
修复有问题的代码,优化数据库查询。
数据库进程 (mysqld, postgres) 慢查询、锁等待、全表扫描、没有索引。 使用 SHOW PROCESSLIST; (MySQL) 或 pg_stat_activity (PostgreSQL) 查看正在执行的查询。
使用 EXPLAIN 分析慢查询的执行计划。
为相关字段添加索引。
优化 SQL 语句。
**Java 进程
分享:
扫描分享到社交APP
上一篇
下一篇