压测指标怎么看?教你如何衡量你的服务性能
首先是压测工具
压测工具很多,有简单的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