压测指标怎么看?教你如何衡量你的服务性能
首先是压测工具
压测工具很多,有简单的ab、wrk等等,也有相对复杂的k6、jmeter等等,一般作为主力研发人员,大致上,我还是习惯用ab或者wrk进行压测。
具体各个工具的优缺点不提,wrk可以在单机上提供更多的压力,满足简单压测的需求。
关于WRK压测
wrk比起apache bench更为高效,因为它支持多线程,更容易发挥多核CPU的能力,甚至可以压满CPU。wrk支持Lua脚本来提供更多的参数定制、参数加密等需求,灵活度更高。
压测准备
1. 安装wrk
详细的安装教程参阅 Wrk Github, 这是最正规的安装途径介绍。
2. 提供一个服务
Spring Boot
比如我们熟练使用的Spring Boot,提供一个简单的API服务。
@GetMapping("/health")
private void health() {
}
当然如果平时使用的是Quarkus或者Vert.x,那么也可以参照编写对应的API。
Quarkus
@Route(path = "/hello1", methods = HttpMethod.GET)
@Operation(description = "hello1 接口")
void hello1(RoutingContext ctx) {
ctx.response().end("hello1, quarkus");
}
Vert.x
router.get("/mxx").handler(req -> req.response().end("hello, 地球"));
3. 压测命令
wrk的命令很简单,可以通过以下命令查看
[root@ecs-1b4c-0002 ~]# wrk
Usage: wrk <options> <url>
Options:
-c, --connections <N> Connections to keep open
-d, --duration <T> Duration of test
-t, --threads <N> Number of threads to use
-s, --script <S> Load Lua script file
-H, --header <H> Add header to request
--latency Print latency statistics
--timeout <T> Socket/request timeout
-v, --version Print version details
Numeric arguments may include a SI unit (1k, 1M, 1G)
Time arguments may include a time unit (2s, 2m, 2h)
4. 压测API
使用如下命令进行压测,维持50个connections,持续20秒。
wrk -c50 -d20s 'http://127.0.0.1:8088/vc/health' --latency
结果如下:
[root@ecs-1b4c-0002 ~]# wrk -c50 -d20s 'http://127.0.0.1:8088/vc/health' --latency
Running 20s test @ http://127.0.0.1:8088/vc/health
2 threads and 50 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 109.32ms 99.16ms 666.12ms 68.08%
Req/Sec 270.47 136.63 550.00 59.89%
Latency Distribution
50% 93.31ms
75% 175.14ms
90% 248.54ms
99% 380.58ms
10598 requests in 20.09s, 1.00MB read
Requests/sec: 527.59
Transfer/sec: 51.01KB
5. 压测结果分析
Requests/sec
我们首先关注的结果大概就是Requests/sec,每秒请求数,也称作QPS。
QPS越大,则每秒处理的请求越多,通常意味着我们的API的能力越好。
10598 requests in 20.09s, 1.00MB read
这个地方记录了20秒内总共处理了多少请求。如果有API的响应异常,也会在这个位置体现出来。如果没有告知error的请求数量,则认为所有请求都正常响应了。
Req/Sec 270.47 136.63 550.00 59.89%
这个指标类似于QPS,因为每秒处理的请求数量并不是一成不变的,有可能这一秒处理的请求少,下一秒处理的请求多。
这个离散性主要用方差来体现。方差越小,则服务越稳定,上下波动范围越小(可以这么理解,如果数学知识牢靠,直接用方差的概念理解更好)。
Latency 109.32ms 99.16ms 666.12ms 68.08%
这个是响应时间。一般我们在描述我们的性能要求时,会这么去说:“保证平均响应时间在250ms以内,保证99%的请求在300ms内完成”。同样这个也有方差的概念,同上。
Latency Distribution
更详细的响应时间描述,比如我们知道90%的请求都在248.58ms内完成,99%的请求在380.58ms内完成。显然和刚才我们要求的性能指标不符。
整体分析
作为研发人员,压测的目的是核查我们提供的API的是否符合服务的基本指标,发现可能潜在的问题。通常来说,只要符合性能要求,那么可以成为达标。
因为不同的服务器下,性能会有较大的差异(服务器配置越好,通常性能越好),所以需要我们有一定的经验来判断服务的各项指标。
以上面的压测结果举例,显然这个API的QPS相对低,结合业务需求和用户量级等等方面,我们判定(服务符合预期or性能不达标需要优化改善)。
如果经常做业务压测的同学可能会比较清楚,spring boot的同步模型下,性能的上线比较低,如果做B端业务还好,如果做C端业务,可能很容易达到天花板,然后就需要更多的了解集群、微服务、分布式等等知识。
贴一下Quarkus的压测性能(同一台服务器)
[root@ecs-1b4c-0002 ~]# wrk -c50 -d20s 'http://127.0.0.1:8080/hello1' --latency
Running 20s test @ http://127.0.0.1:8080/hello1
2 threads and 50 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 537.64us 1.61ms 33.92ms 94.95%
Req/Sec 115.20k 18.64k 168.36k 69.00%
Latency Distribution
50% 162.00us
75% 318.00us
90% 720.00us
99% 8.69ms
4592667 requests in 20.05s, 437.99MB read
Requests/sec: 229060.92
Transfer/sec: 21.84MB