网络不通排查
问题
应用报错连不上某个服务(数据库/API/Redis),如何系统地排查网络问题?
答案
排查流程(由近到远)
Step 1:基础连通性
# 1. ping —— 检查 IP 层连通性
ping -c 3 10.0.1.100
# 注意:有些服务器禁 ping(ICMP),ping 不通不代表网络不通
# 2. telnet / nc —— 检查端口连通性
# 这步最关键!
telnet 10.0.1.100 3306
# 或
nc -zv 10.0.1.100 3306
# Connection to 10.0.1.100 3306 port [tcp/mysql] succeeded!
# 3. curl —— 检查 HTTP 层
curl -v http://10.0.1.100:8080/health
# 可以看到 DNS 解析、TCP 连接、HTTP 响应全过程
Step 2:DNS 排查
# 确认域名解析正确
nslookup db.example.com
dig db.example.com +short
# 常见 DNS 问题:
# 1. 解析到错误的 IP(DNS 缓存过期)
# 2. 解析失败(DNS 服务器不可达)
# 3. /etc/hosts 中有错误的硬编码
# 检查本机 DNS 配置
cat /etc/resolv.conf
# 绕过 DNS 直接测试
curl -H "Host: api.example.com" http://10.0.1.100:80/health
Step 3:路由排查
# traceroute —— 查看到目标的路由路径
traceroute 10.0.1.100
# 如果某一跳开始全是 * * *,说明该跳之后有问题
# mtr —— 持续追踪,能发现间歇性丢包
mtr -n 10.0.1.100
# 查看本机路由表
ip route show
# 确认到目标网段的路由存在且正确
Step 4:防火墙排查
# 查看本机防火墙规则
iptables -L -n -v
# 或 nftables
nft list ruleset
# 查看安全组(云环境)
# 确认入站规则允许该端口
# 临时关闭防火墙测试(仅用于排查,不要在生产长期关闭)
systemctl stop firewalld
# 查看目标端口是否在监听
# 在目标服务器上执行
ss -tlnp | grep 3306
# LISTEN 0 128 0.0.0.0:3306 0.0.0.0:* users:(("mysqld",pid=1234,fd=30))
Step 5:抓包分析
# 最终手段:tcpdump 抓包
# 在源端抓
tcpdump -i eth0 host 10.0.1.100 and port 3306 -nn
# 在目标端抓
tcpdump -i eth0 src host 10.0.2.50 and port 3306 -nn
# 观察:
# - 有 SYN 但没有 SYN-ACK → 目标端没收到或没回应
# - 有 SYN-ACK 但没有 ACK → 中间有设备阻断
# - 有 RST → 端口未监听或被防火墙拒绝
# 保存为文件用 Wireshark 分析
tcpdump -i eth0 host 10.0.1.100 -w /tmp/capture.pcap
快速排查清单
| 步骤 | 命令 | 排查内容 |
|---|---|---|
| 1 | nc -zv IP PORT | 端口连通性 |
| 2 | dig DOMAIN | DNS 解析 |
| 3 | traceroute IP | 路由路径 |
| 4 | iptables -L -n | 本机防火墙 |
| 5 | ss -tlnp (目标机) | 服务是否监听 |
| 6 | tcpdump | 抓包确认 |
常见面试问题
Q1: 应用连接数据库超时,如何排查?
答案:
按层次排查:
- 网络层:
nc -zv db-host 3306确认端口通 - DNS:
dig db-host确认解析正确 - 连接数:
SHOW PROCESSLIST查看数据库连接数是否满了 - 超时配置:检查应用的连接超时设置(connect_timeout)和数据库的
wait_timeout - 防火墙:安全组/iptables 是否放行了应用所在 IP
- 抓包:在应用侧和数据库侧同时抓包,看 TCP 三次握手是否完成