Linux服务器运行网站、数据库、Docker应用或定时任务时,可能出现CPU占用持续升高、网站响应变慢、接口超时等情况。
处理前,需要先确认是短时间的正常计算任务,还是持续存在的资源瓶颈,再定位具体进程和业务原因。
建议按照“查看整体状态、定位进程、连续采样、检查相关资源、处理业务原因”的顺序排查。
本文以常见Linux云服务器为例。涉及进程详情和Docker的命令,建议使用root用户或具备相应权限的账户执行。示例中的进程编号、容器名称和路径,需要根据实际环境修改。
一、查看CPU使用率和系统负载

首先查看当前进程可用的逻辑CPU数量:
nproc
在通常未额外限制CPU的云服务器环境中,该结果可以帮助了解可使用的vCPU数量。
然后查看系统运行时间和平均负载:
uptime
输出中的 load average 通常对应最近1分钟、5分钟和15分钟的平均负载。
继续执行:
top -d 1
该命令每秒刷新一次运行状态。进入界面后,可以使用以下按键:
| 按键 | 作用 |
|---|---|
1 |
切换显示各逻辑CPU的使用情况 |
大写 P |
按CPU占用排序 |
c |
切换显示程序名称或命令行 |
q |
退出 |
在CPU汇总区域,重点关注:
| 字段 | 含义 | 排查方向 |
|---|---|---|
us |
用户态CPU时间 | 应用计算、脚本、数据库查询等 |
sy |
内核态CPU时间 | 系统调用及内核处理 |
id |
空闲CPU时间 | 判断是否仍有可用计算资源 |
wa |
I/O等待时间 | 结合磁盘和存储情况检查 |
si |
软中断处理时间 | 结合网络、中断等指标排查 |
st |
虚拟CPU被管理程序占用的等待时间 | 持续偏高时核查虚拟化调度情况 |
不要只看某一秒的数字。建议连续观察,并与网站访问变慢、任务启动等时间点进行对照。
二、CPU显示100%,是否代表整台服务器已经满载?
需要先区分“单个进程的CPU占用”和“整台服务器的CPU使用率”。
在常见的 top 默认Irix统计模式下,进程CPU占用以一个逻辑CPU的计算时间为基准。
例如,一台有4个可用vCPU的服务器:
| 观察到的情况 | 通常如何理解 |
|---|---|
| 单个进程接近100% | 大致使用一个vCPU的计算时间 |
| 多线程进程接近200% | 大致使用两个vCPU的计算时间 |
| 一个核心接近满载,其他核心空闲 | 可能存在单线程瓶颈或CPU绑定限制 |
| 整体空闲率长期接近0,多个核心都很忙 | 可能存在整体计算资源不足 |
不同工具和显示模式的统计口径可能不同,需要先确认百分比的含义。
单个进程达到100%,不能直接理解为整台多核服务器已经满载。
另外,Linux平均负载会计入正在运行、等待CPU以及处于不可中断等待状态的任务。因此,负载较高时,还要结合CPU使用情况和I/O等待判断。
对于主要消耗CPU的任务,负载持续超过可用逻辑CPU数量,通常提示存在排队;如果同时有大量I/O等待,则需要继续检查存储。
三、定位占用CPU较高的进程

