Linux 网络延迟分析与优化技巧

1次阅读

ping和mtr延迟高但业务不卡顿,是因为icmp探测与tcp业务流量路径/策略不同;应改用tcp探测(如mtr -t)、分析ss -i真实rtt、关注连接状态与中间设备策略。

Linux 网络延迟分析与优化技巧

ping 和 mtr 显示延迟高,但实际业务没卡顿,怎么回事?

网络延迟指标和用户体验不一致,大概率是测量方式没对齐。ping 用的是 ICMP 包,而你的服务走的是 TCP(比如 http数据库连接),中间设备(尤其是防火墙、QoS 策略)可能对 ICMP 做了限速或丢弃,但放行业务流量。ping 结果只能看链路连通性,不能代表应用层真实 RTT。

  • mtr 虽然能定位跳点,但它默认也发 ICMP;加 -T 参数改用 TCP 探测(如 mtr -T -p 443 example.com),才更贴近 https 流量路径
  • 如果业务走的是长连接(如 websocket、gRPC),还要关注 tcpdump 抓包里的 SYNACK 时间、重传次数,而不是单纯看 ping
  • 某些云厂商的“内网延迟”宣传值,测的是同可用区、同宿主机的 iperf3 udp 吞吐,和你跑在容器里、跨节点、带 TLS 的请求毫无可比性

用 tcpping 或 hping3 测 TCP 延迟,为什么结果忽高忽低?

TCP 连接建立过程受 SYN 队列、TIME_WAIT 回收、本地端口耗尽等影响,单次探测波动大,不是工具不准,而是你在测一个有状态的过程。

  • tcpping 默认只发一次 SYN,失败就报超时;建议加 -x 5 多试几次取中位数
  • hping3 -S -p 80 -c 10 example.com 更可控,但注意:目标端口必须监听,否则 SYN 会被 RST 回复,延迟测出来是 0 或极小——这不是快,是连接被拒
  • linux 内核参数 net.ipv4.tcp_tw_reuse 开启后,短连接延迟会降低,但某些 NAT 环境下可能引发 TIME_WAIT 冲突,别无脑开

ss -i 输出里的 rtt/rttvar 是啥?比 ping 准吗?

ss -i 显示的是内核为每个 TCP 连接维护的平滑 RTT 估计值(rtt)和方差(rttvar),来源是真实数据包往返时间,不是探测包,所以比 ping 更贴近业务感受。

  • 它只对已建立的连接有效,ss -t state established 才能看到;刚建立的连接,rtt 可能还是初始值(200ms)
  • rttvar 高说明网络抖动大,即使平均 rtt 看着不高,也可能频繁触发重传
  • 注意单位:rtt 是毫秒,但显示时省略了小数点(比如 rtt:1234 其实是 123.4ms)

调整 net.ipv4.tcp_slow_start_after_idle 导致上传变慢?

这个参数控制空闲连接是否重置拥塞窗口(cwnd)。设为 0 表示不重置,适合长连接、间歇性发包的场景(如 ssh、数据库心跳);但设为 1(默认)会在空闲后降回初始 cwnd=10,对短突发上传(比如上传小文件)明显拖慢首包速度。

  • 不是所有业务都适合关它:echo 0 > /proc/sys/net/ipv4/tcp_slow_start_after_idle
  • 云环境尤其要注意:很多负载均衡器(如 AWS ALB)本身会主动断开空闲连接,此时关掉它反而让连接卡在半死不活状态,触发更多 RST
  • 更稳妥的做法是调 net.ipv4.tcp_keepalive_time 缩短保活间隔,配合应用层心跳,而不是硬压 cwnd

真实延迟问题往往卡在中间链路策略、连接生命周期管理、或测量与业务协议错位上。盯着一个数字调参数,不如先确认你测的到底是不是业务走的那条路。

text=ZqhQzanResources