编写一个接口压测工具

简介: 前段时间有个项目即将上线,需要对其中的核心接口进行压测;由于我们的接口是 gRPC 协议,找了一圈发现压测工具并不像 HTTP 那么多。最终发现了 ghz 这个工具,功能也非常齐全。事后我在想为啥做 gRPC 压测的工具这么少,是有什么难点嘛?为了验证这个问题于是我准备自己写一个工具。

特性


前前后后大概花了个周末的时间完成了相关功能。


github.com/crossoverJi…


网络异常,图片无法展示
|


也是一个命令行工具,使用起来效果如上图;完整的命令如下:


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)


考虑到受众,所以同时支持 HTTPgRPC 接口的压测。


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 页面下载与自己环境对应的版本解压使用。




网络异常,图片无法展示
|


github.com/crossoverJi…


设计模式


整个开发过程中还是有几个点想和大家分享,首先是设计模式。


因为一开始设计时就考虑到需要支持不同的压测模式(次数、时间;后续也可以新增其他的模式)。


所以我便根据压测的生命周期定义了一套接口:


type (
  Model interface {
    Init()
    Run()
    Finish()
    PrintSate()
    Shutdown()
  }
) 


从名字也能看出来,分别对应:


  • 压测初始化


  • 运行压测


  • 停止压测


  • 打印压测信息


  • 关闭程序、释放资源


网络异常,图片无法展示
|
网络异常,图片无法展示
|


然后在两个不同的模式中进行实现。


这其实就是一个典型的依赖倒置原则。


程序员要依赖于抽象接口编程、不要依赖具体的实现。


其实大白话就是咱们 Java 里常说的面向接口编程;这个编程技巧在开发框架、SDK或是多种实现的业务中常用。


好处当然是显而易见: 当接口定义好之后,不同的业务只需要根据接口实现自己的业务就好,完全不会互相影响;维护、扩展都很方便。


支持 HTTPgRPC 也是同理实现的:


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 接口也可以。


源码地址:github.com/crossoverJi…


相关实践学习
通过性能测试PTS对云服务器ECS进行规格选择与性能压测
本文为您介绍如何利用性能测试PTS对云服务器ECS进行规格选择与性能压测。
相关文章
|
5月前
|
监控 Dubbo 测试技术
如何做好一次服务接口压测?
如何做好一次服务接口压测?
52 0
|
9月前
|
JSON Java 测试技术
使用 JMeter 进行灵活的接口自动化测试
JMeter 是一个开源的负载测试工具,它可以模拟多种协议和应用程序的负载,包括 HTTP、FTP、SMTP、JMS、SOAP 和 JDBC 等。在进行接口自动化测试时,使用 JMeter 可以帮助我们快速地构建测试用例,模拟多种场景,发现接口的性能问题。下面是一些 JMeter 接口自动化测试的步骤和技巧。
|
11月前
|
测试技术
jmeter接口自动化
jmeter接口自动化
101 0
|
监控 测试技术 持续交付
后端也要了解接口性能测试?
事情是这样的,公司有个项目上线之后,在Skywalking的接口监控面板,发现其中一个微服务的接口超时频率很高。
后端也要了解接口性能测试?
|
算法 测试技术
接口测试平台163:并发运行用例功能(2)
接口测试平台163:并发运行用例功能(2)
|
存储 JavaScript 前端开发
接口测试平台162:并发运行用例功能(1)
接口测试平台162:并发运行用例功能(1)
接口测试平台162:并发运行用例功能(1)
|
存储 JSON 前端开发
接口测试平台代码实现52: 自动异常测试-5
打开我们上次没写完的P_apis.html 找到这个error_play函数,我们已经替换好了请求体,那么接下来就把新请求体和接口id传递给后台即可
接口测试平台代码实现52: 自动异常测试-5
|
JSON JavaScript 测试技术
接口测试平台代码实现51: 自动异常测试-4
接口测试平台代码实现51: 自动异常测试-4
接口测试平台代码实现51: 自动异常测试-4
|
JSON JavaScript 前端开发
接口测试平台代码实现46:接口调试用户异常操作处理
经过45节的学习,很多同学已经达到了一个不错的水准,可以自主找到一些问题并修复和提出改进方法,我很欣慰。 本节我们要处理的是用户异常操作引起的情况。 大部分处理我们最好都在前端上拦截,这样的好处是不通过请求 就可以瞬间提示错误,所以我们基本只打开P_apis.html就可以了。
接口测试平台代码实现46:接口调试用户异常操作处理
|
XML JSON JavaScript
接口测试平台代码实现50: 自动异常测试-3
本节开始之前,先解决下关于调试层遗漏的一个设计缺陷。就是当已经打开了一个接口的调试层后,如果直接点击其他接口的调试层便会出现显示错误。这类的问题非常多,我们最好是直接根本上绕过去。
接口测试平台代码实现50: 自动异常测试-3