可以先列出CPU占用靠前的进程:
ps -eo pid,ppid,user,stat,pcpu,pmem,comm --sort=-pcpu | head -n 6
该命令显示表头及前5个进程。
常用字段如下:
| 字段 | 含义 |
|---|---|
| PID | 进程编号 |
| PPID | 父进程编号 |
| USER | 运行用户 |
| STAT | 进程状态 |
| %CPU | 进程运行期间的平均CPU占用 |
| %MEM | 内存占用比例 |
| COMMAND | 程序名称 |
ps 的CPU数值是进程运行期间的平均值,不是当前这一秒的瞬时占用。 它适合初步定位,之后应使用 top 或 pidstat 连续确认。
假设需要检查的进程编号为2841,可以查看完整启动信息:
ps -p 2841 -o pid,ppid,user,etime,args
其中,etime 表示进程已经运行了多久,args 用于查看启动参数。
如果该程序包含多个线程,可以进一步执行:
top -H -p 2841
进入界面后按大写 P,观察是否某个线程持续占用较高。
后续如果进程已经重启,PID可能变化,需要重新确认,不能一直使用旧编号。
四、通过连续采样确认是否持续异常
对于短时间波动,仅看一次截图可能无法判断原因。可以使用 sysstat 中的工具连续观察。
如果系统尚未安装,Debian、Ubuntu可以执行:
apt-get update
apt-get install -y sysstat
使用DNF的系统可以执行:
dnf install -y sysstat
安装后,对指定进程每秒采样一次,共采样10次:
pidstat -u -p 2841 1 10
重点观察CPU占用是否一直较高,还是只在某几次采样中出现峰值。
查看各个逻辑CPU的使用情况:
mpstat -P ALL 1 5
根据采样结果,可以进一步区分:
-
某个进程持续消耗CPU。
-
多个进程轮流产生短时高峰。
-
单个核心长期满载。
-
多个核心同时接近满载。
-
CPU主要时间消耗在I/O等待或虚拟化调度等待上。
如果只有一个线程成为瓶颈,单纯增加vCPU数量未必能明显改善,需要结合程序的并行能力分析。
五、同时检查内存和磁盘等待
服务器卡顿有时伴随内存不足或存储等待,需要一起检查。
查看内存:
free -h
重点关注 available,不要仅因为 free 较小就判断内存不足。
继续执行:
vmstat 1 6
重点查看以下字段:
| 字段 | 含义 |
|---|---|
r |
正在运行或等待CPU的任务数量 |
b |
等待I/O完成的阻塞任务数量 |
si、so |
每秒换入、换出的内存量 |
us、sy |
用户态和内核态CPU时间 |
id |
CPU空闲时间 |
wa |
I/O等待时间 |
st |
虚拟化环境中的CPU等待时间 |
这里的 si 表示内存换入,与 top CPU汇总中的软中断字段含义不同。
vmstat 第一行的CPU、I/O等速率统计主要反映开机以来的平均情况,判断当前状态时,应重点查看后续采样。
如果可用内存较低,同时持续发生明显换入换出,应检查应用内存需求和并发数量。
如果 wa 较高、阻塞任务较多,可以进一步查看磁盘统计:
iostat -xz 1 3
结合读写量、请求延迟和设备情况判断,不能只凭某一个百分比认定磁盘故障。
如果 st 长时间明显偏高,可以记录发生时段和连续采样结果,再进一步核查虚拟化资源调度情况。
六、Docker容器CPU占用高怎么排查?

