这里解释一波,“sb” 是 SuperBenchmarker的缩写,所以并不是你想的那个样子(⊙o⊙)?
用官方的描述说:Superbenchmarker是用于对HTTP API和网站进行性能测试的负载生成器命令行工具。受Apache Benchmark的启发,它打算成为steriods上的Apache Benchmark(ab.exe)。它会在测试结束时在终端窗口中显示最终结果,但也会在Web界面中不断报告。
总之sb就是一个开源的测压工具,轻量级,易操作的命令行压力测试工具。
安装篇
- 管理员身份打开powershell
- 运行下面命令
Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))
- 执行choco install superbenchmarker
- 输入 sb,你会看到帮助文档
PS C:\Users\87920> sb
SuperBenchmarker 4.5.1
Copyright (C) 2021 Ali Kheyrollahi
ERROR(S):
Required option 'u, url' is missing.
-c, --concurrency (Default: 1) Number of concurrent requests
-n, --numberOfRequests (Default: 100) Total number of requests
-N, --numberOfSeconds Number of seconds to run the test. If specified, -n will be ignored.
-y, --delayInMillisecond (Default: 0) Delay in millisecond
-u, --url Required. Target URL to call. Can include placeholders.
-m, --method (Default: GET) HTTP Method to use
-t, --template Path to request template to use
-p, --plugin Name of the plugin (DLL) to replace placeholders. Should contain one class which
implements IValueProvider. Must reside in the same folder.
-l, --logfile Path to the log file storing run stats
-f, --file Path to CSV file providing replacement values for the test
-a, --TSV If you provide a tab-separated-file (TSV) with -f option instead of CSV
-d, --dryRun Runs a single dry run request to make sure all is good
-e, --timedField Designates a datetime field in data. If set, requests will be sent according to order
and timing of records.
-g, --TlsVersion Version of TLS used. Accepted values are 0, 1, 2 and 3 for TLS 1.0, TLS 1.1 and TLS 1.2
and SSL3, respectively
-v, --verbose Provides verbose tracing information
-b, --tokeniseBody Tokenise the body
-k, --cookies Outputs cookies
-x, --useProxy Whether to use default browser proxy. Useful for seeing request/response in Fiddler.
-q, --onlyRequest In a dry-run (debug) mode shows only the request.
-h, --headers Displays headers for request and response.
-z, --saveResponses saves responses in -w parameter or if not provided in\response_<timestamp>
-w, --responsesFolder folder to save responses in if and only if -z parameter is set
-?, --help Displays this help.
-C, --dontcap Don't Cap to 50 characters when Logging parameters
-R, --responseRegex Regex to extract from response. If it has groups, it retrieves the last group.
-j, --jsonCount Captures number of elements under the path e.g. root/leaf1/leaf2 finds count of leaf2
children - stores in the log as another parameter. If the array is at the root of the
JSON, use space: -j ' '
-W, --warmUpPeriod (Default: 0) Number of seconds to gradually increase number of concurrent users. Warm-up
calls do not affect stats.
-P, --reportSliceSeconds (Default: 3) Number of seconds as interval for reporting slices. E.g. if chosen as 5,
report charts have 5 second intervals.
-F, --reportFolder Name of the folder where report files get stored. By default it is in
yyyy-MM-dd_HH-mm-ss.ffffff of the start time.
-B, --dontBrowseToReports By default it, sb opens the browser with the report of the running test. If specified,
it wil not browse.
-U, --shuffleData If specified, shuffles the dataset provided by -f option.
--help Display this help screen.
--version Display version information.
System.Linq.Enumerable+<ExceptIterator>d__73`1[CommandLine.Error]
- 执行压测命令
PS C:\Users\87920> sb -u 'http://localhost:9195/openapi/bi/findByUserName?name=xiaomi' -c 20 -N 10
Starting at 2021/2/1 16:03:05
[Press C to stop the test]
7907 (RPS: 558.9)
---------------Finished!----------------
Finished at 2021/2/1 16:03:20 (took 00:00:14.2173096)
Status 200: 7907
RPS: 714.5 (requests/second)
Max: 87ms
Min: 0ms
Avg: 7.8ms
50% below 5ms
60% below 7ms
70% below 8ms
80% below 10ms
90% below 15ms
95% below 20ms
98% below 31ms
99% below 37ms
99.9% below 85ms
应用篇
基础应用
sb -u "http://example.com"
简单运行,必须使用 -u ( - - url) 参数将它指向要调用的目标URL(网站或API)
示例:大家可以试一下,默认不指定任何参数,不论你运行多少次,请求数始终是100
PS C:\Users\afj> sb -u 'https://www.baidu.com'
Starting at 2021/2/5 17:54:18
[Press C to stop the test]
100 (RPS: 14.4)
---------------Finished!----------------
Finished at 2021/2/5 17:54:25 (took 00:00:07.0584647)
Status 200: 100
RPS: 12.4 (requests/second)
Max: 245ms
Min: 47ms
Avg: 52.2ms
50% below 49ms
60% below 50ms
80% below 51ms
90% below 52ms
95% below 56ms
98% below 76ms
99% below 245ms
99.9% below 245ms
sb -u "http://example.com" -c 1 -n 100
使用单个线程触发100个GET请求,-c (–concurrency)(默认: 1) 并发请求数,-n ( --numberOfRequests)(默认: 100) 请求总数
a.可以使用-c和-n来更改并发数或请求总数。不建议使用过高的-c,因为它会影响测试结果。注意你机器上的CPU使用率,确保它是<70%
b.示例:由此可以看出,本条命令等价于上面那条命令
PS C:\Users\afj> sb -u 'https://www.baidu.com' -c 1 -n 100
Starting at 2021/2/5 17:56:53
[Press C to stop the test]
100 (RPS: 12.9)
---------------Finished!----------------
Finished at 2021/2/5 17:57:01 (took 00:00:07.8506337)
Status 200: 100
RPS: 11.3 (requests/second)
Max: 275ms
Min: 55ms
Avg: 60.7ms
50% below 57ms
60% below 57ms
70% below 58ms
80% below 60ms
90% below 66ms
95% below 72ms
98% below 79ms
99% below 275ms
99.9% below 275ms
sb -u "http://example.com" -c 4 -N 1800
如果想要在一段时间内运行测试,而不是确定请求总数,例如可以使用4个并发请求测试30分钟,-c (–concurrency)(默认: 1) 并发请求数,-N(–numberOfSeconds)(如果指定-n,则会被忽略) 运行秒数
示例:使用-N指定运行秒数,而不是-n请求总数
PS C:\Users\afj> sb -u 'https://www.baidu.com' -c 1 -N 10
Starting at 2021/2/7 10:44:03
[Press C to stop the test]
155 (RPS: 11)9)
---------------Finished!----------------
Finished at 2021/2/7 10:44:17 (took 00:00:14.1239997)
Status 200: 155
RPS: 14 (requests/second)
Max: 251ms
Min: 50ms
Avg: 53.4ms
50% below 51ms
60% below 51ms
70% below 51ms
80% below 52ms
90% below 53ms
95% below 58ms
98% below 73ms
99% below 126ms
99.9% below 251ms
sb -u "http://example.com" -c 4 -N 1800 -y 100
为了模拟业务场景,可能需要增加延迟来进行压力测试,那么就可以使用 -y 以毫秒为单位进行延迟,还是用上面的例子,可以使用4个并发请求测试30分钟,-c (–concurrency)(默认: 1) 并发请求数,-N(–numberOfSeconds)(如果指定-n,则会被忽略) 运行秒数,-y (–delayInMillisecond)(默认: 0) 以毫秒为单位进行延迟
示例:增加100ms的请求延迟
PS C:\Users\afj> sb -u 'https://www.baidu.com' -c 1 -N 10 -y 100
Starting at 2021/2/7 10:51:52
[Press C to stop the test]
48 (RPS: 3.4)
---------------Finished!----------------
Finished at 2021/2/7 10:52:06 (took 00:00:14.1569171)
Status 200: 48
RPS: 4.3 (requests/second)
Max: 300ms
Min: 60ms
Avg: 67.2ms
50% below 62ms
60% below 62ms
70% below 62ms
80% below 64ms
90% below 65ms
95% below 66ms
98% below 300ms
99% below 300ms
99.9% below 300ms
sb -u "http://example.com/api/car/123" -n 1000 -m DELETE
以上的列子,默认都是使用http GET 方式进行请求,如果需要其他的method,可以用 -m指定。
示例:使用DELETE 进行api压力测试
PS C:\Users\afj> sb -u 'http://localhost:8188/order/delete/1' -c 1 -N 10 -m DELETE
Starting at 2021/2/7 13:54:30
[Press C to stop the test]
15456 (RPS: 1101.6)
---------------Finished!----------------
Finished at 2021/2/7 13:54:44 (took 00:00:14.0800237)
Status 200: 15456
RPS: 1400.2 (requests/second)
Max: 127ms
Min: 0ms
Avg: 0.1ms
50% below 0ms
60% below 0ms
70% below 0ms
80% below 0ms
90% below 0ms
95% below 0ms
98% below 1ms
99% below 1ms
99.9% below 3ms
进阶应用
基础的参数应用先告一段落,因为它基本上可以满足简单的api的压力测试需求,接下来我们将进入稍微复杂一些的业务场景,比如说压测请求需要带有header,用来传递 token或者用户标识等等,又或者是需要压测post请求,那么以上的示例已经不能满足了,废话不多说,一起来看~
sb -u "http://example.com/" -t template.txt
我们先来看一个官方的例子。要将授权标头发送到服务器,请创建一个template.txt具有以下内容的文本文件:Authorization: Basic GV5ITpub3Bhc3N3b3JkaGVyZQ==
这里需要重点提示下,这个template.txt需要跟你打开的powershell在同一目录下
示例:继续使用DELETE 进行api压力测试
PS C:\Users\afj> sb -u 'http://localhost:8188/order/delete/1' -d -m DELETE -t template.txt
Starting at 2021/3/2 10:33:35
[Press C to stop the test]
delete order,id is 1, Authorization = Basic GV5ITpub3Bhc3N3b3JkaGVyZQ==
1 (RPS: 5.6)
---------------Finished!----------------
Finished at 2021/3/2 10:33:35 (took 00:00:00.2373330)
Status 200: 1
RPS: 0.8 (requests/second)
Max: 159ms
Min: 159ms
Avg: 159ms
50% below 159ms
60% below 159ms
70% below 159ms
80% below 159ms
90% below 159ms
95% below 159ms
98% below 159ms
99% below 159ms
99.9% below 159ms
/**
/**
* Delete path variable.
*
* @param id the id
* @param authorization authorization
* @return desc
*/
@DeleteMapping("/delete/{id}")
public String delete(@PathVariable("id") final String id, @RequestHeader("Authorization")final String authorization) {
log.info("delete order,id is " + id);
log.info(authorization);
return "delete order,id is " + id + ", Authorization = " + authorization;
}
sb -u 'http://localhost:8188/order/save' -d -m POST -t template.txt
那么如果要提交的是一个post请求怎么办呢?
(注意,标头和正文之间的空行,Content-Type: application/json)
示例: 更新template.txt,将请求体添加进去,具体如下
template.txt
Authorization: Basic GV5ITpub3Bhc3N3b3JkaGVyZQ==
Content-Type: application/json
{
"id": "3",
"name": "xiaomi",
"auth": "test"
}
代码示例
/**
* Save order dto.
*
* @param orderDTO the order dto
* @param authorization authorization
* @return the order dto
*/
@PostMapping("/save")
public OrderDTO save(@RequestBody final OrderDTO orderDTO, @RequestHeader("Authorization")final String authorization) {
orderDTO.setName("hello world save order");
orderDTO.setAuth(authorization);
return orderDTO;
}
压测结果
PS C:\Users\87920> sb -u 'http://localhost:8188/order/save' -d -m POST -t template.txt
Starting at 2021/3/2 11:30:44
[Press C to stop the test]
{"id":"3","name":"hello world save order","auth":"Basic GV5ITpub3Bhc3N3b3JkaGVyZQ=="}
1 (RPS: 20.8)
---------------Finished!----------------
Finished at 2021/3/2 11:30:44 (took 00:00:00.2349936)
Status 200: 1
RPS: 0.8 (requests/second)
Max: 28ms
Min: 28ms
Avg: 28ms
50% below 28ms
60% below 28ms
70% below 28ms
80% below 28ms
90% below 28ms
95% below 28ms
98% below 28ms
99% below 28ms
99.9% below 28ms
高阶应用
当我们需要请求参数动态可变,又或者说需要根据我们给定的参数列表进行请求,并且还有可能是post请求方式,那么该怎么做呢?
sb -u "http://example.com/?id={{{id:RAND_INTEGER:[1:1000000]}}}"
首先我们看get请求,每次传入的id是随机可变的。
官方文档中表明,可以发送随机的STRING,DATE,DATETIME,DATETIMEOFFSET,INTEGER,DOUBLE,NAME和GUID等数据类型,本次只演示Integer数据类型,其余的可一行练习,就不展开了
示例:随机发送1到1,000,000范围内的随机整数
PS C:\Users\afj> sb -u 'http://localhost:8188/order/findById/?id={{{id:RAND_INTEGER:[1:1000000]}}}' -d
Starting at 2021/3/2 14:37:29
[Press C to stop the test]
{"id":"631596","name":"hello world findById","auth":null}
1 (RPS: 18.5)
---------------Finished!----------------
Finished at 2021/3/2 14:37:30 (took 00:00:00.2420355)
Status 200: 1
RPS: 0.8 (requests/second)
Max: 34ms
Min: 34ms
Avg: 34ms
50% below 34ms
60% below 34ms
70% below 34ms
80% below 34ms
90% below 34ms
95% below 34ms
98% below 34ms
99% below 34ms
99.9% below 34ms
sb -u "http://example.com/?id={{{id}}} -f test.txt"
如果随机列表不适应业务场景,需要id按照我们给定的列表请求,那怎么办呢?
这样你就需要创建一个文件,txt或者是csv等格式都可以,本次演示使用txt文档
示例:需要创建一个test.txt文件,具体文件内容如下:
id,
1,
2,
3
PS C:\Users\afj> sb -u 'http://localhost:8188/order/findById/?id={{{id}}}' -f test.txt
Starting at 2021/3/2 14:44:00
[Press C to stop the test]
100 (RPS: 606.1)
---------------Finished!----------------
Finished at 2021/3/2 14:44:00 (took 00:00:00.2410504)
Status 200: 100
RPS: 82.1 (requests/second)
Max: 31ms
Min: 0ms
Avg: 0.6ms
50% below 0ms
60% below 0ms
70% below 0ms
80% below 1ms
90% below 1ms
95% below 1ms
98% below 2ms
99% below 31ms
99.9% below 31ms
2021-03-02 14:44:00.354 INFO 23304 --- [ctor-http-nio-3] o.d.s.e.http.controller.OrderController : 1
2021-03-02 14:44:00.358 INFO 23304 --- [ctor-http-nio-3] o.d.s.e.http.controller.OrderController : 2
2021-03-02 14:44:00.359 INFO 23304 --- [ctor-http-nio-3] o.d.s.e.http.controller.OrderController : 3
2021-03-02 14:44:00.360 INFO 23304 --- [ctor-http-nio-3] o.d.s.e.http.controller.OrderController : 1
2021-03-02 14:44:00.361 INFO 23304 --- [ctor-http-nio-3] o.d.s.e.http.controller.OrderController : 2
2021-03-02 14:44:00.362 INFO 23304 --- [ctor-http-nio-3] o.d.s.e.http.controller.OrderController : 3
2021-03-02 14:44:00.364 INFO 23304 --- [ctor-http-nio-3] o.d.s.e.http.controller.OrderController : 1
2021-03-02 14:44:00.365 INFO 23304 --- [ctor-http-nio-3] o.d.s.e.http.controller.OrderController : 2
2021-03-02 14:44:00.366 INFO 23304 --- [ctor-http-nio-3] o.d.s.e.http.controller.OrderController : 3
...
sb -u "http://example.com/ -f test.txt -t template.txt -m POST"
如果需要多个参数要按照我们给定列表进行请求,并且还是类似表单提交的post的请求怎么办呢?
这样你就需要创建2个文件,一个test.txt存储可变参数列表;一个是我们进阶篇里面提到的template.txt
示例:需要创建一个test.txt文件,一个template.txt,具体文件内容如下:
test.txt
id,name,
1,"xiaomi1",
2,"xiaomi2",
3,"xiaomi3"
template.txt
Authorization: Basic GV5ITpub3Bhc3N3b3JkaGVyZQ==
Content-Type: application/json
{
"id": {{{id}}},
"name": {{{name}}},
"auth": "test"
}
PS C:\Users\87920> sb -u 'http://localhost:8188/order/save' -f test.txt -t template.txt -m POST
Starting at 2021/3/2 14:52:37
[Press C to stop the test]
100 (RPS: 505.1)
---------------Finished!----------------
Finished at 2021/3/2 14:52:37 (took 00:00:00.2396538)
Status 200: 100
RPS: 82.3 (requests/second)
Max: 30ms
Min: 0ms
Avg: 1ms
50% below 1ms
60% below 1ms
70% below 1ms
80% below 1ms
90% below 1ms
95% below 2ms
98% below 4ms
99% below 30ms
99.9% below 30ms
2021-03-02 14:52:37.483 INFO 23304 --- [ctor-http-nio-2] o.d.s.e.http.controller.OrderController : OrderDTO(id=1, name=xiaomi1, auth=Basic GV5ITpub3Bhc3N3b3JkaGVyZQ==)
2021-03-02 14:52:37.484 INFO 23304 --- [ctor-http-nio-2] o.d.s.e.http.controller.OrderController : OrderDTO(id=2, name=xiaomi2, auth=Basic GV5ITpub3Bhc3N3b3JkaGVyZQ==)
2021-03-02 14:52:37.485 INFO 23304 --- [ctor-http-nio-2] o.d.s.e.http.controller.OrderController : OrderDTO(id=3, name=xiaomi3, auth=Basic GV5ITpub3Bhc3N3b3JkaGVyZQ==)
2021-03-02 14:52:37.486 INFO 23304 --- [ctor-http-nio-2] o.d.s.e.http.controller.OrderController : OrderDTO(id=1, name=xiaomi1, auth=Basic GV5ITpub3Bhc3N3b3JkaGVyZQ==)
2021-03-02 14:52:37.487 INFO 23304 --- [ctor-http-nio-2] o.d.s.e.http.controller.OrderController : OrderDTO(id=2, name=xiaomi2, auth=Basic GV5ITpub3Bhc3N3b3JkaGVyZQ==)
2021-03-02 14:52:37.488 INFO 23304 --- [ctor-http-nio-2] o.d.s.e.http.controller.OrderController : OrderDTO(id=3, name=xiaomi3, auth=Basic GV5ITpub3Bhc3N3b3JkaGVyZQ==)
2021-03-02 14:52:37.489 INFO 23304 --- [ctor-http-nio-2] o.d.s.e.http.controller.OrderController : OrderDTO(id=1, name=xiaomi1, auth=Basic GV5ITpub3Bhc3N3b3JkaGVyZQ==)
2021-03-02 14:52:37.491 INFO 23304 --- [ctor-http-nio-2] o.d.s.e.http.controller.OrderController : OrderDTO(id=2, name=xiaomi2, auth=Basic GV5ITpub3Bhc3N3b3JkaGVyZQ==)
2021-03-02 14:52:37.492 INFO 23304 --- [ctor-http-nio-2] o.d.s.e.http.controller.OrderController : OrderDTO(id=3, name=xiaomi3, auth=Basic GV5ITpub3Bhc3N3b3JkaGVyZQ==)
到这里大部分的参数案例已经覆盖到了,其实也是把官网的示例演示了一遍,如果还有其他的参数不清楚怎么使用,欢迎在留言区一起讨论~
图表分析
sb -u "http://example.com/ -B"
如果你不希望每次执行完命令后,实时图标分析的html页面弹出,可以使用 -B 关闭,后续如果想看具体的分析报告,可以在你打开的powershell同级目录下找到类似(2021-03-02_11-59-15.889872)的文件夹,找到里面的index.html打开即可
sb -u "http://example.com/ -B -F TEST0001"
如果你觉着类似(2021-03-02_11-59-15.889872)的文件夹不好找,也可以使用 -F 自定义文件夹的名称,比如说是文件夹名为:TEST0001,不过你也不必担心文件夹重名该怎么办,如果指定的文件夹已经存在,默认会进行重命名例如(TEST0001c86d8a1618274037ae7e2b0fd66467bb)
sb -u "http://example.com/ -P 1"
sb默认每3秒获取一次数据切片,也就是说图表的横轴是3秒一个刻度,如果你需要指定获取数据的间隔,可以使用-P 来指定,默认单位是秒
4. 通过如上结果图我们可以看到吞吐率(RPS)和总请求数量(requests)、最大处理时长、最小处理时长、平均时长等信息,你可以随意勾选图表的维度,图表下面有详细的性能数据,一般我们需要注意的是RPS(即每秒请求数,对应 Request per second)
如果对图表的解读还有疑问,欢迎在留言区一起讨论,本次分享就到此为止,欢迎批评指正~