如何使用Grafana k6进行明文HTTP/2(h2c)负载测试
用k6生成h2c流量的方法
k6原生HTTP模块确实没有直接提供h2c支持,但可以通过两种可行方案实现这类测试:
方案1:自定义Go扩展(推荐用于稳定性能测试)
k6支持用Go编写扩展,你可以基于Go标准库实现h2c客户端逻辑:
- 编写Go扩展代码,配置
http2.Transport并开启AllowHTTP: true,以此创建支持h2c的HTTP客户端 - 将扩展编译为k6插件,在测试脚本中调用扩展提供的API发起h2c请求
示例核心Go代码片段:
package h2cext import ( "io" "net" "net/http" "golang.org/x/net/http2" ) func NewH2CClient() *http.Client { transport := &http2.Transport{ AllowHTTP: true, DialTLS: func(network, addr string, cfg *tls.Config) (net.Conn, error) { // h2c无需TLS,直接建立TCP连接 return net.Dial(network, addr) }, } return &http.Client{Transport: transport} } // 导出供k6调用的GET方法 func H2CGet(url string) (string, error) { client := NewH2CClient() resp, err := client.Get(url) if err != nil { return "", err } defer resp.Body.Close() body, _ := io.ReadAll(resp.Body) return string(body), nil }
编译插件后,在k6脚本中导入并调用h2cext.H2CGet()即可发起h2c请求。
方案2:利用experimental.http模块(快速验证场景)
k6的experimental.http模块支持底层TCP连接操作,可手动构造h2c升级流程:
- 建立TCP连接后,发送携带
Connection: Upgrade和Upgrade: h2c头部的HTTP/1.1请求 - 确认服务器返回
101 Switching Protocols响应后,在同一连接上构造HTTP/2帧发送请求
示例k6脚本片段:
import { experimental } from 'k6/http'; export default function () { // 连接目标内网服务 const conn = experimental.http.connect('your-service:8080'); // 发送h2c升级请求 const upgradeReq = 'GET /api/test HTTP/1.1\r\nHost: your-service\r\nConnection: Upgrade\r\nUpgrade: h2c\r\n\r\n'; conn.write(upgradeReq); // 验证升级响应 const resp = conn.read(); if (resp.includes('101 Switching Protocols')) { // 需手动构造符合HTTP/2规范的请求帧(需熟悉HTTP/2协议格式) const h2RequestFrame = ...; conn.write(h2RequestFrame); const h2Resp = conn.read(); console.log('h2c响应内容:', h2Resp); } conn.close(); }
此方案需要了解HTTP/2帧结构,适合快速验证h2c通信可行性,不建议用于大规模性能测试。
注意事项
- 需确保目标服务确实支持h2c,否则升级请求会失败
- 大规模性能测试优先选择方案1,手动构造HTTP/2帧效率低且易出错
- 当前k6官方 roadmap 暂无原生支持h2c的计划,自定义扩展是最稳定的实现方式
内容的提问来源于stack exchange,提问作者Adam Z
相关产品推荐
相关产品推荐

