Linux无现成命令直接查连接耗时,需结合ss识别异常状态、conntrack发现启动失败连接、tcpdump计算SYN到SYN-ACK时间差,或依赖应用层日志获取真实建连耗时。

Linux 没有现成的“连接耗时分布表”命令,ss、conntrack、tcpdump 都不直接记录单个连接的建立/关闭耗时。所谓“连接耗时”,必须靠间接手段推断或主动埋点——别指望 ss -ant 输出里带个 connect_time_ms 字段。
ss 无法查连接建立耗时,但能筛出卡住的残留状态
很多人误以为 ss 能看“连接用了多久”,其实它只显示当前状态和 socket 元信息,不存时间戳。真正可操作的是:识别那些本该快速结束却长期滞留的状态,它们就是耗时异常的信号。
-
ss -ant state time-wait:TIME_WAIT 默认持续 60 秒(由net.ipv4.tcp_fin_timeout控制),大量存在说明服务端频繁主动断连,可能配置了过短的 keepalive 或 client 端未复用连接 -
ss -ant state close-wait:表示对端已 FIN,本端还没调close(),常见于程序没正确处理 EOF 或异常退出后 socket 泄漏 -
ss -ant state syn-sent或syn-recv:SYN 发出后没回 ACK,或三次握手卡在中间,指向网络丢包、防火墙拦截、目标端口未监听
conntrack 表里没有连接耗时字段,但能暴露连接生命周期异常
conntrack -L 输出每条记录含 [ASSURED] 或 [UNREPLIED] 标记,后者表示只收到 SYN 没等到 ACK+SYN-ACK,本质是连接“启动失败”,其存在本身就意味着某次连接尝试卡在 0ms~几秒之间——虽然你不知道具体多少毫秒,但知道它根本没成功。
- 大量
[UNREPLIED]条目:检查是否被 iptables DROP、目标主机不可达、或 SYN Flood 攻击触发 conntrack 限速 - 同一 src/dst 对反复新建又消失:用
sudo conntrack -E | grep "192.168.1.100"实时捕获,确认是重试行为还是瞬时连接风暴 - 连接数接近
/proc/sys/net/netfilter/nf_conntrack_max:新连接会因等待 conntrack slot 而延迟,表现为“连接慢”,实际是资源瓶颈
真要测 TCP 建连耗时,得用 tcpdump + 时间戳计算
这是唯一能拿到真实毫秒级建连耗时的方法,但必须在连接发起侧抓包,且需人工或脚本解析。
- 在客户端执行:
sudo tcpdump -i any -nn port 80 -w connect.pcap && curl -s http://target/ && kill %1 - 用
tshark -r connect.pcap -Y 'tcp.flags.syn==1 and tcp.flags.ack==0' -T fields -e frame.time_epoch提取 SYN 时间 - 再查对应 SYN-ACK 的
frame.time_epoch,相减即为建连耗时(单位秒,小数点后六位) - 注意:若目标在 NAT 后或走负载均衡,SYN-ACK 可能来自中间设备而非真实服务端,结果失真
应用层日志才是最准的连接耗时来源
内核工具只能看到 socket 层行为,而业务关心的“连接耗时”往往指从代码调用 connect() 到返回成功的时间——这必须靠应用自己打日志。
- Go 程序可设
net.Dialer.Timeout并记录time.Since(start) - Java 用
Socket.connect(sockAddr, timeout)包裹 try-catch,捕获ConnectException并记时 - Nginx 的
$upstream_connect_time变量直接输出 upstream 建连耗时(毫秒级,需开启log_format定义)
绕开应用日志去问内核要“连接耗时”,就像问交通摄像头要“司机从家出发到上车用了几分钟”——它只拍下车牌和路口通过时间,出发时刻不在它的视野里。


















