网络协议与性能分析实战指南

面向 SRE / 运维工程师的深度网络诊断手册 覆盖 TCP/IP 栈原理、常见瓶颈识别、工具链使用及优化策略 适用于 Linux(CentOS/RHEL/Ubuntu)生产环境


1. 网络性能分析方法论

🔍 分析流程(USE 方法 + RED 方法)

方法 关键指标
USE(Utilization, Saturation, Errors) 网卡利用率、队列饱和度、丢包/错包
RED(Rate, Errors, Duration) 请求速率、错误率、延迟分布

📊 性能基线(健康阈值)

指标 健康值 危险值
网卡 util < 70% > 90%
TCP 重传率 < 0.1% > 1%
SYN 丢弃 = 0 > 0
TIME_WAIT 数量 < 50% max conn 接近 net.ipv4.ip_local_port_range 上限
UDP 丢包 = 0 > 0

💡 提示:使用 sar -n DEV 1ss -inetstat -s 持续监控。


2. TCP/IP 协议栈关键机制

2.1 TCP 三次握手与队列

Client          Server
  | -- SYN -----> |  → 放入 **SYN Queue** (tcp_max_syn_backlog)
  | <-- SYN+ACK --|  
  | -- ACK -----> |  → 移入 **Accept Queue** (somaxconn)
  • SYN Queue 满 → 丢弃 SYN,netstat -s | grep "listen overflows"
  • Accept Queue 满 → 丢弃 ACK,客户端表现为连接超时

2.2 TIME_WAIT 与端口复用

  • TIME_WAIT 作用:防止旧连接数据包干扰新连接
  • 默认持续时间2 * MSL = 60秒(Linux)
  • 安全复用net.ipv4.tcp_tw_reuse = 1(仅用于 outgoing 连接)

⚠️ 禁止使用 tcp_tw_recycle(Linux 4.12+ 已移除,NAT 环境会导致连接失败)

2.3 拥塞控制算法

算法 特点 适用场景
CUBIC 默认(高带宽) 数据中心内部
BBR 基于带宽估计,低延迟 公网、跨机房
RENO 老旧算法 兼容性场景

启用 BBR:

echo 'net.core.default_qdisc=fq' >> /etc/sysctl.conf
echo 'net.ipv4.tcp_congestion_control=bbr' >> /etc/sysctl.conf
sysctl -p

3. 常见网络瓶颈场景

🚨 场景 1:高并发下连接拒绝("Cannot assign requested address")

  • 原因:本地端口耗尽(ip_local_port_range 范围小)

  • 检查

    ss -s  # 查看 total sockets
    cat /proc/sys/net/ipv4/ip_local_port_range  # 默认 32768 60999
    
  • 解决

    net.ipv4.ip_local_port_range = 1024 65535
    net.ipv4.tcp_fin_timeout = 30
    net.ipv4.tcp_tw_reuse = 1
    

🚨 场景 2:大量 CLOSE_WAIT

  • 原因:应用未正确关闭 socket(代码 bug)

  • 检查

    ss -tan state close-wait | wc -l
    lsof -p <PID> | grep TCP
    
  • 解决:修复应用逻辑,设置合理的读写超时

🚨 场景 3:TCP 重传率高

  • 原因:网络丢包、拥塞、MTU 不匹配

  • 检查

    sar -n ETCP 1    # 查看重传
    ping -M do -s 1472 <host>  # 测试 MTU(1500 - 28 = 1472)
    tc qdisc show dev eth0     # 查看是否限速
    
  • 解决

    • 调整 tcp_rmem/tcp_wmem
    • 启用 BBR
    • 检查交换机/防火墙 QoS

🚨 场景 4:UDP 丢包(DNS、NTP、音视频)

  • 原因:接收缓冲区满、应用处理慢

  • 检查

    netstat -su | grep "receive errors"
    ss -uln  # 查看 Recv-Q
    
  • 解决

    net.core.rmem_max = 268435456   # 256MB
    net.ipv4.udp_rmem_min = 8388608 # 8MB
    

4. 核心诊断工具链

4.1 基础工具

工具 用途 示例
ss 替代 netstat,更快 ss -i state established
sar 历史性能数据 sar -n TCP,ETCP 1
iftop 实时带宽监控 iftop -i eth0
mtr 路由跟踪 + 丢包 mtr --report www.example.com

