进程与端口排查
在 Unix 系统中,"一切皆文件",网络连接也被视为一种打开的文件。排查进程和端口占用是日常运维的基础操作。
核心流程
端口被占用 → lsof 找到进程 → ps 确认详情 → kill 结束进程lsof:列出打开的文件
lsof(List Open Files)是 Linux/macOS 上专门查看打开文件的命令。加上 -i 参数后,可以专门筛选网络相关的文件(即网络连接)。
基本语法
bash
lsof -i [协议]@[主机]:[端口]常用场景
1. 查看谁占用了某个端口
bash
lsof -i :8080输出示例:
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
node 18653 alice 21u IPv4 0x1234 0t0 TCP *:http-alt (LISTEN)关键字段:
COMMAND:进程名称PID:进程 ID(kill 时用)USER:运行用户FD:文件描述符(21u 表示第 21 个文件,u 表示 update 模式)TYPE:IPv4/IPv6NAME:连接状态(LISTEN、ESTABLISHED 等)
2. 查看所有网络连接
bash
lsof -i2.1 查看所有被占用的端口
最常用的组合命令:
bash
lsof -i -P -n | grep LISTEN| 选项 | 全称 | 含义 |
|---|---|---|
-i | internet | 只看网络连接(TCP/UDP) |
-P | Port(数字) | 显示端口号而非服务名(8080 而非 http-alt) |
-n | numeric | 显示 IP 而非主机名(更快,不做 DNS 反查) |
grep LISTEN | — | 只筛选处于监听状态的连接 |
输出示例:
nginx 1551 root 6u IPv4 0x1234 0t0 TCP *:80 (LISTEN)
mysqld 3306 mysql 21u IPv6 0x5678 0t0 TCP *:3306 (LISTEN)
node 8080 www 18u IPv4 0x9abc 0t0 TCP *:8080 (LISTEN)
lsof在 macOS 和 Linux 上都有。
2.2 ss:Linux 上的替代方案
ss(socket statistics,套接字统计)是 netstat 的现代替代品,Linux 专属:
bash
ss -tlnp| 选项 | 含义 |
|---|---|
-t | TCP |
-l | 只显示 listening |
-n | 显示数字端口 |
-p | 显示对应进程名 |
ss 比 lsof / netstat 快得多,因为它通过内核 netlink 接口直接读数据,不用逐条解析 /proc。
macOS 没有
ss,用lsof -i -P -n | grep LISTEN代替。Linux 上如果ss找不到,需要安装iproute2:sudo apt install iproute2。
3. 只看 TCP 或 UDP
bash
lsof -i tcp
lsof -i udp4. 查看某用户的网络连接
bash
lsof -i -u alice5. 查看某进程打开的所有文件
bash
lsof -p 18653ps:查看进程状态
ps(Process Status)用于查看当前运行的进程。
常用命令
bash
# 查看所有进程(完整信息)
ps aux
# 查看所有进程(树形结构)
ps auxf
# 按 CPU 使用率排序
ps aux --sort=-%cpu | head -10
# 按内存使用排序
ps aux --sort=-%mem | head -10
# 只看某用户的进程
ps aux | grep alice
# 查看某端口的进程(配合 grep)
ps aux | grep 18653
# 查看某进程的详细信息
ps -p 18653 -o pid,user,start,time,cmdps 输出字段
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
alice 18653 0.5 2.1 512345 43210 ? Ssl 10:00 0:05 node server.jsUSER:运行用户PID:进程 ID%CPU:CPU 使用率%MEM:内存使用率VSZ:虚拟内存(KB)RSS:物理内存(KB)STAT:进程状态(S=睡眠,R=运行,Z=僵尸,T=停止)START:启动时间TIME:累计 CPU 时间COMMAND:命令与参数
kill:结束进程
kill 向进程发送信号,常用信号:
| 信号 | 编号 | 含义 |
|---|---|---|
SIGTERM | 15 | 请求终止(默认),进程可以清理资源 |
SIGKILL | 9 | 强制终止,进程无法拦截 |
SIGHUP | 1 | 重新加载配置 |
基本用法
bash
# 请求进程优雅退出
kill 18653
# 强制杀死进程
kill -9 18653
# 重新加载配置(不重启)
kill -HUP 18653实战:端口占用排查流程
场景:启动服务时提示 "Port 8080 already in use"
Step 1:找到占用端口的进程
bash
lsof -i :8080输出:
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
node 18653 alice 21u IPv4 0x1234 0t0 TCP *:http-alt (LISTEN)Step 2:确认是否是应该运行的实例
bash
ps -p 18653 -o pid,user,start,time,cmd输出:
PID USER STARTED TIME COMMAND
18653 alice 10:00:00 00:05:23 node server.jsStep 3:决定处理方式
- 如果是旧实例 → kill 掉,重新启动
- 如果是正确实例 → 换个端口启动新服务
bash
# 优雅终止
kill 18653
# 等 2 秒检查是否还在
sleep 2 && lsof -i :8080
# 如果还在,强制杀死
kill -9 18653Step 4:验证端口已释放
bash
lsof -i :8080
# 无输出说明端口已释放场景:两个进程争用同一端口
有时会有多个进程监听同一端口,需要逐个确认:
bash
# 1. 查看所有占用该端口的进程
lsof -i :18789
bash
# 2. 逐个检查每个 PID 的启动命令
ps -p 18653 -o pid,user,start,time,cmd
ps -p 18654 -o pid,user,start,time,cmd
# 3. 杀死不需要的实例
kill 18653
# 4. 验证只剩一个
lsof -i :18789top:实时监控进程
top 提供实时的系统资源监控。
bash
# 启动 top
top
# 常用交互键(在 top 运行中)
# P - 按 CPU 使用率排序
# M - 按内存使用排序
# k - 输入 PID 杀死进程
# q - 退出
# 只看某用户的进程
top -u alice
# 一次性快照(不进入交互模式)
top -b -n 1 | head -20常见问题
Q:kill 后进程还在?
某些进程会捕获 SIGTERM 并忽略,改用 SIGKILL:
bash
kill -9 <PID>如果 -9 还不行,可能是僵尸进程(状态为 Z),需要 kill 父进程:
bash
# 找父进程
ps -o ppid= -p <僵尸PID>
# 杀死父进程
kill <父进程PID>Q:如何找到所有监听端口的进程?
bash
# macOS / Linux 通用(推荐)
lsof -i -P -n | grep LISTEN
# Linux 专属(更快)
ss -tlnpQ:进程占用内存过高怎么排查?
bash
# 按内存排序查看
ps aux --sort=-%mem | head -10
# 或使用 top 交互模式按 M 键
top
# 然后按 M相关资源
- Linux 实用指南 - 更多 Linux 场景文章
- DNS 与代理 - 网络相关排查
- 技术教程 - 服务器部署与运维