linux无直接输出重传率命令,须用/proc/net/snmp计算瞬时重传率:(retranssegs₂−retranssegs₁)÷(outsegs₂−outsegs₁),>0.5%需关注,>2%应立即排查。

用 /proc/net/snmp 算真实瞬时重传率
Linux 不提供直接输出“重传率百分比”的命令,必须靠差值计算:重传率 = (TCPRetransSegs 增量) ÷ (TcpOutSegs 增量)。这个比值才是可比、可告警的真实指标。
执行 cat /proc/net/snmp | grep -A1 Tcp | tail -n1,输出类似:
Tcp: RtoAlgorithm RtoMin RtoMax InSegs OutSegs RetransSegs InErrs
注意列序(不同内核版本可能微调):RetransSegs 通常在第 15 列,OutSegs 在第 11 列。别直接拿绝对值相除——必须取两组采样点的差值。
- 用
watch -n1 'cat /proc/net/snmp | grep -A1 Tcp | tail -n1'观察 5–10 秒,手动记下两组值 - 算出
(RetransSegs₂ − RetransSegs₁) ÷ (OutSegs₂ − OutSegs₁) - 结果 > 0.005(即 0.5%)需关注;> 0.02(2%)说明链路已明显丢包,应立刻排查
用 nstat 看每秒重传增量(省事不手算)
nstat 是 sysstat 提供的专用工具,自动处理差值和单位,比手算更稳,也更适合脚本集成。
运行 watch -n 1 'nstat -z -t 1 | grep -E "TcpRetransSegs|TcpOutSegs"',输出第二列是「上一秒内的增量」,例如:
TcpRetransSegs 123 0.0<br>TcpOutSegs 9876 0.0
该秒重传率 ≈ 123 / 9876 ≈ 1.25%。
-
-t 1表示按 1 秒聚合,-z过滤掉零值,避免干扰 -
TcpOutSegs包含纯 ACK,所以这个比值偏保守,但趋势判断完全够用 - 若系统没装
sysstat,先apt install sysstat或yum install sysstat
用 ss -ti 查单连接重传次数(别误读字段)
ss -ti 的 retransmits 字段常被当成“总重传数”,但它只统计超时重传(RTO timeout),不包括快速重传、SACK 或 TLP。
执行 ss -ti state established,看每行末尾的 retransmits 值:
- 该值在连接关闭后清零,无法回溯;即使
TCPRetransSegs持续上涨,它也可能为 0 - 它对应
/proc/net/snmp中的TCPTimeouts,不是TCPRetransSegs - 真要定位高重传流:先用
ss -tunap找目标四元组,再加-i查其retransmits;若值 > 0 且持续增长,说明该流路径存在稳定丢包
为什么 sar -n TCP 不行,以及常见翻车点
sar -n TCP 实际无效——官方文档和内核源码中根本不存在这个子选项,执行会报错或静默忽略。
有人误用 sar -n TCP 1 3,结果什么也没输出,或返回其他协议层数据(如 DEV)。
- 真正能用的是
sar -n ETCP(扩展 TCP 统计),它提供retransmit(累计重传段数)、orsts、inerrs等字段,但仍是快照,仍需自己做差值 -
netstat -s是对/proc/net/snmp的文本封装,在最小化系统或容器里常不可用;更重要的是字段解析逻辑不透明,容易误判 -
ss -s只显示当前有重传行为的连接数(非累计),不能反映重传总量,也不适用于 UDP 或非 TCP 流量
重传率的核心难点不在采集,而在理解字段语义和时间窗口一致性。同一秒内 RetransSegs 和 OutSegs 的增量必须严格对应,否则比值失真。很多脚本直接读绝对值相除,结果毫无参考价值。











