TCP 重传?用 tcpshark 追踪连接与内核丢包
概要
接口超时,TCP 重传计数上涨:究竟是哪条连接、哪个容器出了问题?仅凭节点级指标,很难确定下一步该查哪里。HUATUO tcpshark 捕获内核重传事件,定位连接、阶段和容器,并自动结合 dropwatch 查找本机丢包证据。本文通过实际命令和案例,介绍如何从重传告警逐步缩小故障范围。
为什么需要 tcpshark
| 工具 | 能回答的问题 | 主要局限 |
|---|---|---|
nstat、netstat -s |
节点重传计数是否增长 | 无法定位连接、方向和容器 |
ss -ti |
当前 socket 的 RTT、拥塞和重传快照 | 难以捕获短连接,不提供逐次事件 |
BCC tcpretrans |
哪条流发生了重传或 TLP | 缺少 tcpshark 提供的阶段分类、容器解析和丢包关联 |
tcpdump、Wireshark |
报文时序、ACK/SACK 和疑似重传 | 需要选择抓包点并保存、重组流量,繁忙节点上开销较高 |
tcpshark 观测以下内核路径:
tcp/tcp_retransmit_skb:观测常规重传队列中的 SKB 重传;tcp/tcp_retransmit_synack:观测服务端建连时的 SYN-ACK 重传;tcp_send_loss_probe:观测 Tail Loss Probe。
输出的事件包含四元组、TCP 状态、序列号、拥塞控制状态、重传计数器和 socket 元数据,并在用户态生成 phase 与 tcp_reason。这些信息支撑三层下钻:
- 从主机网络命名空间下钻到容器节点。
- 从容器节点下钻到具体连接和方向。
- 从连接下钻到建连、数据传输或关闭阶段等阶段;
如何使用 tcpshark
tcpshark 指定 --mode retransmit 和 tcp_retransmit.o 的实际路径。以下命令采集 60 秒,以 10.0.0.1:443-444 过滤常规重传,同时启用 TLP,并以 NDJSON 格式输出:
|
|
以下参数直接影响采集范围和结果完整性:
--duration 60将采集限制在业务异常窗口内;设为0时持续运行,直至收到退出信号;--enable-tlp默认关闭,启用后额外挂载tcp_send_loss_probe并输出 TLP 事件;--filter使用 tcpdump 风格表达式;--max-events-per-second 100在 BPF 侧限制事件速率。
独立运行 tcpshark 时,不会包含 container_id。通过 huatuo-bamai 运行时,系统会依次根据 socket 的内存 cgroup、网络命名空间 cookie 和 inum 解析容器归属。下图中的重传连接来自容器 tcpshark-container-demo。
如何分析故障
不能仅凭 tcp_reason="RTO" 判断网络丢包。建议依次确认连接、阶段、重传路径、关联容器以及丢包位置等。
第一步:确认连接
以第一张图的第一条事件为例:
10.0.0.2:33342 > 10.0.0.1:443:tcp_saddr、tcp_sport、tcp_daddr和tcp_dport共同标识连接与方向;phase="connect"、tcp_state="SYN_SENT"、tcp_flags="SYN"表明正在建立连接;tcp_reason="RTO",前两条事件的icsk_retransmits依次为1、2,且tcp_seq相同:同一个 SYN 连续重试,直接影响建连延迟;net_namespace_inum=4026532512:事件来自该网络命名空间。
第二步:判断连接阶段和路径
phase 将重传分为 connect、data 和 close。tcp_reason 根据事件类型、sk_state、ca_state 和乱序计数器进一步分类。
| 观测信号 | 直接含义 | 优先检查 |
|---|---|---|
connect/RTO 且 SYN |
主动端发起 SYN 重传 | 路由、ACL/防火墙、负载均衡、对端监听和 SYN 队列 |
tcp_retransmit_synack |
服务端发起 SYN-ACK 重传 | 回程链路、客户端状态、防火墙和握手队列 |
data/RTO |
已建立连接进入 Loss 状态或命中 RTO 回退分类 | 主机丢包、网卡、链路拥塞、对端处理和 ACK 返回路径 |
data/fast_retransmit |
探针触发时 socket 处于 Recovery 状态 | 丢包、乱序、ECMP 路径差异及 SACK/RACK 行为 |
TLP |
内核正在执行尾部丢包探测 | 结合后续 ACK、RTO 和业务延迟判断,不能直接认定已经丢包 |
close/RTO |
关闭阶段报文没有按期确认 | 对端退出、连接回收、FIN 路径和中间设备超时策略 |
使用分类结果时需结合上下文:
RTO通常对延迟影响较大。优先关注持续出现、相同序列号反复出现或与业务毛刺对齐的事件;fast_retransmit表示 socket 处于 Recovery 状态,不代表 tcpshark 已还原完整的重复 ACK、SACK 或 RACK 决策过程;unknown表示当前快照不足以分类,不能作为无效事件丢弃。
如需只查看 RTO,可过滤 JSON 输出:
|
|
第三步:判断是否持续
出现以下信号时,应提高排查优先级:
icsk_retransmits持续增长;- 多条连接集中访问同一目的地址、端口或工作负载;
- RTO 与应用延迟、超时或吞吐下降出现在同一时间窗。
对保存的 NDJSON 按目标、阶段和分类聚合,可快速识别主要异常方向:
|
|
第四步:开启丢包检测
指定 --with-dropwatch 后,tcpshark 会加载本机丢包检测功能并自动关联,当前丢包是否由于丢包引起。
|
|
接入 huatuo
除命令行临时采集外,还可通过 huatuo-bamai 持续观测物理机和容器中的 TCP 重传。在 huatuo-bamai 中配置过滤条件、TLP 采集和事件限速:
|
|
tcp_retransmit tracer 默认位于全局 BlackList。启用前需将其移出并重启 huatuo-bamai。关联分析使用 tcpshark 内置的 dropwatch source,独立的 dropwatch 可继续保留在 BlackList 中;仅在需要单独保存原始丢包事件时启用。
详细参数、字段和分类规则见 tcpshark 使用文档。