linux无直接查看tcp重传总数的命令,需组合ss、netstat -s或/proc/net/snmp:ss -s显示当前重传连接数(非累计),netstat -s和/proc/net/snmp提供自启动累计重传段数、超时次数及连接重置数,三者统计口径不同且需注意字段差异与适用场景。

Linux 没有直接暴露“TCP 重传总数”的单一命令或文件,必须组合 ss、netstat -s 或 /proc/net/snmp 解析 TCP 统计字段——且不同来源统计口径不一致,容易误读。
用 ss -s 快速看当前重传连接数
ss -s 输出末尾的 retransmits 行是唯一能直接看到“当前存在重传行为的连接数”的轻量方式,但它不是累计值,也不区分 TCP 版本:
- 运行
ss -s,找类似retransmits: 3这样的行——表示此刻有 3 个连接正在经历重传(即 retransmit timer 已触发但尚未确认) - 这个数字瞬时波动大,
watch -n1 'ss -s | grep retransmit'可观察趋势,但无法回溯历史 - 它不体现重传次数总和,比如一个连接重传 10 次,这里仍只计为 1
- 对 UDP 或非 TCP 流量完全无感
从 netstat -s 提取 TCP 重传累计计数
netstat -s 的 TCP 段落里有明确字段,但需注意:它统计的是内核协议栈发出的重传报文数,不含应用层重试(如 curl 重试 HTTP 请求):
- 执行
netstat -s | grep -A2 "Tcp:",关注retransmitted行,例如:54 segments retransmitted - 该值是自系统启动以来的累计值,重启后归零;若增长过快(如每秒增几十),说明网络丢包或接收端处理延迟严重
- 注意区分
retransmit timeout和retransmitted:前者是超时事件次数,后者是实际发出的重传报文段数,通常后者 ≥ 前者 -
netstat -s在部分最小化镜像中可能未预装,可用ss -s替代,但后者无累计能力
解析 /proc/net/snmp 获取更细粒度 TCP 重传指标
/proc/net/snmp 是内核 SNMP 接口,字段固定、机器可读,适合脚本采集,但需按列索引匹配(不同内核版本列序可能微调):
- 运行
awk '$1 == "Tcp:" {print $10, $11, $12}' /proc/net/snmp——第 10 列是RetransSegs(重传段数),第 11 列是RetransTimeouts(重传超时次数),第 12 列是EstabResets(因重传失败导致连接重置数) - 这些值与
netstat -s中对应项理论上一致,但/proc/net/snmp更可靠:它绕过用户态工具解析,直接读内核计数器 - 某些老内核(如 3.10)可能缺失部分字段,建议先
head -1 /proc/net/snmp确认列名顺序 - 别混淆
/proc/net/snmp和/proc/net/netstat:netstat文件含更多扩展统计(如TcpExt:下的SynRetrans),但字段命名更不直观
为什么 ip -s link 或 ethtool -S 不适用
链路层工具只能告诉你物理帧是否被丢弃或校验失败,无法定位到 TCP 层重传原因:
-
ip -s link show中的RX errors上涨,说明网线/交换机问题,但不等于 TCP 重传——重传可能由远端 ACK 延迟、中间设备限速、甚至本机 socket buffer 满导致 -
ethtool -S eth0 | grep retrans几乎总为空:网卡驱动不统计 TCP 重传,那是协议栈的事 - 若发现
netstat -s重传数飙升,而ip -s link的errors为 0,大概率是路径中某台设备(如防火墙、负载均衡器)静默丢包,而非本机硬件问题
真正难的是把重传数和业务影响挂钩:单看 RetransSegs 增加 1000 次没意义,得结合 ss -i 查具体连接的 retrans 字段、抓包确认丢包位置,再比对应用日志里的超时错误。工具只给数字,原因得靠交叉验证。











