背景
在开发 Web 应用的过程中,作为开发人员,为了确认接口的性能能够达到要求,我们往往需要一个接口压测工具,帮助我们快速地对我们所提供的 Web 服务发起批量请求。在接口联调的过程中,我们通常会用 Postman 等图形化工具来构造对应的请求并调试接口。但是,如果要做批量的请求,并且希望能展示出对应的统计信息,还是需要通过专门的工具才行。
Hey 就是一款非常适合该场景的命令行工具,它由 go 语言编写,并且在 Github 上已开源。Hey 能够并发地运行所提供的请求数并打印统计信息,还支持 HTTP2 站点。
本文将介绍 Hey 的基本安装使用,社区用户基于 Hey 的功能扩展,以及笔者基于自己的需求场景所做的定制化开发工作。
hey
Hey的安装也非常简单,可以直接在其 GIthub 的项目主页上进行下载。对于 macOS 的用户则更加简单,可以直接通过 brew install hey
进行安装。
https://github.com/rakyll/hey
安装完成后,我们只需要在命令行中敲入对应的命令,就可以实现对某个 url 的批量调用,而且 Hey 支持了大量的参数,让调用者可以进行自定义。用法和选项如下:
Usage: hey [options...] <url>
Options:
-n 要运行的请求数。默认值为200。
-c 要同时运行的工作程序数。总请求数不能小于并发级别。默认值为50。
-q 每个工作程序的查询每秒(QPS)速率限制。默认值为无速率限制。
-z 发送请求的应用程序持续时间。达到持续时间后,应用程序将停止并退出。如果指定了持续时间,则忽略n。示例:-z 10s -z 3m。
-o 输出类型。如果未提供,则打印摘要。 "csv"是唯一支持的替代方案。以逗号分隔的值格式转储响应指标。
-m HTTP方法之一:GET、POST、PUT、DELETE、HEAD、OPTIONS。
-H 自定义HTTP标头。您可以通过重复标志指定尽可能多的标头。例如,-H“Accept:text / html”-H“Content-Type:application / xml”。
-t 每个请求的超时时间(以秒为单位)。默认值为20,使用0表示无限制。
-A HTTP接受标头。
-d HTTP请求正文。
-D HTTP请求正文来自文件。例如,/ home / user / file.txt或./ file.txt。
-T 内容类型,默认为"text / html"。
-a 基本身份验证,用户名:密码。
-x HTTP代理地址为主机:端口。
-h2 启用HTTP / 2。
-host HTTP主机标头。
-disable-compression 禁用压缩。
-disable-keepalive 禁用保持活动,防止在不同的HTTP请求之间重用TCP连接。
-disable-redirects 禁用HTTP重定向的跟随
-cpus 使用的CPU核心数。 (当前机器的默认值为8个核心)
下面举一个简单的例子,比如我们希望批量请求百度的主页,只需要执行下列命令:
hey -n 10 -c 2 http://www.baidu.com/
我们就以每次 2 个请求并发发送,发送 5 次访问 baidu.com 的站点,并能得到一份统计报告:
Summary:
Total: 0.8334 secs
Slowest: 0.3334 secs
Fastest: 0.0776 secs
Average: 0.1611 secs
Requests/sec: 11.9987
Response time histogram:
0.078 [1] |■■■■■■■■■■■■■
0.103 [2] |■■■■■■■■■■■■■■■■■■■■■■■■■■■
0.129 [1] |■■■■■■■■■■■■■
0.154 [1] |■■■■■■■■■■■■■
0.180 [3] |■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
0.205 [0] |
0.231 [0] |
0.257 [0] |
0.282 [0] |
0.308 [1] |■■■■■■■■■■■■■
0.333 [1] |■■■■■■■■■■■■■
Latency distribution:
10% in 0.0795 secs
25% in 0.1057 secs
50% in 0.1592 secs
75% in 0.2951 secs
90% in 0.3334 secs
0% in 0.0000 secs
0% in 0.0000 secs
Details (average, fastest, slowest):
DNS+dialup: 0.0005 secs, 0.0776 secs, 0.3334 secs
DNS-lookup: 0.0004 secs, 0.0000 secs, 0.0022 secs
req write: 0.0000 secs, 0.0000 secs, 0.0001 secs
resp wait: 0.0811 secs, 0.0394 secs, 0.1822 secs
resp read: 0.0794 secs, 0.0330 secs, 0.1483 secs
Status code distribution:
[200] 10 responses
可见,统计报告里面包含了各种信息,包括最快/最慢的请求耗时,请求耗时的分布,所有请求响应状态码的分布等等,能够很好很快地帮我们对 Web 服务的性能有一个大致的了解,从而做进一步的优化。
支持 url 中字段正则的 hey
虽然默认的 Hey 足够简单且配置选项丰富,但是它每次命令仅仅能针对一个 url 进行请求和统计分析。
有多名社区开发者在 Github Issue 中提到一个类似问题,那就是希望能够实现一定程度的 URL 动态化,让批量请求不只落在一个 url 上,而是支持调用者进行一些动态设置。
比如说,有社区开发者 preslavrachev 就在 url 中加入了正则的支持,让 url 能够在满足正则配置的情况下进行动态随机生成。举个例子:
hey -n 10 -c 2 http://www.baidu.com/{{[2-9][1-9]}}
统计报告如下,可以看到,url 都满足数字的十位数是 2-9,个位数是 1-9,而且是随机生成的,请求响应都是 404 也符合预期:
http://www.baidu.com/31
http://www.baidu.com/31
http://www.baidu.com/98
http://www.baidu.com/72
http://www.baidu.com/87
http://www.baidu.com/68
http://www.baidu.com/77
http://www.baidu.com/39
http://www.baidu.com/96
http://www.baidu.com/75
Summary:
Total: 0.3644 secs
Slowest: 0.1597 secs
Fastest: 0.0463 secs
Average: 0.0726 secs
Requests/sec: 27.4439
Total data: 2000 bytes
Size/request: 200 bytes
Response time histogram:
0.046 [1] |■■■■■■■
0.058 [6] |■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
0.069 [1] |■■■■■■■
0.080 [0] |
0.092 [0] |
0.103 [0] |
0.114 [0] |
0.126 [0] |
0.137 [0] |
0.148 [0] |
0.160 [2] |■■■■■■■■■■■■■
Latency distribution:
10% in 0.0473 secs
25% in 0.0492 secs
50% in 0.0529 secs
75% in 0.1563 secs
90% in 0.1597 secs
0% in 0.0000 secs
0% in 0.0000 secs
Details (average, fastest, slowest):
DNS+dialup: 0.0202 secs, 0.0463 secs, 0.1597 secs
DNS-lookup: 0.0117 secs, 0.0000 secs, 0.0584 secs
req write: 0.0001 secs, 0.0000 secs, 0.0010 secs
resp wait: 0.0517 secs, 0.0461 secs, 0.0622 secs
resp read: 0.0001 secs, 0.0000 secs, 0.0003 secs
Status code distribution:
[404] 10 responses
【定制开发】支持 url 中 ID 自增的 ihey
刚好,笔者在做压测的时候,url 有一个 id 的动态字段,虽然社区开发者提供的正则方法,但是笔者的场景是一次性创建一大批任务,然后通过批量的调用来进行执行,在这种场景下,随机生成会导致大量的重复请求,而执行过的任务是不允许再次执行的,所以会有问题,所以,笔者的场景需要的是一种能支持数字自增的动态 url。
既然现有的实现无法支持,那么就只能自己做定制开发。笔者对原仓库进行了 fork,同时根据自己的需要进行了定制开发,让这个工具支持了数字自增的动态 url,让我们来看看最终的效果。
为了跟原来的 hey 命令区分开,这里笔者将命令改成 ihey(increase hey),并且已经将可执行文件上传到仓库,可以直接下载执行。命令如下:
ihey -n 10 -c 2 http://some_api/{{20:}}
因为是基于上面 preslavrachev 的修改进行的二次开发,所以这里标识符号依然是{{}},为了标识出是从某个数字开始的,这里就使用了{{number:}},这里的 number 仅支持正整数。
统计报告如下,可以看到,请求 url 从 20 开始,每两个是一组,所以两两的顺序是不确定的,但是总的是从 20-29递增,符合我们的预期。
http://www.baidu.com/21
http://www.baidu.com/20
http://www.baidu.com/22
http://www.baidu.com/23
http://www.baidu.com/24
http://www.baidu.com/25
http://www.baidu.com/26
http://www.baidu.com/27
http://www.baidu.com/28
http://www.baidu.com/29
Summary:
Total: 0.2404 secs
Slowest: 0.0886 secs
Fastest: 0.0341 secs
Average: 0.0474 secs
Requests/sec: 41.5902
Total data: 2000 bytes
Size/request: 200 bytes
Response time histogram:
0.034 [1] |■■■■■■■■
0.040 [5] |■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
0.045 [2] |■■■■■■■■■■■■■■■■
0.050 [0] |
0.056 [0] |
0.061 [0] |
0.067 [0] |
0.072 [0] |
0.078 [0] |
0.083 [0] |
0.089 [2] |■■■■■■■■■■■■■■■■
Latency distribution:
10% in 0.0360 secs
25% in 0.0372 secs
50% in 0.0389 secs
75% in 0.0839 secs
90% in 0.0886 secs
0% in 0.0000 secs
0% in 0.0000 secs
Details (average, fastest, slowest):
DNS+dialup: 0.0095 secs, 0.0341 secs, 0.0886 secs
DNS-lookup: 0.0007 secs, 0.0000 secs, 0.0035 secs
req write: 0.0000 secs, 0.0000 secs, 0.0001 secs
resp wait: 0.0375 secs, 0.0340 secs, 0.0406 secs
resp read: 0.0001 secs, 0.0000 secs, 0.0001 secs
Status code distribution:
[404] 10 responses
总结
本文主要介绍了以下的内容:
一款方便轻量的 api 批量请求工具:hey
社区开发者基于 hey 所做的 url 动态化优化,支持在 url 中通过正则表达式让 hey 随机请求 url。
笔者基于 hey 和社区开发者进行了定制化开发:ihey,让 hey 支持 url 中配置可自增的数字路径,从而达到可预期的动态 url 批量请求。