4.2 高级工具

工具 用途 示例
tcpdump 抓包分析 tcpdump -i eth0 'tcp port 80' -w http.pcap
bpftrace 动态追踪内核 bpftrace -e 'tracepoint:syscalls:sys_enter_connect { @[comm] = count(); }'
bcc BPF 工具集 tcpretrans(实时重传)、opensnoop(文件打开)
iperf3 带宽压测 iperf3 -c <server> -t 60 -P 4

4.3 关键命令速查

# 查看 TCP 连接状态统计
ss -s

# 查看详细 TCP 重传
sar -n ETCP 1

# 实时监控每个连接的 RTT 和 cwnd
ss -i state established

# 检查 SYN Flood 防护
netstat -s | grep -i "syn"

# 查看 UDP 丢包
netstat -su | grep "receive errors"

5. 实战案例分析

案例 1:API 网关偶发 504 Gateway Timeout

现象

  • 客户端请求超时(504)
  • Nginx error.log: upstream timed out (110: Connection timed out)

排查步骤

  1. ss -i 发现后端连接 RTT 高达 2s+
  2. mtr 显示跨机房链路丢包 0.5%
  3. sar -n ETCP 显示 TCP 重传率 0.8%

根因: 公网链路不稳定导致 TCP 重传,触发 Nginx proxy_read_timeout(默认 60s)

解决

  • 启用 BBR 拥塞控制
  • 调整超时:proxy_connect_timeout 5s; proxy_send_timeout 10s; proxy_read_timeout 10s;
  • 后端服务增加重试机制

案例 2:数据库主从同步延迟突增

现象

  • MySQL 主从延迟从 1s → 300s
  • 网络带宽未打满

排查步骤

  1. tcpdump 抓包发现大量 DUP ACK
  2. ss -i 显示 cwnd(拥塞窗口)频繁下降
  3. ethtool -S eth0 发现 rx_crc_errors 非零

根因: 物理网卡故障导致 CRC 错误,触发 TCP 重传

解决: 更换网卡,启用 ethtool -K eth0 rx-checksumming on 校验


6. 网络调优最佳实践

6.1 通用调优参数(/etc/sysctl.d/99-net.conf)

# 连接队列
net.core.somaxconn = 65535
net.core.netdev_max_backlog = 5000
net.ipv4.tcp_max_syn_backlog = 8192

# TIME_WAIT 优化
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 30

# 端口范围
net.ipv4.ip_local_port_range = 1024 65535

# 缓冲区(根据带宽延迟积调整)
net.core.rmem_max = 268435456
net.core.wmem_max = 268435456
net.ipv4.tcp_rmem = 4096 87380 268435456
net.ipv4.tcp_wmem = 4096 65536 268435456

# 拥塞控制
net.core.default_qdisc = fq
net.ipv4.tcp_congestion_control = bbr

6.2 场景化建议

场景 额外调优
反向代理 增大 somaxconn,启用 tcp_tw_reuse
数据库 减小 tcp_slow_start_after_idle=0(避免空闲后慢启动)
音视频 增大 UDP 缓冲区,禁用 Nagle(TCP_NODELAY
跨机房 启用 BBR,增大初始 cwnd(initcwnd=10

7. 高级技巧:eBPF 与 BPFTrace

7.1 实时追踪 TCP 重传

# 使用 bcc 工具
/usr/share/bcc/tools/tcpretrans

# 输出示例:
Tracing retransmits ... Hit Ctrl-C to end
TIME     PID    COMM         LADDR           LPORT  RADDR           RPORT
12:05:23 0      swapper/2    10.0.0.10       3306   10.0.0.20       54321

7.2 自定义 BPFTrace 脚本

// tcp_drop.bt
tracepoint:tcp:tcp_drop {
    printf("DROP: %s:%d -> %s:%d\n",
           ntop(args->saddr), args->sport,
           ntop(args->daddr), args->dport);
}

运行:bpftrace tcp_drop.bt

💡 eBPF 无需修改内核,安全高效,是下一代网络可观测性基石。


最后提醒

  • 不要盲目调大缓冲区!过大的 bufferbloat 会增加延迟
  • 公网环境慎用 tcp_tw_recycle
  • 先抓包,再调参 —— 80% 的问题通过 tcpdump 可定位

results matching ""

    No results matching ""