
Hey HTTP压测工具TLS配置完整源码解析http.Transport三个开关如何协同工作【免费下载链接】heyHTTP load generator, ApacheBench (ab) replacement项目地址: https://gitcode.com/GitHub_Trending/he/heyhey是一个轻量级的 HTTP 负载生成器load generator常用作 ApacheBenchab的替代品。本文带你深入它压测 HTTPS 服务的核心逻辑http.Transport上的三个关键开关——TLS 证书验证、协议升级和连接复用它们如何协同决定每一次请求的连接行为。先认识 hey一个为压测而生的小工具hey 的设计极简指定并发数、请求数向目标 URL 发起批量请求然后输出一份包含延迟分布、百分位、每秒请求数的统计报告。hey -n 1000 -c 100 https://your-service.com当目标服务是 HTTPS 时请求链路必然经过TLS 握手。hey 对这条链路的控制全部集中在构建http.Transport的那一小段代码里。三个开关在哪里Transport 构建位置所有 TLS 相关配置都位于 requester/requester.go 的runWorkers()方法中tr : http.Transport{ TLSClientConfig: tls.Config{ InsecureSkipVerify: true, ServerName: b.Request.Host, }, MaxIdleConnsPerHost: min(b.C, maxIdleConn), DisableCompression: b.DisableCompression, DisableKeepAlives: b.DisableKeepAlives, Proxy: http.ProxyURL(b.ProxyAddr), } if b.H2 { http2.ConfigureTransport(tr) } else { tr.TLSNextProto make(map[string]func(string, *tls.Conn) http.RoundTripper) }短短十几行藏着三个可以独立拨动、又互相影响的开关。开关一InsecureSkipVerify —— 压测工具为什么要跳过证书验证第一个开关位于TLSClientConfig内部由两个字段组成requester/requester.goInsecureSkipVerify: true—— 跳过服务端证书的有效性校验过期证书、自签名证书、域名不匹配都能通过ServerName: b.Request.Host—— 仍然把请求的 Host 作为 SNI 发给服务端这是一个非常典型的压测工具式组合两者看似矛盾实则互补字段作用压测场景的意义InsecureSkipVerify不校验证书真伪测试环境常用自签名证书不能因为证书问题导致压测失败ServerName发送正确的 SNI同一个 IP 上跑了多个 HTTPS 站点时服务端靠 SNI 路由到正确的虚拟主机和证书关键点跳过验证 ≠ 放弃 SNI。如果连 SNI 都不发多站点部署的服务会返回默认站点的证书甚至拒绝连接压测结果就失真了。hey 同时设置这两个字段保证证书不挑但身份要说清楚。开关二TLSNextProto —— 控制 TLS 层是否升级到 HTTP/2第二个开关决定 TLS 握手完成后说哪种话。Go 的 HTTP 客户端默认会在 TLS 的 ALPN 协商中尝试升级到 HTTP/2而 hey 通过-h2命令行标志定义于 hey.go来控制这件事加-h2调用http2.ConfigureTransport(tr)注入 HTTP/2 传输层TLS 握手时通过 ALPN 协商h2协议不加-h2把tr.TLSNextProto设为一个非 nil 的空 map这正是 Go 标准库约定的禁用自动升级写法TLS 连接将停留在 HTTP/1.1为什么对压测重要HTTP/2 的多路复用意味着一个连接可以同时跑多个请求服务端资源消耗模式和 HTTP/1.1 完全不同。测试时必须明确测的是哪种协议否则结果没有可比性。hey 把默认值定为 HTTP/1.1、需要显式开启 HTTP/2避免用户无意间测出偏差结果。开关三DisableKeepAlives —— 连接复用还是每请求重建第三个开关直接改变压测的压力形态requester/requester.go默认keep-alive 开启TCP 连接含已建立的 TLS 连接会被放入空闲池复用。同时MaxIdleConnsPerHost被设为min(b.C, 500)即空闲连接数不超过并发数也不超过上限 500加-disable-keepalive每个请求结束后立即关闭连接。下一轮请求要重新走完整的 DNS → TCP 握手 → TLS 握手这个开关让 hey 可以模拟两种截然不同的真实场景长连接场景浏览器、移动端 App连接复用延迟低服务端连接池压力大短连接场景某些 API 网关、爬虫流量每请求一次完整握手TLS 握手开销被摊进每个请求的延迟里配合 requester/print.go 报告模板中的DNSdialup指标连接建立耗时含 TLS 握手你可以直观看到两种模式下连接开销的差异。三个开关如何协同一张连接生命周期图把三个开关组合起来一次 HTTPS 请求的连接生命周期是这样的┌─────────────────────────────────────────────────────────┐ │ 请求发起 │ │ │ │ │ ▼ │ │ 连接池里找空闲连接 ──找到──► 直接发请求跳过下面两步 │ │ │未找到 keep-alive 开启时走这条快路径 │ │ ▼ │ │ TCP 握手 → TLS 握手 │ │ │ · ServerName 决定发送哪个 SNI ← 开关一 │ │ │ · ALPN 协商 h2 或 http/1.1 ← 开关二 │ │ │ · 证书不校验自签名也放行 ← 开关一 │ │ ▼ │ │ 发送请求 → 读取响应 │ │ ▼ │ │ keep-alive 开──是──► 连接回池等下一个请求复用 │ │ └─否──► 立即关闭连接 ← 开关三│ └─────────────────────────────────────────────────────────┘协同逻辑可以概括为三句话开关一管能不能连自签名证书环境下保证握手不会因为证书问题失败开关二管连上之后说什么协议HTTP/1.1 与 HTTP/2 的资源模型完全不同必须显式指定开关三管用完之后怎么办复用则摊薄握手成本关闭则把完整握手成本计入每个请求三者共同决定了压测报告中 Requests/sec、平均延迟和DNSdialup三项核心指标的形状。快速上手用 hey 观察三个开关的效果安装后可直接对照运行参考 README.md# 基线HTTP/1.1 连接复用默认组合 hey -n 500 -c 50 https://staging.example.com # 短连接模式观察 DNSdialup 指标如何被 TLS 握手成本抬高 hey -n 500 -c 50 -disable-keepalive https://staging.example.com # HTTP/2 模式观察多路复用下的延迟分布变化 hey -n 500 -c 50 -h2 https://staging.example.com对比三组输出中的Latency distribution百分位延迟和DNSdialup连接建立耗时就能亲眼看到每个开关拨动后连接层行为的不同。常见问题FAQQ1InsecureSkipVerify: true是不是很危险对压测工具而言是合理设计——它只影响 hey 客户端本地是否校验证书不影响服务端安全。但要注意这意味着 hey 无法帮你发现证书过期问题生产巡检请配合专门的证书检查工具。Q2为什么默认不开 HTTP/2保持与 ApacheBench 等工具的可比性。HTTP/2 需要服务端和客户端双方支持显式-h2开启能避免以为在测 HTTP/2实际协商成了 HTTP/1.1的隐蔽偏差。Q3并发数很高时空闲连接池会撑爆内存吗不会。MaxIdleConnsPerHost: min(b.C, 500)把空闲连接上限同时约束在并发数和 500 之内见 requester/requester.go。总结hey 在十几行代码里用一个http.Transport加三个开关就覆盖了压测 HTTPS 服务时的全部关键变量证书信任策略、协议版本选择、连接生命周期管理。理解了 requester/requester.go 这一段你就不仅会用 hey 压测还能看懂压测报告里每个延迟指标背后连接层到底发生了什么。【免费下载链接】heyHTTP load generator, ApacheBench (ab) replacement项目地址: https://gitcode.com/GitHub_Trending/he/hey创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考