网络栈调优98 条

TLS 握手延迟测量

用 openssl s_client 观察握手过程与协商结果, 结合 time 命令量化握手开销。

什么是 TLS 握手延迟测量

TLS 握手要在 TCP 建连之后再交换证书并协商密钥,因此比裸 TCP 多出若干往返。用 openssl s_client 可以观察握手的完整输出(协议版本、加密套件、证书链),配合 time 命令量化耗时;把会话导出再导入,则可以对比全握手与会话复用(session resumption)的差异。测量时要区分进程启动开销与真正的握手时间,也要在同地域、同链路上对比才有意义。

基本信息

基本命令openssl s_client -connect <host>:443 -servername <host> -brief
计时time openssl s_client ... < /dev/null
会话复用-sess_out 导出、-sess_in 导入
关注输出协议版本、加密套件、证书验证结果、会话是否复用
影响因素RTT、证书链大小、密钥交换算法、服务端配置
配套curl -w 的 time_connect/time_appconnect 更贴近真实调用

典型使用场景

  • 站点首屏慢:区分 DNS、TCP、TLS 与业务处理各自的耗时
  • 会话复用评估:确认服务端是否支持并能命中复用
  • 加密套件与协议核对:验收安全基线配置是否生效
  • 证书链排查:确认中间证书是否完整、验证是否成功
  • 多地域对比:评估不同出口到同一服务的握手差异

测量与对比

测量与对比
# 基本握手与耗时(-brief 输出精简结果)
time openssl s_client -connect example.com:443 -servername example.com -brief < /dev/null
# 先保存会话,再复用会话,对比两次的握手耗时
openssl s_client -connect example.com:443 -sess_out /tmp/s.pem < /dev/null
openssl s_client -connect example.com:443 -sess_in /tmp/s.pem < /dev/null
# 看各阶段耗时(更贴近应用调用)
curl -sS -o /dev/null -w 'dns=%{time_namelookup} conn=%{time_connect} tls=%{time_appconnect} total=%{time_total}\n' https://example.com

结果判读

现象可能原因下一步
握手耗时约等于 1-2 个 RTT正常范围与同地域基线对比即可
明显高于 RTT 量级证书链过大或算法开销高核对证书链与协商结果
会话复用未命中服务端未开启或不支持检查服务端 TLS 配置
证书验证失败中间证书缺失或时间不符补全链或校准时间
把进程启动开销算进握手时间是常见误差:用 time 命令测的是整个 openssl 进程,多次测量取稳定值更可靠。
不复用会话就断定服务端 TLS 性能不足会得出错误结论:真实业务中连接池与会话复用能显著摊薄握手成本,评估要贴近实际调用方式。

易错点

  • 把进程启动开销算进握手时间,得出握手很慢的错误结论
  • 不复用会话就断定服务端 TLS 性能不足,忽略连接池与复用对实际体验的影响
  • 只测一次就下结论:网络抖动会主导结果,应在不同时间点多次测量取稳定区间
  • 忽略 -servername 参数,导致测到默认虚拟主机或验证失败,结果与实际访问对象不同

数据来源与参考

  • man openssl-s_client
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