Linux无直接输出重传率命令,必须用/proc/net/snmp中同一时间窗口内TCPRetransSegs与TcpOutSegs的增量比值计算:重传率=(RetransSegs₂−RetransSegs₁)÷(OutSegs₂−OutSegs₁),>0.5%需关注,>2%应立即排查。

用 /proc/net/snmp 算系统级瞬时重传率(最准、最轻量)
Linux 不提供直接输出“重传率”的命令,/proc/net/snmp 是唯一内核原生、容器可用、无需额外包的可靠来源。关键不是看绝对值,而是同一时间窗口内的增量比:(RetransSegs₂ − RetransSegs₁) ÷ (OutSegs₂ − OutSegs₁)。
执行 cat /proc/net/snmp | grep -A1 Tcp | tail -n1,输出类似:
Tcp: RtoAlgorithm RtoMin RtoMax InSegs OutSegs RetransSegs InErrs
第 11 列是 OutSegs(总发出段数),第 15 列是 RetransSegs(已重传段数)。注意:不同内核版本列序可能微调,建议先 head -1 /proc/net/snmp 确认字段位置。
- 用
watch -n1 'cat /proc/net/snmp | grep -A1 Tcp | tail -n1'观察 5–10 秒,手动记下两组值即可计算 - 结果 > 0.005(0.5%)需关注;> 0.02(2%)说明链路已明显丢包,应立刻排查物理层或中间设备
-
OutSegs包含纯 ACK,所以该比值偏保守,但趋势判断完全可靠
用 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过滤零值,避免干扰 - 若系统未装
sysstat,用apt install sysstat(Debian/Ubuntu)或yum install sysstat(RHEL/CentOS)补上 - 它不依赖 net-tools,也不受
netstat -s字段名不统一的坑影响
用 ss -ti 查单连接的 retransmits(别当重传总数用)
ss -ti 输出里的 retransmits 字段常被误读为“该连接总重传次数”,但它只统计超时重传(RTO timeout),不含快速重传、SACK 或 TLP。
执行 ss -ti state established,每行末尾的 retransmits 值对应 /proc/net/snmp 中的 TCPTimeouts,不是 TCPRetransSegs。
- 该值在连接关闭后清零,无法回溯历史;即使全局
TCPRetransSegs持续上涨,它也可能为 0 - 真要定位高重传流:先用
ss -tunap找目标四元组(如ss -tunap sport = :8080),再加-i查其retransmits;若值 > 0 且持续增长,说明该流路径存在稳定丢包 - 别用
ss -s的retransmits: 3当累计值——它只是当前有重传行为的连接数,不是重传段总数
为什么 sar -n TCP 和 netstat -s 容易翻车
sar -n TCP 实际无效——内核源码和 man page 中根本不存在这个子选项,执行会静默忽略或报错。有人误用 sar -n TCP 1 3,结果什么也没输出,或返回其他协议层数据(如 DEV)。
netstat -s 是对 /proc/net/snmp 的文本封装,但问题不少:
- 在最小化系统或容器里常不可用(CentOS 7+/Ubuntu 22.04+ 默认不预装
net-tools) - 字段名不统一(有的写
TCPRetransSegs,有的写RetransSegs),脚本解析极易出错 - 它不提供时间窗口差值,仍需你手动采样计算,不如直接读
/proc/net/snmp
真正能用的是 sar -n ETCP,它提供 retransmit(累计重传段数)等字段,但仍是快照,仍需自己做差值——不如 nstat 或轮询 /proc/net/snmp 直观。


















