必须用ss -ti查看真实业务流量RTT,因其直接读取内核TCP控制块中动态更新的rtt值(如rtt:0.858/0.46),而ping测ICMP路径延迟,不受TCP拥塞控制、重传等影响,无法反映HTTP/MySQL/SSH等实际连接状况。

要看真实业务流量的 RTT,必须用 ss -ti;ping 测出来的是 ICMP 路径延迟,和你正在跑的 HTTP、MySQL、SSH 连接完全不是一回事。
为什么 ping 的 RTT ≠ 当前 TCP 连接的 RTT
常见错误是看到 ping 延迟 5ms 就以为服务快,结果 curl 卡住 800ms —— 很可能那条 TCP 连接实际 RTT 已飙到 400ms+,但 ping 根本反映不出来。
-
ping发的是 ICMP 包,不经过 TCP 栈,不受拥塞控制、重传、SACK、TSO/GSO 影响 - 真实业务走 TCP,内核在每个 ACK 中动态更新 RTT,
ss -ti直接读的就是这个值 - ICMP 可能被防火墙限速或丢弃,TCP 流量却正常(尤其云厂商策略)
- 同一台机器上不同 TCP 连接的 RTT 差异极大(比如一个连 CDN,一个连数据库)
用 ss -ti 精确抓取指定 TCP 连接的 RTT
ss -ti 是唯一能在运行时读取内核 TCP 控制块中 rtt 字段的命令,输出形如 rtt:0.858/0.46,前者是平滑 RTT(srtt),后者是方差(rttvar)。
- 查本机所有 ESTAB 连接的 RTT:
ss -ti state established - 查连向特定目标 IP 和端口的连接:
ss -ti 'dst 192.168.0.224:20007' - 查本地某端口发起的连接:
ss -ti 'src :8080' - 动态观察变化:
watch -n1 'ss -ti state established | grep -v "rtt:" | head -5'
注意:如果某行没出现 rtt: 字段,说明该连接刚建连、还没收到足够 ACK,可稍等或触发一次请求(比如发个 HTTP 请求)再试。
结合 traceroute 定位 RTT 高在哪一段
单看 ss -ti 只知道“这条连接 RTT 高”,但不知道“高在哪一跳”。这时候得用 traceroute -T 找出异常跃点。
- 执行
traceroute -T -p 443 example.com(强制走 TCP,绕过 ICMP 屏蔽) - 发现第 5 跳延迟突增(比如从 12ms → 210ms),记下该跳 IP
- 立刻执行
ss -ti 'dst <该跳IP>',确认是否也出现高 RTT - 再对比
ping -c3 <该跳IP>:若 ping 正常但 TCP RTT 高,大概率是中间设备对 TCP 流量做了深度检测或限速
别信 mtr 的“平均延迟”——它默认用 ICMP,且窗口太宽,容易掩盖瞬时抖动。
真正难的不是命令怎么敲,而是意识到:RTT 不是单个数字,而是随连接、路径、时间实时变化的指标;同一个 curl 请求背后可能涉及多个 TCP 连接,每条的 RTT 都得单独看。


















