Linux 网络丢包故障排查实战

一、故障现象

网络丢包是生产环境中常见的网络问题,典型表现包括:

  • 应用请求超时或响应缓慢
  • TCP 连接频繁重传
  • 视频/语音通话卡顿
  • 文件传输速度不稳定
  • ping 测试出现 Request timeout 或高延迟

二、初步诊断

2.1 使用 ping 测试基础连通性

1
2
3
4
5
6
7
8
# 持续 ping 测试,观察丢包率
ping -c 100 目标 IP

# 大包测试(检测 MTU 问题)
ping -s 1472 -c 10 目标 IP

# 带时间戳的 ping(分析延迟波动)
ping -D 目标 IP

结果分析:

  • 丢包率 < 1%:正常
  • 丢包率 1%-5%:需要关注
  • 丢包率 > 5%:严重问题,需立即排查

2.2 使用 mtr 定位丢包位置

1
2
3
4
5
6
# 安装 mtr
apt install mtr -y # Debian/Ubuntu
yum install mtr -y # CentOS/RHEL

# 路由追踪 + 丢包统计
mtr -rwnc 100 目标 IP

输出解读:

1
2
3
4
Host                    Loss%   Snt   Last   Avg  Best  Wrst StDev
1. 192.168.1.1 0.0% 100 1.2 1.5 0.8 5.2 0.6
2. 10.0.0.1 15.0% 100 5.8 8.2 2.1 45.3 12.1 ← 问题节点
3. 目标 IP 0.0% 100 10.2 12.1 8.5 25.6 5.4

关键判断:

  • 中间节点丢包:运营商或网络设备问题
  • 最后一跳丢包:目标服务器或防火墙问题
  • 全程丢包:本地网络配置问题

三、本地网络排查

3.1 检查网卡状态与错误计数

1
2
3
4
5
6
7
8
# 查看网卡详细统计
ethtool -S eth0

# 查看网卡错误包
ip -s link show eth0

# 查看网卡驱动信息
ethtool -i eth0

关键指标:

  • rx_dropped:接收丢弃包数(持续增加说明有问题)
  • tx_dropped:发送丢弃包数
  • rx_errors:接收错误包数
  • tx_errors:发送错误包数
  • collisions:冲突数(全双工网络应为 0)

3.2 检查网卡 Ring Buffer

1
2
3
4
5
6
7
# 查看当前 Ring Buffer 设置
ethtool -g eth0

# 临时调大 Ring Buffer(重启失效)
ethtool -G eth0 rx 4096 tx 4096

# 永久生效:写入 /etc/network/interfaces 或 systemd-networkd 配置

适用场景: 高并发场景下 rx_dropped 持续增长

3.3 检查网络中断平衡

1
2
3
4
5
6
7
8
# 查看网卡中断分布
cat /proc/interrupts | grep eth0

# 查看中断亲和性
cat /proc/irq/$(cat /proc/interrupts | grep eth0 | awk -F: '{print $1}' | head -1)/smp_affinity_list

# 优化中断亲和性(将中断绑定到特定 CPU)
echo 2 > /proc/irq/IRQ_NUMBER/smp_affinity

3.4 检查 TCP 连接状态

1
2
3
4
5
6
7
8
# 查看 TCP 连接统计
netstat -s | grep -i "segments"

# 查看重传统计
netstat -s | grep -i "retrans"

# 实时监控连接状态
watch -n 1 'netstat -ant | awk '\''{print $6}'\'' | sort | uniq -c'

关键指标:

  • segments retransmitted:重传包数(持续增长说明网络问题)
  • connection resets received:连接重置数

四、内核参数排查

4.1 检查网络缓冲区

1
2
3
4
5
6
7
8
9
10
11
# 查看当前网络缓冲区设置
sysctl -a | grep -E "net.core.(rmem|wmem)"
sysctl -a | grep -E "net.ipv4.tcp_(rmem|wmem)"

# 临时调大缓冲区
sysctl -w net.core.rmem_max=16777216
sysctl -w net.core.wmem_max=16777216
sysctl -w net.ipv4.tcp_rmem="4096 87380 16777216"
sysctl -w net.ipv4.tcp_wmem="4096 65536 16777216"

# 永久生效:写入 /etc/sysctl.conf

4.2 检查连接跟踪表

1
2
3
4
5
6
7
8
9
10
# 查看连接跟踪表使用情况
cat /proc/net/nf_conntrack | wc -l
cat /proc/sys/net/netfilter/nf_conntrack_count
cat /proc/sys/net/netfilter/nf_conntrack_max

# 如果接近上限,调大
sysctl -w net.netfilter.nf_conntrack_max=262144

# 永久生效
echo "net.netfilter.nf_conntrack_max=262144" >> /etc/sysctl.conf

4.3 检查 TCP 参数

1
2
3
4
5
6
7
8
# 查看 TCP 相关参数
sysctl -a | grep -E "net.ipv4.tcp_(fin|keepalive|tw)"

# 优化 TCP 参数
sysctl -w net.ipv4.tcp_fin_timeout=30
sysctl -w net.ipv4.tcp_keepalive_time=600
sysctl -w net.ipv4.tcp_tw_reuse=1
sysctl -w net.ipv4.tcp_max_syn_backlog=8192

五、防火墙与安全组排查

5.1 检查 iptables/nftables 规则

