0

0

解析Golang中的gRPC性能基准测试方法 Go语言对比不同并发下的吞吐

P粉602998670

P粉602998670

发布时间:2026-03-13 16:05:02

|

430人浏览过

|

来源于php中文网

原创

结论:ghz 更贴近真实服务压测场景,go test -bench 只适合测单个函数或客户端 stub 调用开销;前者走真实 HTTP/2 连接、模拟网络栈与流控,后者不建连接、复用 conn、忽略 TLS/序列化等开销,结果无法反映线上 QPS。

解析golang中的grpc性能基准测试方法 go语言对比不同并发下的吞吐

gRPC 基准测试该用哪个工具:ghz 还是 go test -bench

直接说结论:ghz 更贴近真实服务压测场景,go test -bench 只适合测单个函数或客户端 stub 调用开销。别拿 go test -bench 的结果去推断线上 QPS——它不走网络栈、不建真实连接、默认复用 grpc.ClientConn,测出来的是“理想裸调用”,不是“并发请求吞吐”。

常见错误现象:go test -bench=. 显示 50k req/s,但用 ghz 一压,20 并发就卡在 800 QPS,CPU 没打满,延迟飙升。原因就是前者没模拟连接建立、TLS 握手、流控、序列化反序列化等真实路径。

  • ghz 是命令行工具,走真实 HTTP/2 连接,支持并发控制、持续时长、QPS 限制、TLS 配置,输出含 p90/p99 延迟、错误率、吞吐趋势
  • go test -bench 适合定位瓶颈:比如对比 proto.Marshal vs json.Marshal 开销,或测试自定义 Codec 实现的序列化耗时
  • 如果你要对比“不同并发数下的吞吐变化”,必须用 ghz 或自己写带连接池和并发控制的压测 client,否则数据无参考价值

并发数设置不对,ghz 测出来的吞吐就是假的

很多人跑 ghz --concurrency 100 就以为是 100 并发请求,其实不是:默认 ghz 会为每个 goroutine 复用一个 grpc.ClientConn,而 gRPC 默认对每个 ClientConn 最多只建 100 个 HTTP/2 stream(受 MaxConcurrentStreams 控制)。所以 100 并发下,如果服务器端也设了 MaxConcurrentStreams: 100,实际可能只有不到 100 个请求真正并行。

使用场景:你想看“从 10 并发到 500 并发,吞吐如何变化”,就得确保客户端和服务端都不成为瓶颈。

立即学习go语言免费学习笔记(深入)”;

  • 客户端侧:加 --connections 10 让 ghz 创建 10 个独立连接,再分摊 100 并发,避免单连接 stream 耗尽
  • 服务端侧:检查 grpc.ServerOption 是否显式设置了 grpc.MaxConcurrentStreams(1000),没设的话默认是 100
  • 还要确认服务端 OS 层的文件描述符限制:ulimit -n 至少大于 connections × streams_per_conn + 其他服务开销,否则会报 accept: too many open files

Go 客户端里手动写 benchmark,怎么避免常见陷阱

真要写 go test -bench 测 gRPC 调用,最容易踩的坑是“没重用 conn”和“没清空 context”。每次 grpc.Dialcontext.WithTimeout 都是开销,测出来的是创建成本,不是调用成本。

PPT.AI
PPT.AI

AI PPT制作工具

下载

参数差异:用 grpc.WithTransportCredentials(insecure.NewCredentials()) 替代 TLS,避免加密耗时干扰;用 grpc.WithBlock() 确保 Dial 同步完成,否则 bench 会因连接未就绪而失败。

  • BenchmarkXXX 函数外初始化 *grpc.ClientConn 和 client stub,bench 内只做 client.Method(ctx, req)
  • 每次请求必须用新 context.WithTimeout,但别在循环里反复 time.Now() —— 直接用 ctx, cancel := context.WithTimeout(context.Background(), 10*time.Millisecond),结束后 cancel()
  • 如果测流式接口,注意 Recv() 调用次数和是否真的触发了多次网络往返,建议用 io.Copy(ioutil.Discard, stream) 模拟消费,而不是只调一次 Recv()