如果业务运行在Docker中,应在运行Docker的服务器上检查。
查看各容器的CPU和内存使用情况:
docker stats
只获取一次结果:
docker stats --no-stream
也可以只显示需要的字段:
docker stats --no-stream --format \
'table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}'
发现某个容器占用较高后,例如容器名为 web,查看其进程:
docker top web -eo pid,ppid,pcpu,pmem,comm
再结合容器日志排查:
docker logs --since 10m --tail 100 web
这条命令查看最近10分钟范围内的末尾日志。如果应用把日志写入容器内文件,还需要检查应用自己的日志位置。
需要注意:
-
容器CPU百分比在多核环境中可能超过100%。
-
容器进程的PID与容器内部看到的PID可能不同。
-
容器配置了CPU配额或绑定核心时,可能在整机仍有空闲资源的情况下遇到性能限制。
-
容器内程序异常重试、循环报错或任务堆积,都可能持续消耗CPU。
先确认容器、进程和具体业务,再决定是否调整并发、资源限制或程序配置。
七、常见原因分别怎么处理?
找到高CPU进程后,应结合程序用途判断,不能只根据进程名称下结论。
| 常见情况 | 建议检查内容 |
|---|---|
| PHP-FPM持续高占用 | 高访问量页面、慢接口、插件任务、重复请求和程序循环 |
| MySQL持续高占用 | 慢查询、索引、全表扫描、连接并发和报表任务 |
| Python、Java、Node.js进程高占用 | 计算任务、循环逻辑、重试机制、任务队列和运行日志 |
| 压缩、备份或编译任务占用高 | 是否为预期任务,是否与业务高峰重叠 |
| 多个定时任务同时运行 | 执行时间是否重叠,上一轮任务是否尚未结束 |
| 软中断占用偏高 | 网络包量、连接变化、中断分布及相关系统指标 |
| 不认识的程序持续高占用 | 启动来源、执行路径、运行用户和相关日志 |
如果不清楚某个程序的来源,可以查看可执行文件路径:
readlink -f /proc/2841/exe
再结合前面的进程启动参数、父进程和部署记录核实。
程序名称可以被修改,单凭名称无法判断是否正常。如果已经确认存在未授权程序,应保留必要记录,限制其影响范围,并检查入口和凭据安全。
八、业务已经变慢,应该先做什么?
在保留必要排查信息后,可以按照影响范围逐步处理。
暂停或错开非必要任务。 对已经确认的备份、压缩、报表和批量计算任务,调整到低峰执行,避免与在线业务争抢资源。
控制并发和重复执行。 如果任务队列持续堆积,应检查消费速度、重试间隔和并发设置。盲目增加工作进程,可能进一步加重资源竞争。
处理持续报错或异常循环。 如果某个程序不断重试、重复查询或循环执行,应优先修复触发原因。
结合业务情况调整访问策略。 网站出现异常请求时,可以根据日志对具体接口、来源或请求行为采取措施,同时检查缓存和应用处理效率。
必要时重启对应服务。 重启可能暂时恢复业务,但会影响连接和未完成任务,应先确认服务用途、数据状态和可接受的中断时间。
不要因为CPU高就直接强制结束数据库进程,或同时重启所有容器。对单个服务的操作,也应先确认依赖关系。
九、什么情况下需要升级CPU配置?
在排除了异常循环、重复任务和明显配置问题后,如果正常业务仍长期接近CPU容量上限,可以考虑升级或拆分服务。
| 排查结果 | 优先考虑的方向 |
|---|---|
| 多个核心持续繁忙,业务能够并行处理 | 增加vCPU或拆分业务 |
| 一个核心长期满载,其他核心较空闲 | 优化单线程逻辑,评估单核性能 |
| 主要是数据库查询消耗CPU | 优化查询、索引和缓存,再评估扩容 |
| 主要是I/O等待或内存交换 | 优先处理存储和内存瓶颈 |
| 主要受容器CPU配额限制 | 核查资源限制与实际业务需求 |
| 定时任务导致周期性高峰 | 调整执行时间、并发和任务拆分方式 |
扩容前,建议保留业务高峰时段的连续监控数据,避免只根据某一次CPU峰值判断。
十、处理后如何确认恢复正常?
处理完成后,重新观察:
top -d 1
如已安装sysstat,可以再次采样:
mpstat -P ALL 1 5
同时验证实际业务:
-
网站和接口响应是否恢复。
-
超时和错误数量是否下降。
-
后台任务是否正常完成。
-
数据库查询和任务队列是否恢复稳定。
-
原先的高CPU进程是否仍持续异常。
如果问题仍然存在,向莱卡云提交工单时,可以整理以下信息:
| 信息 | 建议提供内容 |
|---|---|
| 发生时间 | 明确日期、时间及所用时区 |
| 服务器情况 | 操作系统、vCPU数量及主要运行的业务 |
| 整体状态 | top、uptime 等输出 |
| 进程情况 | 高占用进程的PID、程序名称和连续采样结果 |
| 容器情况 | 如使用Docker,提供对应容器资源统计 |
| 业务变化 | 是否刚发布程序、增加任务或出现访问量变化 |
| 已处理事项 | 已调整的配置、暂停的任务及处理后的结果 |
发送日志和命令输出前,应去除密码、Token等敏感信息。
日常维护中,应结合业务响应时间设置CPU持续高占用告警,并保留历史监控。对于备份、报表和批量任务,合理安排执行时间和并发,便于尽早发现资源瓶颈。