linux无直接输出重传率命令,必须用/proc/net/snmp中tcpretranssegs与tcpoutsegs的增量比值计算:重传率=(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 MaxConn ActiveOpens PassiveOpens AttemptFails EstabResets CurrEstab InSegs OutSegs RetransSegs InErrs OutRsts InCsumErrors
其中第 15 列是 RetransSegs,第 11 列是 OutSegs(注意:不是第 10 或 12 列,不同内核列序一致但需验证)。
- 不能直接用绝对值相除——必须取两组采样点的差值,否则重启后归零或长时间运行后数值溢出失真
- 建议用
watch -n1 'cat /proc/net/snmp | grep -A1 Tcp | tail -n1'观察 5–10 秒,手动记下两组值再计算 - 结果 > 0.005(即 0.5%)需关注;> 0.02(2%)说明链路已明显丢包,应立刻排查物理层或中间设备
-
TcpOutSegs包含纯 ACK,所以该比值略偏保守,但趋势判断完全可靠
用 nstat 看每秒重传增量(省事不手算)
nstat 是 sysstat 提供的专用工具,自动做差值、单位归一化,比手算稳得多。
运行 watch -n 1 'nstat -z -t 1 | grep -E "TcpRetransSegs|TcpOutSegs"',输出类似:
TcpRetransSegs 123 0.0 TcpOutSegs 9876 0.0
第二列是「上一秒内的增量」,直接用 123 ÷ 9876 ≈ 1.25% 即可。
-
-t 1表示按 1 秒聚合,-z过滤掉零值,避免干扰 - 若系统没装
sysstat,先apt install sysstat或yum install sysstat - 注意:
TcpOutSegs同样含纯 ACK,所以该比值仍是保守估计,但足够用于告警阈值判断
用 ss -ti 定位单连接重传行为(别误读字段)
ss -ti 输出里的 retransmits 字段只统计超时重传(RTO timeout),不包括快速重传、SACK 重传或 TLP。
执行 ss -ti state established,每行末尾类似 retransmits:3 的值,含义是:
- 该连接自建立以来发生的 RTO 超时次数,不是总重传段数
- 对应
/proc/net/snmp中的TCPTimeouts,不是TCPRetransSegs - 连接关闭后清零,无法回溯历史;即使全局
TCPRetransSegs持续上涨,它也可能为 0 - 真要定位高重传流,先用
ss -tunap找目标四元组(如ss -tunap sport = :443),再加-i查其retransmits;若值 > 0 且持续增长,说明该流路径存在稳定丢包
为什么 sar -n TCP 不行,以及常见翻车点
sar -n TCP 实际无效——内核源码和官方文档中根本不存在这个子选项,执行会报错或静默忽略。
有人误用 sar -n TCP 1 3,结果什么也没输出,或返回其他协议层数据(如 DEV)。真正能用的是:
-
sar -n ETCP:提供retransmit(累计重传段数)、orsts、inerrs等字段,但仍是快照,仍需自己做差值 -
sar -n TCP的输出字段(如retrans/s)本质来自同一套内核计数器,但retrans/s ÷ oseg/s只能粗略估算比例,因oseg/s含纯 ACK,且无时间窗口对齐保障 -
netstat -s是/proc/net/snmp的文本封装,在最小化系统或容器里常不可用;更重要的是字段解析逻辑不透明,容易把RetransSegs和RetransTimeouts混淆
真正难的不是采集数据,而是理解每个数字背后统计口径的差异——比如一个连接快速重传 5 次,ss -ti 显示 retransmits:0,而 /proc/net/snmp 的 RetransSegs 已 +5。这点不厘清,监控就等于盲人摸象。











