网络故障排查手册¶
本章核心: 掌握系统化网络问题诊断方法,快速定位和解决各类网络故障
📖 章节导航¶
前序章节: 无(本章为工具参考) 后续章节: 无 快速参考: 网络工具箱.md 全部章节 配合使用: 00-网络知识全景图.md 快速诊断表
目录¶
1. 诊断流程方法论¶
1.1 通用排查流程¶
Text Only
┌─────────────────────────────────────────────────────────────┐
│ 网络问题诊断流程 │
└─────────────────────────────────────────────────────────────┘
Step 1: 问题定义
↓
├─ 明确症状:完全不通?慢?间歇性?
├─ 影响范围:单机?全网?特定服务?
└─ 时间特征:持续?周期性?随机?
Step 2: 信息收集
↓
├─ 错误信息(截图/日志)
├─ 最近变更(配置/代码/部署)
├─ 网络拓扑图
└─ 监控数据(流量/延迟/丢包)
Step 3: 分层排查(自下而上)
↓
├─ 物理层:网线、接口、设备状态灯
├─ 数据链路层:MAC地址、ARP表、交换机
├─ 网络层:IP配置、路由表、防火墙
├─ 传输层:端口状态、TCP连接、拥塞
└─ 应用层:服务状态、DNS、配置
Step 4: 假设验证
↓
├─ 提出可能原因
├─ 设计验证实验
├─ 执行测试
└─ 确认/排除假设
Step 5: 问题解决
↓
├─ 实施修复
├─ 验证解决
├─ 记录根因
└─ 预防措施
1.2 快速决策树¶
Text Only
无法访问网站?
├─ 所有网站都不行?
│ ├─ 是 → 检查本地网络连接
│ │ ├─ ping 8.8.8.8 → 不通 → 检查网线/WiFi/路由器
│ │ └─ ping通 → 检查DNS → 更换DNS服务器
│ └─ 否 → 特定网站问题
│ ├─ ping域名 → 不通 → DNS问题
│ └─ ping通 → 检查防火墙/代理
└─ 只有特定应用不行?
├─ 检查应用配置(代理/端口)
└─ 检查防火墙规则
连接很慢?
├─ ping测试 → 高延迟/丢包 → 网络质量差
├─ traceroute → 定位慢在哪一跳
└─ 带宽测试 → 带宽不足
间歇性断连?
├─ 检查物理连接(网线松动/WiFi信号)
├─ 检查IP冲突
└─ 检查设备负载(CPU/内存/连接数)
2. 常见错误速查表¶
2.1 HTTP状态码¶
| 状态码 | 含义 | 常见原因 | 解决方案 |
|---|---|---|---|
| 2xx 成功 | |||
| 200 | OK | 正常 | - |
| 201 | Created | 资源创建成功 | - |
| 204 | No Content | 成功但无返回 | - |
| 3xx 重定向 | |||
| 301 | 永久重定向 | URL已变更 | 更新链接 |
| 302 | 临时重定向 | 临时跳转 | 跟随跳转 |
| 304 | 未修改 | 缓存有效 | - |
| 4xx 客户端错误 | |||
| 400 | 请求错误 | 参数错误/格式错误 | 检查请求体 |
| 401 | 未认证 | 缺少Token/认证失败 | 检查认证信息 |
| 403 | 禁止访问 | 权限不足 | 检查权限配置 |
| 404 | 未找到 | URL错误或资源不存在 | 检查URL |
| 408 | 请求超时 | 服务器处理超时 | 检查后端性能 |
| 429 | 请求过多 | 触发限流 | 降低请求频率 |
| 5xx 服务器错误 | |||
| 500 | 内部错误 | 服务器异常 | 查看服务器日志 |
| 502 | 网关错误 | 上游服务无响应 | 检查上游服务 |
| 503 | 服务不可用 | 服务过载/维护 | 检查服务状态 |
| 504 | 网关超时 | 上游响应超时 | 检查上游性能 |
2.2 SSH连接错误¶
| 错误信息 | 原因 | 解决方案 |
|---|---|---|
Connection refused | SSH服务未启动/端口错误 | sudo systemctl start sshd |
Connection timed out | 防火墙阻挡/网络不通 | 检查防火墙/安全组 |
Permission denied (publickey) | 密钥认证失败 | 检查密钥权限/authorized_keys |
Host key verification failed | 服务器指纹变化 | 删除~/.ssh/known_hosts对应行 |
Too many authentication failures | 尝试次数过多 | 检查SSH配置MaxAuthTries |
Port 22: No route to host | 网络不可达 | 检查IP/路由/网络连接 |
2.3 DNS错误¶
| 错误信息 | 原因 | 解决方案 |
|---|---|---|
NXDOMAIN | 域名不存在 | 检查域名拼写/是否过期 |
SERVFAIL | DNS服务器故障 | 更换DNS服务器 |
REFUSED | DNS服务器拒绝查询 | 检查DNS配置/防火墙 |
TIMEOUT | DNS查询超时 | 检查网络/更换DNS |
NOERROR但IP错误 | DNS劫持/缓存污染 | 刷新DNS缓存/使用DoH |
2.4 Docker网络错误¶
| 错误信息 | 原因 | 解决方案 |
|---|---|---|
network not found | 网络不存在 | docker network create |
port already allocated | 端口被占用 | netstat -tlnp找冲突 |
no such container | 容器名错误 | 检查容器名/ID |
container not running | 容器未启动 | docker start <container> |
driver failed | 网络驱动错误 | 重启Docker/检查驱动 |
3. 分层排查指南¶
3.1 物理层排查¶
Bash
# 1. 检查网络接口状态
ip link show
# 或
ifconfig -a
# 预期输出:
# eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500
# 关键标志:UP(启用)、LOWER_UP(物理连接正常)
# 2. 检查网线连接
ethtool eth0
# 预期输出:
# Link detected: yes
# Speed: 1000Mb/s
# Duplex: Full
# 3. 查看网卡统计(检查错误)
ifconfig eth0 | grep -E "(errors|dropped|overruns)"
# 或
ip -s link show eth0
# 关注:RX errors、RX dropped、TX errors 应该为0或很小
3.2 数据链路层排查¶
Bash
# 1. 检查ARP表
arp -a
# 或
ip neigh
# 2. 查看MAC地址
ip link show eth0
# 3. 检查VLAN配置
ip -d link show eth0.100
# 4. 交换机端口检查(如有权限)
# Cisco
show interfaces status
show mac address-table
# 常见问题:
# - MAC地址冲突
# - VLAN配置错误
# - STP阻塞端口
3.3 网络层排查¶
Bash
# 1. 检查IP配置
ip addr show
ip route show
# 2. 连通性测试
ping 8.8.8.8 # 测试外网连通
ping 192.168.1.1 # 测试网关
ping <同网段IP> # 测试局域网
# 3. 路由追踪
traceroute 8.8.8.8
# Windows: tracert 8.8.8.8
# 4. 检查防火墙
sudo iptables -L -n -v # Linux
netsh advfirewall show currentprofile # Windows
# 5. 检查NAT/端口转发
curl ifconfig.me # 查看公网IP
3.4 传输层排查¶
Bash
# 1. 查看端口监听
ss -tlnp
# 或
netstat -tlnp
# 2. 检查TCP连接状态
ss -tan | awk '{print $1}' | sort | uniq -c
# 3. 测试端口连通性
nc -zv 192.168.1.100 22 # netcat测试
telnet 192.168.1.100 22 # telnet测试
# 4. 抓包分析
sudo tcpdump -i eth0 port 80 -w capture.pcap
# 然后用Wireshark分析
# 5. 检查连接数限制
ulimit -n # 文件描述符限制
sysctl net.ipv4.tcp_max_syn_backlog # SYN队列
3.5 应用层排查¶
Bash
# 1. DNS解析测试
nslookup example.com
dig example.com
dig @8.8.8.8 example.com # 指定DNS服务器
# 2. HTTP测试
curl -I https://example.com
curl -v https://example.com # 详细输出
wget --server-response https://example.com
# 3. SSL/TLS检查
openssl s_client -connect example.com:443 -servername example.com
openssl x509 -in cert.pem -text -noout # 查看证书详情
# 4. 服务状态检查
systemctl status nginx
journalctl -u nginx -f # 实时日志
# 5. 应用日志分析
tail -f /var/log/nginx/error.log
grep "ERROR" /var/log/app.log
4. 实战排错案例¶
案例1:网站间歇性无法访问¶
症状: 公司网站每天下午3-5点访问缓慢,偶尔完全打不开
排查过程:
Bash
# Step 1: 确认问题时间规律
# 查看监控发现每天固定时段CPU飙升
# Step 2: 检查服务器资源
top -bn1 | head -20
# 发现MySQL进程CPU占用90%+
# Step 3: 查看慢查询日志
mysql -e "SHOW FULL PROCESSLIST;"
# 发现有大量慢查询堆积
# Step 4: 分析慢查询
pt-query-digest /var/log/mysql/slow.log
# 发现某个统计查询没有索引
# Step 5: 检查连接数
netstat -an | grep :3306 | wc -l
# 连接数达到max_connections上限
根因: 下午业务高峰期,统计报表任务触发大量慢查询,导致MySQL连接池耗尽
解决方案: 1. 优化慢查询,添加索引 2. 调整报表任务到夜间执行 3. 增加连接池大小 4. 添加数据库读写分离
案例2:SSH突然连接不上¶
症状: 服务器突然无法SSH连接,但ping通
排查过程:
Bash
# Step 1: 本地测试
ssh -v user@server # 详细模式查看卡在哪一步
# 发现卡在"debug1: expecting SSH2_MSG_KEX_ECDH_REPLY"
# Step 2: 通过VNC/控制台登录服务器
# 检查SSH服务状态
systemctl status sshd
# 服务正常运行
# Step 3: 检查端口监听
ss -tlnp | grep 22
# 发现监听在127.0.0.1:22,不是0.0.0.0:22
# Step 4: 检查配置文件
grep ListenAddress /etc/ssh/sshd_config
# 发现 ListenAddress 127.0.0.1
根因: 同事修改SSH配置时误将ListenAddress设为127.0.0.1,导致只监听本地
解决方案:
Bash
# 修改配置
sed -i 's/ListenAddress 127.0.0.1/#ListenAddress 127.0.0.1/' /etc/ssh/sshd_config # sed流编辑器:文本替换与转换
systemctl restart sshd
案例3:Docker容器无法访问外网¶
症状: 容器内无法ping通外网,宿主机正常
排查过程:
Bash
# Step 1: 检查容器网络模式
docker inspect <container> | grep -A 10 NetworkMode
# 默认bridge模式
# Step 2: 检查docker0网桥
ip addr show docker0
# 网桥正常
# Step 3: 检查IP转发
sysctl net.ipv4.ip_forward
# 返回0,IP转发被禁用!
# Step 4: 检查iptables规则
sudo iptables -t nat -L -n -v | grep MASQUERADE
# 发现MASQUERADE规则缺失
# Step 5: 检查DNS配置
cat /etc/resolv.conf
# 发现nameserver是127.0.0.53,容器无法访问
根因: 1. IP转发被意外关闭 2. Docker的iptables规则被其他程序清空 3. 容器使用宿主机的本地DNS
解决方案:
Bash
# 开启IP转发
echo 1 > /proc/sys/net/ipv4/ip_forward
echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
# 重启Docker服务重建iptables规则
systemctl restart docker
# 配置Docker使用公共DNS
cat > /etc/docker/daemon.json <<EOF
{
"dns": ["8.8.8.8", "8.8.4.4"]
}
EOF
systemctl restart docker
案例4:API响应时快时慢¶
症状: 微服务API响应时间不稳定,200ms-5s波动
排查过程:
Bash
# Step 1: 应用层日志分析
# 发现慢请求都集中在访问user-service
# Step 2: 检查user-service连接池
netstat -an | grep :8080 | grep ESTABLISHED | wc -l # grep文本搜索:按模式匹配行
# 连接数达到上限
# Step 3: 检查连接池配置
# 发现连接池大小设置为50,但并发请求峰值200+
# Step 4: 检查TCP连接状态
ss -tan | grep :8080 | awk '{print $1}' | sort | uniq -c
# 大量TIME_WAIT状态
# Step 5: 抓包分析
sudo tcpdump -i any host user-service -w slow.pcap
# 分析发现连接建立耗时过长
根因: 1. 连接池大小不足,请求排队等待 2. 连接未及时复用,频繁创建销毁 3. DNS解析偶尔超时
解决方案:
Python
# 优化HTTP连接池配置
import requests
from requests.adapters import HTTPAdapter
session = requests.Session()
adapter = HTTPAdapter(
pool_connections=100,
pool_maxsize=200,
max_retries=3
)
session.mount('http://', adapter)
session.mount('https://', adapter)
# 使用连接超时和读取超时分离
response = session.get(
url,
timeout=(3, 27) # (连接超时, 读取超时)
)
5. 性能问题诊断¶
5.1 网络延迟诊断¶
Bash
# 1. 测量各环节延迟
# DNS解析时间
time dig +short example.com
# TCP连接时间
time nc -z -w2 example.com 443
# TLS握手时间
time openssl s_client -connect example.com:443 </dev/null
# 首字节时间(TTFB)
curl -o /dev/null -w "TTFB: %{time_starttransfer}\n" https://example.com
# 总下载时间
curl -o /dev/null -w "Total: %{time_total}\n" https://example.com
# 2. 使用mtr持续监测
mtr --report --report-cycles 100 example.com
# 3. 带宽测试
# 安装speedtest-cli
pip install speedtest-cli
speedtest-cli
# iperf3测试内网带宽
# 服务端:iperf3 -s
# 客户端:iperf3 -c <server_ip>
5.2 带宽瓶颈定位¶
Bash
# 1. 实时带宽监控
iftop -i eth0
nload eth0
# 2. 按连接统计流量
sudo tcpdump -i eth0 -nn -q 2>/dev/null | awk '{print $3}' | cut -d. -f1-4 | sort | uniq -c | sort -rn | head
# 3. 进程流量统计
sudo nethogs eth0
# 4. 历史流量(如有监控)
# sar -n DEV 1 10
5.3 连接数问题¶
Bash
# 1. 查看当前连接数统计
ss -tan | awk '{print $1}' | sort | uniq -c | sort -rn
# 2. 查看TIME_WAIT数量(过高会耗尽端口)
ss -tan state time-wait | wc -l
# 3. 查看端口使用范围
cat /proc/sys/net/ipv4/ip_local_port_range
# 4. 优化TIME_WAIT
# 编辑 /etc/sysctl.conf
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 0 # 已废弃,勿用
net.ipv4.tcp_fin_timeout = 30
sysctl -p
附录:一键诊断脚本¶
Bash
#!/bin/bash
# network_diagnose.sh - 网络一键诊断脚本
echo "========== 网络诊断报告 =========="
echo "生成时间: $(date)"
echo ""
echo "【1. 基本网络信息】"
echo "主机名: $(hostname)"
echo "公网IP: $(curl -s ifconfig.me)"
echo ""
echo "【2. 网络接口状态】"
ip addr show | grep -E "(inet|UP|DOWN)" # |管道:将前一命令的输出作为后一命令的输入
echo ""
echo "【3. 路由表】"
ip route show
echo ""
echo "【4. DNS配置】"
cat /etc/resolv.conf
echo ""
echo "【5. 连通性测试】"
echo "测试网关..."
ping -c 3 $(ip route | grep default | awk '{print $3}') | tail -2 # $()命令替换:执行命令并获取输出
echo "测试外网..."
ping -c 3 8.8.8.8 | tail -2
echo "测试DNS..."
ping -c 3 baidu.com | tail -2
echo ""
echo "【6. 监听端口】"
ss -tlnp | head -20
echo ""
echo "【7. 连接统计】"
ss -tan | awk '{print $1}' | sort | uniq -c | sort -rn # awk文本处理:按列提取和格式化数据
echo ""
echo "【8. 防火墙状态】"
sudo iptables -L -n | head -10
echo ""
echo "========== 诊断完成 =========="
总结¶
排查 checklist¶
- 确认问题范围和影响面
- 收集错误信息和日志
- 从物理层开始逐层排查
- 使用合适的工具验证假设
- 记录解决过程和根因
- 实施预防措施避免复发
常用工具速查¶
| 用途 | Linux | Windows |
|---|---|---|
| 连通性 | ping | ping |
| 路由追踪 | traceroute | tracert |
| 端口检查 | ss/netstat | netstat |
| 抓包 | tcpdump | Wireshark |
| DNS查询 | dig/nslookup | nslookup |
| 带宽测试 | iperf3 | iperf3 |
| 流量监控 | iftop/nload | Resource Monitor |