前言
服务响应慢、接口超时、用户反馈卡顿,很多时候问题出在网络层面。延迟高、丢包、抖动这些问题看起来简单,排查起来却需要一套系统的方法。
本文整理网络延迟和丢包问题的排查思路和常用工具,配合实际案例。
1. 基础检测工具
1.1 ping:最简单的延迟检测
bash
# 基础用法
ping 192.168.1.100
# 指定次数
ping -c 10 192.168.1.100
# 指定间隔(秒)
ping -i 0.2 192.168.1.100
# 指定包大小(测试MTU问题)
ping -s 1400 192.168.1.100
# 不允许分片(检测MTU)
ping -M do -s 1472 192.168.1.100
关注指标:
lua
64 bytes from 192.168.1.100: icmp_seq=1 ttl=64 time=0.5 ms
--- 192.168.1.100 ping statistics ---
10 packets transmitted, 10 received, 0% packet loss, time 9000ms
rtt min/avg/max/mdev = 0.4/0.6/1.2/0.2 ms
time:单次往返延迟(RTT)packet loss:丢包率mdev:延迟标准差,反映抖动
1.2 traceroute:定位延迟在哪一跳
bash
# 基础用法
traceroute 8.8.8.8
# 使用ICMP(默认用UDP)
traceroute -I 8.8.8.8
# 使用TCP(绕过某些防火墙)
traceroute -T -p 80 8.8.8.8
# 显示AS号(定位运营商)
traceroute -A 8.8.8.8
输出解读:
scss
1 192.168.1.1 (192.168.1.1) 1.234 ms 1.123 ms 1.345 ms
2 10.0.0.1 (10.0.0.1) 5.678 ms 5.432 ms 5.876 ms
3 * * *
4 202.97.33.1 (202.97.33.1) 20.123 ms 19.876 ms 20.345 ms
- 每行三个时间是三次探测的RTT
* * *表示该跳没有响应(可能禁ping,不一定有问题)- 关注延迟突然增大的位置
1.3 mtr:ping + traceroute的结合
bash
# 交互模式
mtr 8.8.8.8
# 报告模式
mtr -r -c 100 8.8.8.8
# 显示更多信息
mtr -r -c 100 -w 8.8.8.8
输出解读:
sql
HOST: server Loss% Snt Last Avg Best Wrst StDev
1.|-- 192.168.1.1 0.0% 100 0.5 0.6 0.4 1.2 0.1
2.|-- 10.0.0.1 0.0% 100 5.2 5.4 5.0 6.8 0.3
3.|-- 202.97.33.1 2.0% 100 20.1 21.3 19.5 45.6 5.2
4.|-- 72.14.216.1 0.0% 100 35.2 36.1 34.8 42.3 1.5
5.|-- 8.8.8.8 0.0% 100 38.5 39.2 38.0 48.6 2.1
Loss%:丢包率Avg:平均延迟StDev:标准差,反映抖动
注意:中间节点的丢包不一定是问题,有些路由器限制ICMP响应速率。关键看最终目标的丢包率。
2. 延迟问题排查
2.1 定位延迟来源
延迟高,先定位是哪段网络的问题:
bash
# 1. 本机到网关
ping -c 20 192.168.1.1
# 2. 网关到运营商
traceroute 114.114.114.114
# 3. 到目标服务器
mtr -r -c 50 目标IP
常见情况:
| 延迟位置 | 可能原因 |
|---|---|
| 第一跳(网关)高 | 局域网问题、WiFi干扰、交换机负载 |
| 运营商骨干高 | 跨运营商、跨区域、带宽拥塞 |
| 目标服务器高 | 服务器负载高、距离远 |
2.2 分析延迟波动
bash
# 长时间ping,观察延迟变化
ping -i 0.5 192.168.1.100 | while read line; do
echo "$(date '+%Y-%m-%d %H:%M:%S') $line"
done | tee ping_log.txt
分析结果:
bash
# 看延迟分布
awk -F'time=' '{print $2}' ping_log.txt | awk -F' ' '{print int($1)}' | sort | uniq -c
# 找出延迟超过阈值的时间点
grep -E 'time=[0-9]{2,}\.' ping_log.txt
2.3 TCP层面的延迟分析
ping只测ICMP,实际TCP连接可能不一样:
bash
# 测试TCP连接延迟
# 安装hping3
yum install -y hping3
# TCP SYN延迟
hping3 -S -p 80 -c 10 192.168.1.100
# 输出示例
# len=46 ip=192.168.1.100 ttl=64 DF id=0 sport=80 flags=SA seq=0 win=65535 rtt=0.5 ms
也可以用tcpdump分析:
bash
# 抓TCP握手时间
tcpdump -i eth0 -nn 'host 192.168.1.100 and tcp[tcpflags] & (tcp-syn|tcp-ack) != 0'
2.4 应用层延迟分析
bash
# HTTP请求各阶段耗时
curl -w "\n\
DNS解析: %{time_namelookup}s\n\
TCP连接: %{time_connect}s\n\
TLS握手: %{time_appconnect}s\n\
首字节: %{time_starttransfer}s\n\
总耗时: %{time_total}s\n" \
-o /dev/null -s https://www.example.com
# 输出示例
# DNS解析: 0.012s
# TCP连接: 0.045s
# TLS握手: 0.123s
# 首字节: 0.234s
# 总耗时: 0.345s
3. 丢包问题排查
3.1 确认丢包位置
bash
# 持续ping,统计丢包
ping -c 1000 -i 0.1 192.168.1.100
# 用mtr定位丢包在哪一跳
mtr -r -c 200 192.168.1.100
分析技巧:
- 如果某一跳开始出现丢包,后续节点丢包率相近,问题在那一跳
- 如果只有中间某一跳丢包,后续恢复,可能是该节点限制ICMP,不是真丢包
3.2 检查本机网络
bash
# 网卡错误统计
ifconfig eth0 | grep -E 'errors|dropped|overruns'
# 或者用ip命令
ip -s link show eth0
# 详细统计
cat /proc/net/dev
# 检查网卡队列
ethtool -S eth0 | grep -E 'drop|error|miss'
常见问题:
bash
# RX dropped高:接收缓冲区满
# 解决:增大ring buffer
ethtool -G eth0 rx 4096
# RX errors高:物理层问题
# 检查网线、交换机端口
# TX dropped高:发送队列满
# 检查带宽是否打满
sar -n DEV 1
3.3 检查系统层面
bash
# 检查conntrack是否满
cat /proc/sys/net/netfilter/nf_conntrack_count
cat /proc/sys/net/netfilter/nf_conntrack_max
# 检查socket缓冲区
cat /proc/sys/net/core/rmem_max
cat /proc/sys/net/core/wmem_max
# 检查TIME_WAIT数量
ss -s
# 检查SYN队列
netstat -s | grep -i syn
3.4 检查网络设备
bash
# 检查交换机端口统计(登录交换机)
show interface ethernet 1/1 counters
# 检查路由器队列
show interface fastethernet 0/0 | include drops
# 检查防火墙连接数
iptables -L -v -n
4. 常见问题场景
4.1 跨运营商延迟高
表现:同城访问延迟却很高。
排查:
bash
mtr -r -c 50 -w 目标IP
如果看到流量绑到了远地(比如北京的机器访问上海,结果绕到广州),就是运营商互联问题。
解决方案:
- 使用BGP多线机房
- CDN加速
- 用组网工具走专线(后面会讲)
4.2 WiFi环境丢包
表现:无线连接时丢包,有线正常。
排查:
bash
# Linux查看WiFi信号
iwconfig wlan0
# 关注Signal level和Noise level
# Signal level应该大于-70 dBm
解决方案:
- 换5G频段
- 调整AP位置
- 减少同频干扰
4.3 MTU问题导致丢包
表现:ping小包正常,大包就丢。
排查:
bash
# 二分法找MTU
ping -M do -s 1472 192.168.1.100 # 如果不通
ping -M do -s 1400 192.168.1.100 # 如果通
ping -M do -s 1436 192.168.1.100 # 继续二分
常见MTU:
- 以太网:1500
- PPPoE:1492
- VPN隧道:1400-1450
解决方案:
bash
# 调整MTU
ip link set eth0 mtu 1400
# 或者开启PMTUD
sysctl -w net.ipv4.ip_no_pmtu_disc=0
4.4 TCP重传导致慢
表现:带宽够,但传输慢。
排查:
bash
# 查看重传统计
netstat -s | grep -i retrans
# 或者
ss -ti dst 192.168.1.100
# 看retrans字段
解决方案:
bash
# 调整TCP参数
sysctl -w net.ipv4.tcp_retries2=8
sysctl -w net.ipv4.tcp_syn_retries=3
# 启用BBR拥塞控制(改善高延迟网络)
sysctl -w net.core.default_qdisc=fq
sysctl -w net.ipv4.tcp_congestion_control=bbr
4.5 跨机房/跨网络延迟问题
多机房部署时,机房间网络质量直接影响服务性能。
排查:
bash
# 持续监控机房间延迟
while true; do
echo "$(date) $(ping -c 1 -W 1 对端IP | grep time=)"
sleep 10
done >> latency_monitor.log
优化方案:
- 专线:延迟低、稳定,但贵
- SD-WAN:智能选路,成本适中
- 组网工具:WireGuard、ZeroTier、星空组网等,在公网基础上建隧道,有一定优化效果
如果是临时跨网络调试,用组网工具把几台机器串起来挺方便。配置一次后,机器之间就像在同一个局域网,延迟也比绕公网直连稳定一些。
5. 监控与告警
5.1 Prometheus + Blackbox Exporter
yaml
# blackbox.yml
modules:
icmp:
prober: icmp
timeout: 5s
icmp:
preferred_ip_protocol: ip4
tcp_connect:
prober: tcp
timeout: 5s
http_2xx:
prober: http
timeout: 5s
http:
valid_http_versions: ["HTTP/1.1", "HTTP/2"]
valid_status_codes: [200]
yaml
# prometheus.yml
scrape_configs:
- job_name: 'blackbox-icmp'
metrics_path: /probe
params:
module: [icmp]
static_configs:
- targets:
- 192.168.1.100
- 192.168.2.100
relabel_configs:
- source_labels: [__address__]
target_label: __param_target
- source_labels: [__param_target]
target_label: instance
- target_label: __address__
replacement: blackbox-exporter:9115
常用指标:
promql
# 延迟
probe_duration_seconds{job="blackbox-icmp"}
# 丢包(探测失败)
probe_success{job="blackbox-icmp"} == 0
# 告警规则
- alert: HighLatency
expr: probe_duration_seconds > 0.1
for: 5m
labels:
severity: warning
annotations:
summary: "High latency to {{ $labels.instance }}"
5.2 简单脚本监控
bash
#!/bin/bash
# network_monitor.sh
TARGETS="192.168.1.100 192.168.2.100 8.8.8.8"
THRESHOLD_MS=50
THRESHOLD_LOSS=5
for target in $TARGETS; do
result=$(ping -c 10 -W 2 $target 2>/dev/null)
if [ $? -ne 0 ]; then
echo "[$(date)] ERROR: $target unreachable"
continue
fi
avg=$(echo "$result" | tail -1 | awk -F'/' '{print $5}')
loss=$(echo "$result" | grep -oP '\d+(?=% packet loss)')
if [ $(echo "$avg > $THRESHOLD_MS" | bc) -eq 1 ]; then
echo "[$(date)] WARNING: $target latency ${avg}ms > ${THRESHOLD_MS}ms"
fi
if [ $loss -gt $THRESHOLD_LOSS ]; then
echo "[$(date)] WARNING: $target packet loss ${loss}% > ${THRESHOLD_LOSS}%"
fi
done
加到crontab定期执行:
bash
*/5 * * * * /path/to/network_monitor.sh >> /var/log/network_monitor.log 2>&1
6. 优化建议
6.1 系统参数优化
bash
# /etc/sysctl.conf
# 增大socket缓冲区
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216
# 启用TCP BBR(需要内核4.9+)
net.core.default_qdisc = fq
net.ipv4.tcp_congestion_control = bbr
# 减少TIME_WAIT
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 30
# 增大连接跟踪表
net.netfilter.nf_conntrack_max = 1048576
6.2 网卡优化
bash
# 增大ring buffer
ethtool -G eth0 rx 4096 tx 4096
# 开启网卡多队列
ethtool -L eth0 combined 4
# 中断亲和性(绑定到不同CPU)
# 查看中断号
cat /proc/interrupts | grep eth0
# 绑定到指定CPU
echo 2 > /proc/irq/XX/smp_affinity
6.3 应用层优化
- 使用连接池,减少TCP握手
- 启用HTTP/2,多路复用
- 合理设置超时和重试
- 考虑本地缓存,减少网络请求
总结
| 问题类型 | 排查工具 | 关键指标 |
|---|---|---|
| 延迟高 | ping, mtr, hping3 | RTT, 各跳延迟 |
| 丢包 | ping, mtr, ethtool | Loss%, 网卡错误计数 |
| 抖动 | mtr, ping统计 | StDev, 延迟波动 |
| TCP慢 | ss, netstat -s | 重传次数 |
| 应用慢 | curl -w, tcpdump | 各阶段耗时 |
排查步骤:
- 确认现象:是延迟高、丢包还是抖动
- 定位位置:本机、局域网、运营商、还是目标端
- 分析原因:网络设备、带宽、配置、还是物理层
- 验证解决:修改后持续观察,确认问题解决
网络问题排查需要耐心,一层层定位,工具只是辅助,关键是理解网络各层的工作原理。