吞吐下降拐点背后,往往是 HTTP/2 流控或 Go runtime 调度问题

当你看到并发从 200 升到 300,QPS 不升反降、p99 延迟跳变,别急着怪业务逻辑——先查两个地方:http2.Transport.MaxConcurrentStreams 和 Go 的 GOMAXPROCS 设置。

性能影响:gRPC 默认用 http2.Transport,其 MaxConcurrentStreams 默认是 100;而 Go 1.21+ 默认 GOMAXPROCS 是 CPU 核心数,如果压测机只有 4 核,但启了 500 goroutine,调度器争抢严重,大量时间花在 parked goroutine 唤醒上,不是花在处理请求上。

  • 客户端改 http2.Transport:通过 grpc.WithTransportCredentials(credentials.TransportCredentials(...)) 包一层自定义 transport,并设置 MaxConcurrentStreams 到 1000+
  • 压测机上临时设 GOMAXPROCS=16(根据 CPU 逻辑核数调整),再跑 ghz,对比吞吐变化
  • go tool trace 抓一次压测过程,看 Proc 状态是否长期 IdleRunning 时间碎片化,这是调度瓶颈的明确信号

真实压测中,连接复用策略、流控窗口、Go 调度器、甚至 DNS 解析缓存都会成为隐性瓶颈。数据波动大时,先盯住 ghz 输出里的 error rate 和 latency 分布,比盯着平均 QPS 有用得多。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
golang如何定义变量
golang如何定义变量

golang定义变量的方法:1、声明变量并赋予初始值“var age int =值”;2、声明变量但不赋初始值“var age int”;3、使用短变量声明“age :=值”等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

211

2024.02.23

golang有哪些数据转换方法
golang有哪些数据转换方法

golang数据转换方法:1、类型转换操作符;2、类型断言;3、字符串和数字之间的转换;4、JSON序列化和反序列化;5、使用标准库进行数据转换;6、使用第三方库进行数据转换;7、自定义数据转换函数。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

247

2024.02.23

golang常用库有哪些
golang常用库有哪些

golang常用库有:1、标准库;2、字符串处理库;3、网络库;4、加密库;5、压缩库;6、xml和json解析库;7、日期和时间库;8、数据库操作库;9、文件操作库;10、图像处理库。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

356

2024.02.23

golang和python的区别是什么
golang和python的区别是什么

golang和python的区别是:1、golang是一种编译型语言,而python是一种解释型语言;2、golang天生支持并发编程,而python对并发与并行的支持相对较弱等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

214

2024.03.05

golang是免费的吗
golang是免费的吗

golang是免费的。golang是google开发的一种静态强类型、编译型、并发型,并具有垃圾回收功能的开源编程语言,采用bsd开源协议。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

409

2024.05.21

golang结构体相关大全
golang结构体相关大全

本专题整合了golang结构体相关大全,想了解更多内容,请阅读专题下面的文章。

490

2025.06.09

golang相关判断方法
golang相关判断方法

本专题整合了golang相关判断方法,想了解更详细的相关内容,请阅读下面的文章。

201

2025.06.10

golang数组使用方法
golang数组使用方法

本专题整合了golang数组用法,想了解更多的相关内容,请阅读专题下面的文章。

1479

2025.06.17

TypeScript类型系统进阶与大型前端项目实践
TypeScript类型系统进阶与大型前端项目实践

本专题围绕 TypeScript 在大型前端项目中的应用展开,深入讲解类型系统设计与工程化开发方法。内容包括泛型与高级类型、类型推断机制、声明文件编写、模块化结构设计以及代码规范管理。通过真实项目案例分析,帮助开发者构建类型安全、结构清晰、易维护的前端工程体系,提高团队协作效率与代码质量。

26

2026.03.13

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Go 教程
Go 教程

共32课时 | 6.2万人学习

Go语言实战之 GraphQL
Go语言实战之 GraphQL

共10课时 | 0.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号