用 AI 压 gRPC 与 HTTP 接口:ghz、k6 与结果解读

gRPC 压测绕不开 ghz:它直接用 .proto 描述文件发起调用,不需要你写客户端代码,参数与输出都是纯文本,正好适合贴给 AI 解读。HTTP 接口交给 k6 或 wrk。真正费时间的不是发压,而是看懂输出——平均值好看、P99 难看,是这两个协议压测里最常见的翻车方式。

一、ghz 常用参数

参数含义使用要点
--proto / --import-pathsproto 文件与依赖的搜索目录依赖其他 proto 时不补 import 路径会报找不到类型
--call方法全名,如 pkg.Service/Method必须带包名;写错会报 method not found,而非参数错误
-c并发数(并发 worker)与 --rps 分开调:先定速率看能否达成,再加并发看延迟
--rps目标速率上限(每秒请求数)设 0 表示不限速;此时实际速率由 -c 与服务端延迟共同决定
-n / -z总请求数 / 持续时间短测用 -n,稳态与稳定性场景用 -z 5m 便于对齐时间轴
-d / -m请求体 JSON / metadata(鉴权头)结构复杂先本地验证;token 过期会导致中段大量失败
--insecure明文连接,不做 TLS仅内网压测用;要评估 TLS 开销就补一次不带它的对照
-O / --format输出格式:summary / json / csv / html要画每秒请求数曲线就导出 json 或 csv,别只看 summary

二、压 gRPC

# 1) 先用 grpcurl 确认方法和参数都对,再上 ghz
grpcurl -plaintext -d '{"uid":"u-1"}' -H 'authorization: Bearer dev-token' \
  10.0.0.12:9090 im.v1.UserService/Get
# 2) 定速率压测:8000 QPS、并发 200、持续 5 分钟,导出 JSON 供后续分析
ghz --insecure --proto ./proto/user.proto --import-paths ./proto \
  --call im.v1.UserService/Get -d '{"uid":"u-1001"}' -m '{"authorization":"Bearer <token>"}' \
  --rps 8000 -c 200 -z 5m --timeout 3s -O json -o ghz-user.json 10.0.0.12:9090
# 3) 找拐点:不限速,只加并发,每档跑 2 分钟
for c in 50 100 200 400 800; do
  ghz --insecure --proto ./proto/user.proto --call im.v1.UserService/Get -d '{"uid":"u-1001"}' \
    --rps 0 -c $c -z 2m -O summary 10.0.0.12:9090 | tee "ghz-c$c.txt"
  sleep 60
done
Summary:
  Count:        2400000      Total:        300.12 s
  Slowest:      482.11 ms    Fastest:      0.42 ms
  Average:      6.85 ms      Requests/sec: 7996.80

Latency distribution:
  50 % in 4.78 ms      <- 中位数
  95 % in 18.02 ms
  99 % in 61.44 ms     <- 长尾,体感问题在这里

Status code distribution:
  [OK] 2399811 responses    [DeadlineExceeded] 189 responses

关键读法:Average 6.85ms 而 P99 61.44ms,说明约 1% 的请求在排队或遇到锁竞争;Requests/sec 7996.80 略低于目标 --rps 8000,加上 189 条 DeadlineExceeded,要看超时是否集中在某一时段而不是均匀分布。

三、压 HTTP 接口

# k6:恒定到达率,请求体与鉴权按接口实际情况替换
k6 run -e BASE=http://10.0.0.12:8080 -e TOKEN="$T" --summary-export=http-summary.json bench/http-get.js
# wrk:吞吐基线快照,配 Lua 脚本做参数化
wrk -t8 -c400 -d120s --latency -s bench/get.lua http://10.0.0.12:8080/api/v1/items
-- bench/get.lua:每个请求换一个 id,避免单热点把结论带偏
local counter = 0
request = function()
  counter = counter + 1
  return wrk.format("GET", "/api/v1/items/" .. (counter % 100000),
    { ["Authorization"] = "Bearer " .. (counter % 200) })
end

k6 按分位与阈值给结论,适合进流水线;wrk 输出分位较少但吞吐更高,适合做压测机能力快照。两者都要记录压测机自身的 CPU:wrk 线程数超过物理核数时,瓶颈就在压测机。

