Linux 进程管理与端口排查:ps、top、ss 实战指南
在 Linux 服务器运维中,进程与端口是最常打交道的两个对象:服务起不来,先看进程在不在;端口访问不通,先看端口有没有监听。ps、top、ss 三个命令覆盖了从静态快照、动态监控到网络连接的完整排查链路,熟练组合使用,能解决日常工作中九成以上的进程与端口问题。
一、先理清概念:进程、线程与端口
进程是操作系统分配资源的基本单位,每个进程有唯一的 PID;线程是进程内的执行单元,共享进程的内存空间;端口则是应用层与传输层之间的通信端点,0-65535 号端口中,0-1023 为系统保留端口,普通用户进程一般使用 1024 以上端口。
理解这个分层关系非常重要:进程不等于端口,一个进程可以监听多个端口,一个端口同一时刻通常只能被一个进程监听。排查时先确认进程是否存在,再确认端口是否监听,最后确认网络是否可达,层层递进才不会走弯路。
二、ps:给进程拍一张快照
ps 输出的是命令执行那一刻的进程状态,是最常用的静态排查工具。
ps aux | grep nginx
ps -ef | grep java
ps aux --sort=-%cpu | head -n 15
ps -o pid,ppid,%cpu,%mem,cmd -p 1234
ps aux 的列含义值得记牢:USER 是启动用户,%CPU 与 %MEM 是资源占用,VSZ、RSS 分别是虚拟内存与常驻内存,STAT 是进程状态,R 表示运行,S 表示睡眠,D 表示不可中断睡眠,Z 表示僵尸,T 表示停止。看到大量 D 状态进程,往往意味着磁盘 I/O 出现瓶颈;看到 Z 状态,则要检查父进程是否及时回收了子进程。
结合 grep 使用时要注意,grep 自身也会出现在结果里,常用技巧是写成 grep [n]ginx,或者加上 grep -v grep 过滤掉自身。
三、top:实时观察系统负载
如果说 ps 是照片,top 就是录像。默认每 3 秒刷新一次,首屏几行最关键:load average 三个数字分别代表 1 分钟、5 分钟、15 分钟的平均负载,持续超过 CPU 核数就说明系统过载;Tasks 行统计进程总数与各状态数量;%Cpu(s) 行中,us 是用户态占比,sy 是内核态占比,wa 是 I/O 等待占比,id 是空闲占比。
常用的交互键:按大写 P 按 CPU 占用排序,按大写 M 按内存占用排序,按数字 1 展开每个 CPU 核的使用情况,按 k 可以直接杀掉某个进程,按 q 退出。配合 -b -n 1 还能把一次快照输出到文件,便于事后分析:
top -b -n 1 | head -n 20
top -H -p 1234
其中 -H 可以查看进程内的线程,当某个 Java 进程 CPU 很高却不知道是哪个线程引起时,top -H 能快速定位到线程级别。
四、ss:端口与连接的真相
ss 是 netstat 的继任者,速度更快、信息更全。
ss -tlnp
ss -tlnp | grep 8080
ss -tnp | grep ESTAB
ss -s
ss -tn state time-wait | wc -l
-t 表示 TCP,-l 只显示监听端口,-n 不解析服务名,-p 显示占用端口的进程。ss -tlnp 是日常最常用的一条命令,一眼就能看出哪些端口在监听、被哪个进程占用。
常见连接状态要会读:LISTEN 表示等待连接,ESTAB 表示已建立连接,TIME-WAIT 是主动关闭方等待残余报文的状态,数量过多可能耗尽端口,需要关注;CLOSE-WAIT 则表示对方已关闭、本地应用却没有及时关闭连接,往往是应用代码存在连接泄漏。
五、实战:端口被占用的排查流程
启动服务时最常见报错是 Address already in use。标准排查流程如下:
# 1. 看是谁占了端口
ss -tlnp | grep 8080
# 2. 看进程详情,确认它是什么服务
ps -ef | grep 1234
# 3. 需要释放时,先优雅停止
kill 1234
# 4. 若无响应,再强制终止
kill -9 1234
这里有两点经验。第一,先确认占用端口的进程是不是自己需要的服务,贸然 kill 可能误杀其他业务。第二,kill 默认发送 SIGTERM,给进程留出清理资源的时间;只有进程无响应时才用 SIGKILL,也就是 kill -9,因为它不会给进程任何清理机会。
六、实战:CPU 飙高的进程定位
当服务器负载突然升高,可以按下面的顺序定位:
# 1. top 确认是哪个进程占用高
top
# 2. 展开线程,找到占用最高的线程
top -H -p 1234
# 3. 线程号转十六进制
printf "%x\n" 5678
# 4. 结合 jstack 等工具看线程栈(以 Java 为例)
jstack 1234 | grep -A 20 "nid=0x162e"
对于非 Java 进程,可以用 perf 或 strace 进一步追踪系统调用。记住,定位问题要从整体到局部:先确认是 CPU、内存还是 I/O 导致,再定位到进程、线程,最后结合应用日志确认根因。
七、僵尸进程与信号
僵尸进程,也就是 Z 状态的进程,已经结束执行,但父进程还没有调用 wait 回收它的退出状态。它本身不占内存,只占用进程表项,真正需要处理的是没有回收它的父进程:找到父进程的 PPID,修复父进程的回收逻辑,或者重启父进程,僵尸进程便会自动消失。
信号是进程间最简单的通信方式,常用的有:SIGTERM(15,默认的 kill 信号,请求终止)、SIGKILL(9,强制终止,无法捕获)、SIGINT(2,Ctrl+C)、SIGHUP(1,终端挂断,常用于让守护进程重载配置)。日常管理进程,优先使用系统自带的 systemctl 或 service 命令,它们比直接 kill 更规范,也能正确处理依赖和重启策略。
八、排查速查表
| 场景 | 首选命令 |
|---|---|
| 查某个服务在不在 | ps -ef | grep 服务名 |
| 查 CPU、内存占用前十 | ps aux --sort=-%cpu | head |
| 实时监控负载 | top,按 P 或 M 排序 |
| 查端口被谁占用 | ss -tlnp | grep 端口 |
| 统计当前连接数 | ss -tn | wc -l |
| 查某个进程的线程 | top -H -p PID |
| 优雅停止进程 | kill PID |
| 强制终止进程 | kill -9 PID |
结语
进程管理与端口排查没有捷径,靠的就是对 ps、top、ss 三个工具的熟练组合:ps 负责静态快照,top 负责动态监控,ss 负责网络连接。遇到问题时,先看进程,再看端口,最后看网络,一步步缩小范围,大多数故障都能在几分钟内定位。建议把本文的命令收藏起来,下次线上出问题时按流程逐项排查。
- 点赞
- 收藏
- 关注作者
评论(0)