压测指标怎么看?教你如何衡量你的服务性能

1,854 阅读4分钟

压测工具

压测工具很多,有简单的abwrk等等,也有相对复杂的k6jmeter等等,一般作为主力研发人员,大致上,我还是习惯用ab或者wrk进行压测。 ​

具体各个工具的优缺点不提,wrk可以在单机上提供更多的压力,满足简单压测的需求。 ​

WRK

wrk比起apache bench更为高效,因为它支持多线程,更容易发挥多核CPU的能力,甚至可以压满CPUwrk支持Lua脚本来提供更多的参数定制、参数加密等需求,灵活度更高。 ​

压测准备

安装wrk

详细的安装教程参阅 Wrk Github, 这是最正规的安装途径介绍。 ​

提供一个服务

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, 地球"));

压测命令

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)

压测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

压测结果分析

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的是否符合服务的基本指标,发现可能潜在的问题。通常来说,只要符合性能要求,那么可以成为达标。 ​

因为不同的服务器下,性能会有较大的差异(服务器配置越好,通常性能越好),所以需要我们有一定的经验来判断服务的各项指标。 ​

以上面的压测结果举例,显然这个APIQPS相对低,结合业务需求和用户量级等等方面,我们判定(服务符合预期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

K6

K6也是比较新的一款压测工具,可以用js写压测脚本。 ​

参见 天道下的负载测试K6

包含压力测试、负载测试、冒烟、自动化测试等都可以来做。 ​

参考文档

  1. 天道下的负载测试K6
  2. 内网压测VS外网压测
  3. 脱离业务场景的压测都是耍流氓
  4. 请给Sprint Boot多一些内存