四、让 AI 解读结果

角色:性能分析师。下面是一次 gRPC 压测的完整输出与背景,只解读,不要重写脚本。
背景:单实例 4C8G;接口逻辑 = 先查 Redis,未命中查 MySQL;压测机 8C16G 独立节点;
      目标 = 8000 QPS,P99 < 100ms,错误率 < 0.1%;压测期间服务端 CPU 62%,GC 暂停累计 1.2s。
原始输出:
  <粘贴 ghz 的 summary 或 json 统计段>
要求:
  1) 分别解读平均值与 P99,说明两者差距指向哪类问题(排队、锁竞争、GC、下游慢)
  2) 列出错误码分布,逐类给出可能原因与下一步验证动作
  3) 判断每秒请求数是否平稳,给出判断依据,并说明还需要哪些数据才能确认
  4) 每条结论标明是「数据支持」还是「需要补充采集」,并写出这次压测回答不了的问题

第 4 条是让 AI 解读压测数据时的安全绳:压测数据很少具备充分的因果证据,要求它区分「数据支持」与「需要补充采集」,能挡掉大部分自信但错误的因果断言。

五、读结果的三条规则

观测项判读典型误判
平均 vs P99平均正常、P99 陡增 → 少量请求排队,查锁、GC、下游抖动「平均才 7ms,没问题」,掩盖 1% 用户的糟糕体感
错误码分布4xx 多半是脚本问题,5xx 是服务问题,超时可能来自下游或压测机把 401 集中爆发当成服务端不稳
每秒请求数曲线导出 json/csv 后按秒聚合,看是否平稳、是否随加压阶梯同步下降只看总 Requests/sec 平均值,忽略中途掉速

六、protobuf 与 JSON 的体积差异

对比项protobufJSON影响
字段名只传字段号(1~2 字节)每次传完整键名小消息下键名占大头,差距 2~5 倍
类型与定界类型由 .proto 描述,长度前缀定界靠文本字面量与引号逗号字段越多,JSON 冗余越明显
压缩后体积gzip 后差距收窄到 1.5~2 倍压缩率通常更高带宽受限时先比压缩后体积
解析成本二进制解析,无字符串扫描需要词法解析高 QPS 下 JSON 的 CPU 开销不可忽略
protoc --encode=im.v1.Msg ./proto/im.proto < msg.json | wc -c  # protobuf 字节数
wc -c < msg.json                                               # JSON 字节数
# 比较两者的延迟:ghz 用 -d 传 JSON,或写死二进制用 -b 传文件

体积要换算到吞吐才有意义:单条省 100 字节,10 万 QPS 下就是约 10 MB/s 的出口带宽差,这才是压测报告里该出现的数字。

常见坑

坑现象做法
-c 与 --rps 一起无脑加大分不清瓶颈在速率还是排队先定 --rps 看能否达成,再单独调 -c 观察延迟
用 --insecure 得出延迟结论报告里少了 TLS 握手与加密成本标注是否启用 TLS,涉及线上容量时补对照
只导出 summary拿不到每秒请求数曲线-O json 或 -O csv 导出原始样本再按秒聚合
压测前不预热、token 中途过期P99 被冷启动拉高,中段 401 爆发被当成服务劣化丢弃前 30 秒数据,压测时长与 token 有效期对齐
忽略响应体校验服务端返回业务错误码仍计入成功断言业务码,HTTP 200 不等于成功

小结:gRPC 用 ghz,先 grpcurl 校验方法与参数,再用 --proto、--call、-c、--rps、-z、-O json 组成命令,-c 与 --rps 分开调才能分清是速率不够还是排队;HTTP 用 k6 做带阈值的场景回归、用 wrk 做吞吐快照。解读结果时死守三条规则——平均与 P99 分开看、错误码按类归因、每秒请求数按秒画曲线;给 AI 的提示词里要求它区分「数据支持」与「需要补充采集」,比让它直接下因果结论安全得多。跨协议的对照数值与 IM 场景参数可参考 im-system 目录第 26 章。

笔记加载中…