1
2
3
4
5
6
7
8
9
# 查看 iptables 规则及计数
iptables -L -n -v

# 查看 nftables 规则
nft list ruleset

# 临时关闭防火墙测试(生产环境慎用)
systemctl stop iptables
systemctl stop firewalld

5.2 检查云服务商安全组

  • 阿里云:控制台 → 云服务器 ECS → 安全组
  • 腾讯云:控制台 → 云服务器 → 安全组
  • AWS:EC2 → Security Groups
  • 华为云:控制台 → 弹性云服务器 → 安全组

检查要点:

  • 入站规则是否允许目标端口
  • 出站规则是否有限制
  • 是否有 IP 白名单限制

六、应用层排查

6.1 使用 tcpdump 抓包分析

1
2
3
4
5
6
7
8
9
10
11
12
# 抓取指定端口的包
tcpdump -i eth0 port 80 -w capture.pcap

# 抓取特定 IP 的包
tcpdump -i eth0 host 192.168.1.100 -w capture.pcap

# 实时分析(不保存)
tcpdump -i eth0 -n port 80

# 过滤特定标志位
tcpdump -i eth0 'tcp[tcpflags] & (tcp-rst) != 0' # RST 包
tcpdump -i eth0 'tcp[tcpflags] & (tcp-syn) != 0' # SYN 包

6.2 使用 Wireshark 分析

1
2
3
4
5
6
7
# 将抓包文件传输到本地分析
scp root@server:/root/capture.pcap ./

# Wireshark 过滤表达式
tcp.analysis.retransmission # 重传包
tcp.analysis.window_full # 窗口满
tcp.flags.reset == 1 # RST 标志

6.3 检查应用日志

1
2
3
4
5
# Nginx 错误日志
tail -f /var/log/nginx/error.log | grep -i "timeout\|error"

# 应用日志中的网络错误
journalctl -u 服务名 -f | grep -i "connection\|timeout"

七、常见丢包场景与解决方案

7.1 场景一:高并发下 rx_dropped 增长

原因: 网卡 Ring Buffer 或内核接收缓冲区不足

解决方案:

1
2
3
4
5
6
# 调大 Ring Buffer
ethtool -G eth0 rx 4096 tx 4096

# 调大内核接收缓冲区
sysctl -w net.core.rmem_max=16777216
sysctl -w net.core.netdev_max_backlog=5000

7.2 场景二:TCP 重传率高

原因: 网络拥塞、MTU 问题、或对端处理能力不足

解决方案:

1
2
3
4
5
6
7
8
# 启用 TCP BBR 拥塞控制
sysctl -w net.core.default_qdisc=fq
sysctl -w net.ipv4.tcp_congestion_control=bbr

# 检查 MTU
ip link show eth0 | grep mtu
# 如有问题,调整 MTU
ip link set eth0 mtu 1400

7.3 场景三:连接跟踪表满

原因: 大量短连接导致 nf_conntrack 表满

解决方案:

1
2
3
4
5
6
# 调大连接跟踪表
sysctl -w net.netfilter.nf_conntrack_max=262144

# 缩短超时时间
sysctl -w net.netfilter.nf_conntrack_tcp_timeout_established=432000
sysctl -w net.netfilter.nf_conntrack_tcp_timeout_time_wait=30

7.4 场景四:云服务器内网丢包

原因: 实例规格带宽限制、安全组配置、或宿主机问题

解决方案:

  1. 检查实例带宽限制
  2. 验证安全组规则
  3. 联系云服务商排查宿主机
  4. 考虑升级实例规格

八、排查流程总结

1
2
3
4
5
6
7
8
9
10
11
12
13
1. ping 测试 → 确认丢包存在

2. mtr 追踪 → 定位丢包位置

3. 本地检查 → ethtool/ip -s 查看错误计数

4. 内核参数 → 检查缓冲区和连接跟踪

5. 防火墙 → 检查 iptables/安全组

6. 抓包分析 → tcpdump/Wireshark 深入分析

7. 应用日志 → 检查应用层错误

九、监控与预警

9.1 Prometheus 监控指标

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# node_exporter 网络指标
node_network_receive_drop_total
node_network_transmit_drop_total
node_network_receive_errs_total
node_network_transmit_errs_total

# 告警规则示例
- alert: NetworkPacketDrop
expr: rate(node_network_receive_drop_total[5m]) > 100
for: 5m
labels:
severity: warning
annotations:
summary: "网络丢包告警"
description: "{{ $labels.instance }} 接收丢包率过高"

9.2 定期健康检查脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#!/bin/bash
# network-health-check.sh

INTERFACE="eth0"
THRESHOLD=100

RX_DROPPED=$(ip -s link show $INTERFACE | awk '/RX:/{getline; print $3}')
TX_DROPPED=$(ip -s link show $INTERFACE | awk '/TX:/{getline; print $3}')

if [ "$RX_DROPPED" -gt "$THRESHOLD" ] || [ "$TX_DROPPED" -gt "$THRESHOLD" ]; then
echo "WARNING: Network drop detected on $INTERFACE"
echo "RX Dropped: $RX_DROPPED, TX Dropped: $TX_DROPPED"
exit 1
fi

echo "OK: Network health check passed"
exit 0

十、参考资料


文档版本: v1.0
最后更新: 2026-03-19
适用系统: Linux (CentOS/Ubuntu/Debian)