「服务器好卡」是每个 Linux 用户都会遇到的报案。处理流程只有三步:找到是谁、看懂它在干什么、选择合适的处置方式。本文把 ps、top、信号这三件事按这个流程组织起来。
先定位:找到可疑进程
ps -eo pid,ppid,user,stat,etime,%cpu,%mem,args --sort=-%cpu | head这条命令按 CPU 占用倒序列出前几个进程。各列含义:PPID 是父进程,STAT 是状态,ETIME 是运行时长,ARGS 是完整命令行。
如果已经知道名字,pgrep -af nginx 直接列出 PID 和命令行;pgrep -x 要求进程名精确匹配,避免误伤。要按内存排序就把 --sort=-%cpu 换成 --sort=-%mem。
再看懂:STAT 状态列
| 状态 | 含义 | 该担心吗 |
|---|---|---|
| R | 运行中或排队等 CPU | 多核机器上大量 R 说明 CPU 饱和 |
| S | 可中断睡眠(在等事件) | 正常服务大多时间在此状态 |
| D | 不可中断睡眠(等 I/O) | 持续 D 状态指向磁盘/NFS 故障,查 dmesg |
| T | 被暂停 | 谁按了 Ctrl+Z 或发了 STOP? |
| Z | 僵尸 | 父进程没回收,杀它没用,要找父进程 |
僵尸进程本身不耗资源,只是进程表里的一个条目,正确做法是重启它的父进程。ps -eo ppid,stat,args | awk '$2 ~ /Z/' 可以快速找到僵尸的父进程。
动态观察:top 的正确打开方式
top 打开后几个按键显著提高效率:
1:展开每个 CPU 核心的使用率,判断是单线程打满还是整体饱和。M:按内存排序,P回到按 CPU 排序。c:显示完整命令行。k:在 top 里直接发信号(输入 PID 和信号编号)。
头部 load average 三个值是 1/5/15 分钟的平均负载。经验法则:负载长期超过 CPU 核心数,说明有进程在排队。但负载高不等于 CPU 高——大量 D 状态进程等磁盘也会推高负载,需要结合 %wa(iowait)一起看。
处置:信号的正确顺序
信号是发给进程的「通知」,进程可以决定怎么响应。常用的三个:
| 信号 | 编号 | 行为 |
|---|---|---|
| TERM | 15 | 请求退出,程序可以捕获并做清理(关闭连接、写盘) |
| HUP | 1 | 挂起;许多守护进程约定为重载配置 |
| KILL | 9 | 内核直接终止,不给程序任何清理机会 |
正确顺序是先 TERM,等几秒,再考虑 KILL:
kill 12345 # 默认发 TERMsleep 5kill -0 12345 2>/dev/null && kill -9 12345 # 还活着才补 KILLkill -9 的代价:事务没写完、锁没释放、临时文件残留。对数据库类进程尤其危险。kill -0 不真的发信号,只探测进程是否存在。
别用 killall 名字 或 pkill 模式 模糊批量杀,测试环境和生产环境混用的机器上很容易误伤。
别忘了 systemd 管的服务
如果进程是由 systemd 管理的服务,直接 kill 会被 Restart= 策略自动拉起来,越杀越多。正确入口:
systemctl status myapp # 看状态和最近日志sudo systemctl stop myapp # 停止journalctl -u myapp -n 100 # 看日志判断进程归谁管:systemctl status <PID> 直接传 PID 也行,会显示它属于哪个 unit。
一个完整的排查实例
症状:网站响应慢。
top发现 load 12(8 核),按1看 CPU 有空闲,但%wa高达 40%——瓶颈在 I/O。ps -eo pid,stat,args | awk '$2 ~ /D/'找到一批 D 状态的备份脚本进程。dmesg | tail看到磁盘 I/O error——是硬件/存储层问题,不是业务进程的问题。- 处置:通知存储运维,而不是 kill 业务进程。
工具只是入口,「先形成假设、再找证据」才是排障的核心。
延伸阅读
man 1 ps、man 1 top、man 7 signal- procps-ng 项目
- Brendan Gregg 的 Linux 性能分析资料
分享文章
生成精美分享图或复制链接,与更多人分享本文。
继续阅读
最后更新于 ,距今已过 41 天
部分内容可能已过时