4、服务端本地排查:检查服务进程状态、端口监听、服务端防火墙、iptables规则
好,我们继续往下走。前面几章我们把网络路径上的问题捋了一遍,从客户端一直追到了服务器门口。现在,门到了,该检查服务器自己了。
这一章,说白了就是四个字——本地排查。我见过太多人,客户端一报超时,立马怀疑网络、怀疑云厂商、怀疑中间链路,折腾半天,最后发现是服务器上的进程根本没起来。嗯,这种事我也干过,所以现在我的排查习惯,永远是先看本地。
核心思路:服务端本地排查,就是确认「服务在不在、端口开没开、防火墙放没放行」。这三步走完,90% 的本地问题都能定位。
4.1 检查服务进程状态
第一步,看看进程在不在。别笑,这步真不能省。
我个人习惯用 systemctl 或者 ps 来查。如果你用的是 systemd 管理的服务,直接:
systemctl status your-service-name
输出里会告诉你进程是 active (running) 还是挂了。如果是 inactive (dead) 或者 failed,那问题就简单了——服务没跑起来。
但有时候 systemctl 显示 running,实际进程却僵死了。怎么办?我建议再用 ps 确认一下:
ps aux | grep your-service-name
看看进程的 STAT 列。如果是 D(不可中断睡眠)或者 Z(僵尸进程),那服务虽然活着,但已经没法正常工作了。我在项目中遇到过 Nginx 进程变成僵尸态,客户端连接全部超时,排查了半天才发现是 worker 进程卡死在磁盘 I/O 上。
小技巧:用 ps -eo pid,stat,comm | grep -E "D|Z" 可以快速过滤出异常状态的进程。我每次上服务器第一件事就是跑这个命令。
4.2 检查端口监听状态
进程活着,不代表端口在监听。你想想看,服务启动时可能配置错了,监听的 IP 或端口不对,客户端自然连不上。
我最常用的命令是 ss,比 netstat 快很多:
ss -tlnp | grep :8080
参数解释一下:
-t:只看 TCP-l:只显示 LISTEN 状态的端口-n:不解析服务名,直接显示端口号-p:显示监听该端口的进程信息
输出大概长这样:
LISTEN 0 128 0.0.0.0:8080 0.0.0.0:* users:(("java",pid=12345,fd=13))
这里要注意几个关键点:
- 监听地址:
0.0.0.0:8080表示监听所有网卡,127.0.0.1:8080表示只监听本地回环。如果服务只绑了127.0.0.1,外部客户端肯定连不上。 - 进程 PID:确认这个 PID 和你刚才查的进程 ID 一致。
- 端口号:确认是客户端要连的那个端口。
避坑指南:我曾经排查过一个案例,服务进程正常,端口也 LISTEN,但客户端就是超时。最后发现服务绑的是 127.0.0.1,而客户端从公网 IP 访问。所以,一定要检查监听地址,别只看端口。
4.3 检查服务端防火墙
进程在跑,端口在监听,但客户端还是超时?那八成是防火墙拦了。
Linux 上常见的防火墙工具有 firewalld、ufw,还有最底层的 iptables。我们先说 firewalld,因为它现在用得最多。
检查 firewalld 状态:
systemctl status firewalld
firewall-cmd --state
如果防火墙是开启的,看看有没有放行你的服务端口:
firewall-cmd --list-all
输出里会列出 ports 和 services。如果没看到你的端口,那就需要添加规则:
firewall-cmd --add-port=8080/tcp --permanent
firewall-cmd --reload
如果是 ufw(Ubuntu 上常见),命令类似:
ufw status
ufw allow 8080/tcp
我的习惯:排查时我会先临时关闭防火墙测试一下,确认问题是否由防火墙引起。但生产环境千万别这么干——关防火墙等于裸奔。正确做法是加一条临时规则测试,测试完再持久化。
4.4 检查 iptables 规则
firewalld 和 ufw 其实都是 iptables 的前端封装。真正干活的是 iptables。所以,有时候 firewalld 显示规则加上了,但 iptables 层面可能还有冲突。
查看当前 iptables 规则:
iptables -L -n -v
这个命令会列出所有链(Chain)的规则。重点关注 INPUT 链,因为入站流量走这里。
输出示例:
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
0 0 DROP tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:8080
0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:22
看到没?第一条规则就把 8080 端口的流量 DROP 了。这就是客户端超时的原因。
如果规则太多,我习惯用 iptables -L INPUT -n --line-numbers 显示行号,方便定位和删除。
删除一条规则:
iptables -D INPUT 1
这里的 1 就是行号。
避坑指南:我曾经在排查一个线上问题时,发现 iptables 规则里有一条 REJECT 规则,但 firewalld 里完全看不到。原因是有人直接用了 iptables 命令加规则,绕过了 firewalld。所以,别只看 firewalld,iptables 也要查。
4.5 整体排查流程图
下面这张图总结了服务端本地排查的完整流程。你可以把它贴在工位上,每次排查照着走一遍。
4.6 常见问题速查表
最后,我整理了一张速查表。遇到超时问题,对着这张表查,能省不少时间。
| 现象 | 可能原因 | 排查命令 | 解决方案 |
|---|---|---|---|
| 进程不存在 | 服务未启动、进程崩溃 | systemctl status |
启动服务,检查日志 |
| 进程存在但端口未 LISTEN | 配置错误、端口被占用 | ss -tlnp |
检查配置文件,换端口 |
| 端口 LISTEN 但地址是 127.0.0.1 | 服务只绑定了本地回环 | ss -tlnp |
修改绑定地址为 0.0.0.0 |
| 防火墙未放行端口 | firewalld/ufw 规则缺失 | firewall-cmd --list-all |
添加放行规则 |
| iptables 有 DROP/REJECT 规则 | 手动添加的 iptables 规则 | iptables -L -n -v |
删除或修改对应规则 |
我的经验:这张表我打印出来贴在显示器边上。每次排查超时问题,先过一遍这五条,基本能解决 80% 的本地问题。剩下的 20%,要么是应用层逻辑问题,要么是内核参数调优——那些我们后面章节再聊。