您现在的位置是:亿华云 > 系统运维
让我们一起编写一个接口压测工具
亿华云2025-10-04 00:38:12【系统运维】3人已围观
简介前言前段时间有个项目即将上线,需要对其中的核心接口进行压测;由于我们的接口是 gRPC 协议,找了一圈发现压测工具并不像 HTTP 那么多。最终发现了 ghz 这个工具,功能也非常齐全。事后我在想为啥
前言
前段时间有个项目即将上线,让们需要对其中的起编核心接口进行压测;由于我们的接口是 gRPC 协议,找了一圈发现压测工具并不像 HTTP 那么多。接口
最终发现了 ghz 这个工具,压测功能也非常齐全。工具
事后我在想为啥做 gRPC 压测的让们工具这么少,是起编有什么难点嘛?为了验证这个问题于是我准备自己写一个工具。
特性
前前后后大概花了个周末的接口时间完成了相关功能。
https://github.com/crossoverJie/ptg/
也是压测一个命令行工具,使用起来效果如上图;完整的工具命令如下:
NAME: ptg - Performance testing tool (Go) USAGE: ptg [global options] command [command options] [arguments...] COMMANDS: help, h Shows a list of commands or help for one command GLOBAL OPTIONS: --thread value, -t value -t 10 (default: 1 thread) --Request value, --proto value -proto http/grpc (default: http) --protocol value, --pf value -pf /file/order.proto --fully-qualified value, --fqn value -fqn package.Service.Method --duration value, -d value -d 10s (default: Duration of test in seconds, Default 10s) --request value, -c value -c 100 (default: 100) --HTTP value, -M value -m GET (default: GET) --bodyPath value, --body value -body bodyPath.json --header value, -H value HTTP header to add to request, e.g. "-H Content-Type: application/json" --target value, --tg value http://gobyexample.com/grpc:127.0.0.1:5000 --help, -h show help (default: false)考虑到受众,所以同时支持 HTTP 与 gRPC 接口的让们压测。
做 gRPC 压测时所需的起编参数要多一些:
ptg -t 10 -c 100 -proto grpc -pf /xx/xx.proto -fqn hello.Hi.Say -body test.json -tg "127.0.0.1:5000"比如需要提供 proto 文件的路径、具体的接口请求参数还有请求接口的全路径名称。
目前只支持最常见的压测 unary call 调用,后续如果有需要的工具话也可以 stream。
同时也支持压测时间、次数两种压测方式。站群服务器
安装
想体验度朋友如果本地有 go 环境那直接运行:
go get github.com/crossoverJie/ptg没有环境也没关系,可以再 release 页面下载与自己环境对应的版本解压使用。
https://github.com/crossoverJie/ptg/releases
设计模式
整个开发过程中还是有几个点想和大家分享,首先是设计模式。
因为一开始设计时就考虑到需要支持不同的压测模式(次数、时间;后续也可以新增其他的模式)。
所以我便根据压测的生命周期定义了一套接口:
type ( Model interface { Init() Run() Finish() PrintSate() Shutdown() } )从名字也能看出来,分别对应:
压测初始化 运行压测 停止压测 打印压测信息 关闭程序、释放资源然后在两个不同的模式中进行实现。
这其实就是一个典型的依赖倒置原则。
程序员要依赖于抽象接口编程、不要依赖具体的实现。
其实大白话就是咱们 Java 里常说的面向接口编程;这个编程技巧在开发框架、SDK或是多种实现的业务中常用。
好处当然是显而易见:当接口定义好之后,不同的业务只需要根据接口实现自己的高防服务器业务就好,完全不会互相影响;维护、扩展都很方便。
支持 HTTP 和 gRPC 也是同理实现的:
type ( Client interface { Request() (*Response, error) } )当然前提得是前期的接口定义需要考虑周全、不能之后频繁修改接口定义,这样的接口就没有意义了。
goroutine
另外一点则是不得不感叹 goroutine+select+channel 这套并发编程模型真的好用,并且也非常容易理解。
很容易就能写出一套并发代码:
func (c *CountModel) Init() { c.wait.Add(c.count) c.workCh = make(chan *Job, c.count) for i := 0; i < c.count; i++ { go func() { c.workCh <- &Job{ thread: thread, duration: duration, count: c.count, target: target, } }() } }比如这里需要初始化 N 个 goroutine 执行任务,只需要使用 go 关键字,然后利用 channel 将任务写入。
当然在使用 goroutine+channel 配合使用时也得小心 goroutine 泄露的问题;简单来说就是在程序员退出时还有 goroutine 没有退出。
比较常见的例子就是向一个无缓冲的 channel 中写数据,当没有其他 goroutine 来读取数时,写入的 goroutine 就会被一直阻塞,最终导致泄露。
总结
有 gRPC 接口压测需求的朋友欢迎试用,提出宝贵意见;当然 HTTP 接口也可以。服务器托管
源码地址:https://github.com/crossoverJie/ptg/
很赞哦!(469)
上一篇: 公司和个人选域名方法一样吗?有什么不同?
下一篇: 4、参加域名拍卖会
相关文章
- 小白注册网站域名该怎么办?有什么步骤?
- 聊聊WPF继续响应被标记为已处理事件的方法
- 为什么 Python 的 f-string 可以连接字符串与数字?
- 如何在 ASP.NET Core MVC 5 中处理未知的 Action
- 为了避免将来给我们的个人站长带来的麻烦,在选择域名后缀时,我们的站长最好省略不稳定的后缀域名,比如n,因为我们不知道策略什么时候会改变,更不用说我们将来是否还能控制这个域名了。因此,如果站长不是企业,或者有选择的话,如果不能选择域名的cn类,最好不要选择它。
- 用Python分析14425条死亡公司数据 看十年创业公司消亡史
- 2020年会消亡的4种编程语言
- Go mod 七宗罪,你知道几宗?
- 这个不用多说,不同平台的注册价格不同,且不同平台对域名释放交易的把控与曝光不同,当然价格相对便宜且平台渠道广操作便利的平台最好。
- 程序员不能错过的2021年很重要的11种编程语言