最准确方式是用openssl s_client逐版本强制握手并计时:需指定-tls1_2/-tls1_3、-no_ticket、-sess_out /dev/null和-brief,观察real耗时;tlsv1.3通常120–350ms,tlsv1.2为200–600ms,反超则需确认是否真协商成功。

直接用 openssl s_client 分版本发起真实握手并计时,是最准确、可复现的方式。Nginx 本身不暴露“握手耗时”变量,也不能跨版本自动对比;必须由客户端主动控制协议版本,逐次测量,排除缓存和复用干扰。
用 openssl s_client 逐版本测握手时间
核心是强制指定 TLS 版本,并用 time 捕获完整连接建立耗时(含 TCP + TLS)。注意每次测试前清空会话缓存,避免复用掩盖真实开销:
- 测 TLSv1.2:
time openssl s_client -connect example.com:443 -servername example.com -tls1_2 -cipher 'ECDHE-ECDSA-AES128-GCM-SHA256' -brief 2>/dev/null - 测 TLSv1.3:
time openssl s_client -connect example.com:443 -servername example.com -tls1_3 -ciphersuites 'TLS_AES_128_GCM_SHA256' -brief 2>/dev/null - 关键参数说明:
-brief减少输出干扰;-cipher或-ciphersuites锁定单一套件,确保版本间对比公平;-servername必须带上,否则可能绕过 SNI 导致降级
排除会话复用干扰
默认情况下,openssl 会尝试复用上一次会话,导致第二次耗时极低,无法反映首次握手差异。需显式禁用:
- 加
-no_ticket禁用 Session Ticket 复用 - 加
-sess_out /dev/null防止写入会话缓存 - 推荐完整命令:
time openssl s_client -connect example.com:443 -servername example.com -tls1_2 -no_ticket -sess_out /dev/null -brief 2>/dev/null
对比结果看什么
关注终端输出的 real 时间(非 user/sys),它代表从发起连接到收到 ServerHello 的总耗时。典型差异规律:
- TLSv1.2:通常 2–4 次往返(RTT),实测多在 200–600ms(取决于网络延迟)
- TLSv1.3:1-RTT 标准握手,或 0-RTT(若客户端有缓存票据),实测常为 120–350ms
- 若 TLSv1.3 耗时反超,需检查是否真协商成功——确认输出中有 New, TLSv1.3 和 Cipher is TLS_AES_128_GCM_SHA256,而非回退到 TLSv1.2
辅助验证:用 curl 看 appconnect 时间
作为交叉参考,curl 的 %{time_appconnect} 包含 DNS + TCP + TLS 全流程,适合批量采样:
- 运行:
curl -w "appconnect: %{time_appconnect}\n" -o /dev/null -s https://example.com - 多次执行取中位数,比对开启/关闭 TLSv1.3 配置后的变化
- 注意:该值受 DNS 缓存影响,建议加
--resolve example.com:443:IP绕过











