☰
Hey压测HTTPS服务:TLS握手开销对延迟的影响及3种快速排除方法
2026/10/4 4:02:21 网站建设 项目流程

Hey压测HTTPS服务:TLS握手开销对延迟的影响及3种快速排除方法

【免费下载链接】heyHTTP load generator, ApacheBench (ab) replacement项目地址: https://gitcode.com/GitHub_Trending/he/hey

hey 是一款轻量级 HTTP 压测工具(ApacheBenchab的现代替代品),原生支持 HTTPS 与 HTTP/2。本文面向新手,讲清楚 hey 压测 HTTPS 服务时,TLS 握手开销如何体现在延迟指标里,以及如何用-disable-keepalive对比法快速量化并排除它对压测结果的影响。

为什么 HTTPS 压测的延迟总是比 HTTP 偏高?

🔐 每建立一条新的 HTTPS 连接,客户端和服务端都要先完成一次TLS 握手:

  1. TCP 三次握手(1 个 RTT)
  2. TLS 握手:TLS 1.2 通常需要 2 个 RTT,TLS 1.3 缩短到 1 个 RTT
  3. 之后才能真正发送 HTTP 请求

也就是说,一条"冷"连接的延迟天然比复用中的连接多出 1~2 个网络往返时间。同机房压测时一次握手大约 2~5ms,跨地域压测则可能到 30~80ms——如果每个请求都新建连接,这部分开销会直接叠加进你的平均延迟。

hey 的延迟分阶段指标:看懂 "DNS+dialup"

hey 用httptrace给每个请求做分阶段埋点(见 requester/requester.go),最终报告里包含 5 个阶段的平均值、最快值和最慢值:

阶段指标含义是否包含 TLS 握手
DNS+dialupDNS 解析 + TCP 建连 + TLS 握手(仅新连接)✅ 核心指标
DNS-lookup仅 DNS 解析耗时❌
req write写完整请求的耗时❌
resp wait从发完请求到收到首字节的等待❌(服务端响应时间)
resp read读完响应体的耗时❌

默认报告模板定义在 requester/print.go。这里有一个新手最容易踩的坑:DNS+dialup只在连接未被复用时才被计时(requester/requester.go 中if !connInfo.Reused的判断)。hey 默认开启 keep-alive,连接会被反复复用,所以大多数请求的握手开销被"摊销"掉了,DNS+dialup平均值会显得很小——但这不代表握手不存在,只是没被逐次计入。

另外两点值得了解(见 requester/requester.go):

  • hey 默认设置InsecureSkipVerify: true,跳过 TLS 证书校验——压测时不会因自签证书报错,但 hey 的结果不能用于验证证书有效性;
  • 每主机的空闲连接池上限是min(并发数, 500),并发-c超过 500 后会有连接频繁新建,额外触发握手。

3 条命令测出 TLS 握手开销(对比法)

💡 核心思路:其他条件完全一致,只切换"是否复用连接",两组DNS+dialup平均值的差,就近似等于单次 TLS+TCP 握手开销。

第 1 步:默认 keep-alive 压测(握手被摊销,代表真实用户场景)

hey -n 1000 -c 50 https://api.example.com

第 2 步:加-disable-keepalive,每个请求都新建连接(完整暴露握手开销)

hey -n 1000 -c 50 -disable-keepalive https://api.example.com

该参数的说明见 hey.go:禁用 keep-alive 后,不同请求之间不再复用 TCP 连接。

第 3 步:对比两组的 DNS+dialup 平均值,差值 ≈ 一次握手耗时

下面是一份示例输出(本地测试环境的典型量级,供参考):

指标keep-alive(默认)-disable-keepalive差值
DNS+dialup 平均0.0002s0.0031s≈ 3ms / 次握手
resp wait 平均0.0048s0.0052s基本不变

可以看出:关闭复用后resp wait(服务端响应时间)几乎没变,涨的全是建连阶段——这就是 TLS 握手开销的"指纹"。

如需逐请求数据做进一步分析,用-o csv导出(字段说明见 requester/print.go):

hey -n 1000 -c 50 -z 30s -o csv -disable-keepalive https://api.example.com > tls_off.csv

CSV 第 2 列DNS+dialup就是每次请求的连接建立耗时,可以自行统计分位数。

4 种降低 TLS 握手对延迟影响的方法

  1. ✅ 保持默认 keep-alive,让连接复用摊销握手成本。压测时不要随手加-disable-keepalive,它只用于量化握手开销本身。
  2. ⚡ 用-h2启用 HTTP/2 多路复用。一条 TLS 连接上可以跑多个并发流,握手次数从"每连接 1 次"降为接近"每 worker 1 次":
    hey -h2 -n 1000 -c 50 https://api.example.com
  3. 📊 用-z定时压测,让请求量足够大。例如-z 30s持续压测,握手只发生在起步阶段,占比自然摊薄;同时对比实验要固定-c与压测时长,保证两组可比。
  4. 🌐 缩短握手 RTT。把压测机部署到与目标同机房(跨地域 RTT 会线性放大握手成本);服务端升级到TLS 1.3(1-RTT 握手),并确保持有足够空闲连接池(-c ≤ 500时每个 worker 可稳定持有空闲连接)。

安装 hey 与延伸阅读

通过 git 克隆源码构建:

git clone https://gitcode.com/GitHub_Trending/he/hey

安装与构建方式详见 README.md 和 Makefile。本文涉及的核心文件:

  • 命令行参数定义(-disable-keepalive、-h2、-o csv等):hey.go
  • TLS 配置、连接池与 HTTP/2 开关:requester/requester.go
  • 分阶段计时埋点逻辑:requester/requester.go
  • 默认报告模板与 CSV 字段:requester/print.go
  • 更多命令示例:README.md

掌握"DNS+dialup 对比法"后,你再用 hey 压测 HTTPS 服务时,就能一眼分清:慢在握手,还是慢在服务本身。

【免费下载链接】heyHTTP load generator, ApacheBench (ab) replacement项目地址: https://gitcode.com/GitHub_Trending/he/hey

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询