【免费下载链接】TcpQuality
测网速时,ping 丢包率常常是 0%,但真实业务却卡顿——问题在于 ICMP 小包与 TCP 大流量的路径、优先级都不同。TcpQuality 是一款 Linux TCP 质量检测脚本,它借助 bpftrace 在内核级钩住tcp_retransmit_skb事件,逐段记录真实重传并去重计数,把"这条链路到底丢了多少 TCP 数据段"量化成可对比的指标,比传统丢包率更贴近用户真实体感。
为什么"丢包率"经常会骗人
很多运维工具用 ping 或 mtr 判断网络质量,但这类探测存在明显偏差:
- 协议不同:ping 发的是 ICMP 小包,而你的业务走的是 TCP 443 大流量,部分运营商会对其做不同的 QoS 调度;
- 包长不同:小探针包容易"挤"进队列,大包却容易触发队列丢弃;
- 口径不同:ICMP 丢包按"往返失败"计,一次抖动就可能丢一个 ping,而 TCP 一次丢包会触发整段重传,两者的量级完全不可比。
换句话说,ping 显示 0% 丢包 ≠ 你的 TCP 流量没有丢包。真正反映链路损耗的,是"有多少 TCP 数据段被迫重传了至少一次"。
核心原理:bpftrace 内核级追踪重传
TcpQuality 的关键在于直接用 bpftrace 在内核里抓"重传"这个动作本身。核心脚本是 tcpquality-retrans-seq.bt,它挂载在内核 tracepointtcp:tcp_retransmit_skb上:
tracepoint:tcp:tcp_retransmit_skb /args->dport == 443/ { if (args->skbaddr != 0) { $skb = (uint64)args->skbaddr; $seq = *(uint32 *)($skb + 40); $end_seq = *(uint32 *)($skb + 44); ... } }它只关注443 端口的 TCP 重传事件,从重传 skb 中读出该数据段的seq/end_seq(序列号区间),连同目标地址、socket 指针一起输出。这样每一个"被重传的数据段"都有了一份内核级证据,而不是靠事后估算。
一个细节很见功力:同一个数据段可能被重传多次(RTO 退避后反复发)。TcpQuality 在用户态以skaddr + seq + end_seq组合去重,保证一个数据段无论重传几次,只计一次——这正是"唯一重传段占比"比裸重传次数更能反映真实损耗的原因。
双保险设计:seq 主探针 + skb 兜底
不同内核的 BTF 信息可用性不同,直接读 TCP 控制块可能在某些内核上失败。TcpQuality 为此准备了两级探针:
| 探针 | 文件 | 去重键 | 适用场景 |
|---|---|---|---|
| seq 主探针 | tcpquality-retrans-seq.bt | socket + seq + end_seq | 内核 BTF 可读,精度最高 |
| skb 兜底探针 | tcpquality-retrans-skb.bt | socket + skb 指针 | 无 BTF TCP 类型的内核 |
启动逻辑在 runTcpQuality-core.sh 的speedtest_retrans_trace_start中:优先尝试 seq 探针,失败则自动切换 skb 兜底方案;两者都不可用时才放弃追踪,绝不输出一个虚假的"0 重传"结果。脚本注释里还特别提醒 shell 侧校验器要拒绝零序列号记录,防止内核布局差异污染数据。
与 TCP_INFO 交叉验证,结果更可信
只靠 tracepoint 还不够,TcpQuality 还引入第二数据源做交叉验证:tcpquality-tcpinfo.c。
这是一个轻量级 LD_PRELOAD 库,会拦截测速进程(curl)的connect/close调用:
- 只跟踪目标 IP 的 443 连接;
- 连接关闭时用
getsockopt(TCP_INFO)读取该 socket 的权威统计:tcpi_total_retrans(累计重传次数)、tcpi_data_segs_out(发出数据段数)、tcpi_bytes_retrans(重传字节数); - 写入快照文件供主脚本解析。
若系统没有预编译库,主脚本会自动降级为用ss -tinp解析同等信息(见 runTcpQuality-core.sh 的speedtest_tcp_info_ss_snapshot)。最终报告里,bpftrace 的"唯一重传段数"必须落在 TCP_INFO 累计重传数的合理范围内才会被采纳(runTcpQuality-core.sh),两套独立数据互相印证,结果可靠性远高于单一来源。
如何跑起来:一行命令测出真实损耗
TcpQuality 默认检测全国三网运营商节点,入口脚本为 runTcpQuality.sh。国内环境一行即可运行:
bash <(curl -fsSL https://tcpquality.ibsgss.uk/run)常用参数(完整列表见 README.md):
--all:完整检测 IPv4/IPv6、CERNET/CERNET2、国际互联和单线程测速;--speedtest:TCP 质量探测后追加单线程测速(重传追踪就工作在这一阶段);-p NUM:并行节点数,范围 1-31,默认 16;--province bj等:只测指定省份。
测速阶段的完整流水线是:启动 bpftrace 探针 → 启动 TCP_INFO 监控 → 发起 curl 下载/上传 → 停止探针 → 去重计数并交叉校验。整套编排集中在 runTcpQuality-core.sh 中,你无需关心任何细节,报告会自动呈现每个节点的延迟、重传数与重传占比。
你最终会得到什么
跑完后,每个节点会得到一组远比"丢包率 0%"有信息量的指标:
- 唯一重传段占比:真正发生过至少一次重传的数据段比例,直接量化链路损耗;
- 累计重传数与重传字节数:来自 TCP_INFO 的 socket 级口径;
- 单线程测速速率:在锁定 TOS 计数、排除干扰流量后的干净速率;
- 分方向(下载/上传)、分地址族(IPv4/IPv6)的对比,帮助定位是回程质量差还是国际互联抖动。
小结
🔍 TcpQuality 的思路很清晰:既然 ICMP 丢包率不能代表 TCP 真实损耗,那就回到内核本身,用 bpftrace 逐个追踪重传数据段、用 seq 去重计数,再叠加 TCP_INFO 交叉验证。对需要评估线路质量的站长和运维来说,这套"重传追踪 + 多源校验"的方法,比任何单一 ping 指标都更接近用户的真实体感。
项目采用 GPL-3.0-only 授权,详见 LICENSE。
【免费下载链接】TcpQuality
相关推荐
1分钟测出服务器真实网络质量:TcpQuality TCP质量探测快速入门指南
1分钟测出服务器真实网络质量:TcpQuality TCP质量探测快速入门指南 TcpQuality 是一个 TCP 质量检测脚本,能在一分钟内测出服务器的真实
BTree 开源项目使用教程
BTree 开源项目使用教程 1. 项目的目录结构及介绍 btree/ ├── btree.go ├── btree_test.go ├── LICENSE ├
可观测性性能剖析tracetcp完整指南:如何用TCP追踪快速诊断网络故障
tracetcp完整指南:如何用TCP追踪快速诊断网络故障 在网络连接故障排查中,tracetcp作为一款专业的TCP路由追踪工具,能够通过发送TCP SYN数
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考