跳转至

网络故障排查手册

网络故障排查手册

本章核心: 掌握系统化网络问题诊断方法,快速定位和解决各类网络故障


📖 章节导航

前序章节: 无(本章为工具参考) 后续章节: 无 快速参考: 网络工具箱.md 全部章节 配合使用: 00-网络知识全景图.md 快速诊断表


目录

  1. 诊断流程方法论
  2. 常见错误速查表
  3. 分层排查指南
  4. 实战排错案例
  5. 性能问题诊断

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