现在IT领域都讲大数据、高并发、海量连接等时髦词汇,这些特性的系统在上线之前一定会做大量的测试,今天介绍一些常用的性能测试工具。

先认识几个专有名词:

1、吞吐率(Requests per second)

概念:服务器并发处理能力的量化描述,单位是reqs/s,指的是某个并发用户数下单位时间内处理的请求数。某个并发用户数下单位时间内能处理的最大请求数,称之为最大吞吐率。 计算公式:总请求数 / 处理完成这些请求数所花费的时间,即 Request per second = Complete requests / Time taken for tests

2、并发连接数(The number of concurrent connections)

概念:某个时刻服务器所接受的请求数目,简单的讲,就是一个会话。

3、并发用户数(The number of concurrent users,Concurrency Level)

概念:要注意区分这个概念和并发连接数之间的区别,一个用户可能同时会产生多个会话,也即连接数。

4、用户平均请求等待时间(Time per request)

计算公式:处理完成所有请求数所花费的时间/ (总请求数 / 并发用户数),即 Time per request = Time taken for tests /( Complete requests / Concurrency Level)

5、服务器平均请求等待时间(Time per request: across all concurrent requests)

计算公式:处理完成所有请求数所花费的时间 / 总请求数,即 Time taken for / testsComplete requests 可以看到,它是吞吐率的倒数。 同时,它也=用户平均请求等待时间/并发用户数,即 Time per request / Concurrency Level

wrk2

wrk2是一个主要基于wrk的HTTP基准测试工具,wrk2经过修改后能够提供稳定的吞吐量负载以及更精确的延时统计,即通过设置参数,wrk2增加了–rate或-R参数设置吞吐量(每秒总请求数)及–u_latency参数显示延时统计。

下载安装wrk2工具:

# git clone https://github.com/giltene/wrk2.git 下载源码
# cd wrk2  安装目录
# make

# cp wrk /usr/local/bin

在命令行就可以直接使用wrk命令了,基本参数:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
Options:                                            
    -c, --connections <N>  Connections to keep open # HTTP连接数,如1k,1M,1G,
    -d, --duration  <T>  Duration of test           # 测试持续时间,如 2s 2m 2h          
    -t, --threads <N>  Number of threads to use     # 开启的线程数 
                                                      
    -s, --script   <S>  Load Lua script file        # 进阶功能,使用 lua 脚本
    -H, --header   <H>  Add header to request       # 添加请求头

    -L  --latency    Print latency statistics       # 打印详细延迟统计
    -U  --u_latency  Print uncorrceted latency statistics 
        --timeout     <T>  Socket/request timeout # 请求超时,大于该时间的将被记录
    -B, --batch_latency    Measure latency of whole   
                           batches of pipelined ops   
                           (as opposed to each op)    
    -v, --version          Print version details      
    -R, --rate        <T>  work rate (throughput) # 每个线程每秒钟完成的请求数(吞度量)
                           in requests/sec (total)    
                           [Required Parameter]

参数说明:

  • 线程数:-t,一般是依据CPU核数来设定,最大值不要超过2倍CPU核数。
  • 连接数:-c,可以理解为并发数,连接数可以在测试过程中多次调整,找到QPS达到最大临界点时的最大并发量;由于服务都有自身的负载极限,也会出现连接数越大QPS越低的情况,这种情况是因为连接数设置的过高,导致待测系统超出自身能承受的负载。
  • 吞吐量:-R,是每个线程每秒完成的请求数,这个数值是wrk2必带的一个参数,在测试过程中也是需要测试人员多次调试,通过不断上调其数值,测试出QPS的临界值及保证服务可用的时延。

一般线程数不宜过多,核数的2到4倍足够了,多了反而因为线程切换过多造成效率降低,因为 wrk 不是使用每个连接一个线程的模型,而是通过异步网络 io 提升并发量,所以网络通信不会阻塞线程执行,这也是 wrk 可以用很少的线程模拟大量网路连接的原因。而现在很多性能工具并没有采用这种方式,而是采用提高线程数来实现高并发。所以并发量一旦设的很高,测试机自身压力就很大。测试效果反而下降。

下面举两个例子来说明使用方法:

使用方法 说明
wrk -t2 -c100 -d30s -R2000 url 2个线程,100个连接,持续时间30s,每秒2000个请求
wrk -t2 -c100 -d30s -R2000 –latency url 2个线程,100个连接,持续时间30s,每秒2000个请求

做这样一个实验,大家可以试一试:用Node.js写一个简单的WebServer(端口:5111),返回服务器当前时间。第一次直接访问这个Node端口压测,第二次用Nginx做负载均衡(端口:8019)的的配置再压测,结果如下:

image-20210118144401192

看到没有,Nginx做代理转发之后性能下降明显,这是值得大家警惕的对方。别看Nginx是强大的代理工具,用了他之后的性能损耗还是挺大的;对他的专门优化是需要下功夫研究的。

ab

ab是apache自带的压力测试工具。ab非常实用,它不仅可以对apache服务器进行网站访问压力测试,也可以对其它类型的服务器进行压力测试。比如nginx、tomcat、IIS等。

安装ab测试工具(就是找到apache2-utils这个包安装即可):

sudo apt-get install apache2-utils
zypper in apache2-utils

安装完了之后就可以得到 ab命令了,有些地方可能还会得到ab2的命令,ab2一般也是直接链接到ab了,是一样的不用纠结。这个命令也支持很多参数,看下面的参数列表:

Usage: ab [options] [http[s]://]hostname[:port]/path
Options are:
    -n requests     Number of requests to perform
    -c concurrency  Number of multiple requests to make at a time
    -t timelimit    Seconds to max. to spend on benchmarking
                    This implies -n 50000
    -s timeout      Seconds to max. wait for each response
                    Default is 30 seconds
    -b windowsize   Size of TCP send/receive buffer, in bytes
    -B address      Address to bind to when making outgoing connections
    -p postfile     File containing data to POST. Remember also to set -T
    -u putfile      File containing data to PUT. Remember also to set -T
    -T content-type Content-type header to use for POST/PUT data, eg.
                    'application/x-www-form-urlencoded'
                    Default is 'text/plain'
    -v verbosity    How much troubleshooting info to print
    -w              Print out results in HTML tables
    -i              Use HEAD instead of GET
    -x attributes   String to insert as table attributes
    -y attributes   String to insert as tr attributes
    -z attributes   String to insert as td or th attributes
    -C attribute    Add cookie, eg. 'Apache=1234'. (repeatable)
    -H attribute    Add Arbitrary header line, eg. 'Accept-Encoding: gzip'
                    Inserted after all normal header lines. (repeatable)
    -A attribute    Add Basic WWW Authentication, the attributes
                    are a colon separated username and password.
    -P attribute    Add Basic Proxy Authentication, the attributes
                    are a colon separated username and password.
    -X proxy:port   Proxyserver and port number to use
    -V              Print version number and exit
    -k              Use HTTP KeepAlive feature
    -d              Do not show percentiles served table.
    -S              Do not show confidence estimators and warnings.
    -q              Do not show progress when doing more than 150 requests
    -l              Accept variable document length (use this for dynamic pages)
    -g filename     Output collected data to gnuplot format file.
    -e filename     Output CSV file with percentages served
    -r              Don't exit on socket receive errors.
    -m method       Method name
    -h              Display usage information (this message)
    -Z ciphersuite  Specify SSL/TLS cipher suite (See openssl ciphers)
    -f protocol     Specify SSL/TLS protocol
                    (SSL3, TLS1, TLS1.1, TLS1.2 or ALL)

拿前面的例子再跑一把性能测试看看,5111是直接暴露的node,8019是 Nginx代理之后的端口:

ab2 -n30000 -c100 http://127.0.0.1:5111/
ab2 -n30000 -c100 http://127.0.0.1:8019/

奇怪的事情发生了,两次的结果分别如下:

# ab2 -n 10000 -c 100 http://127.0.0.1:5111/

Server Software:        
Server Hostname:        127.0.0.1
Server Port:            5111

Document Path:          /
Document Length:        37 bytes

Concurrency Level:      100
Time taken for tests:   7.749 seconds
Complete requests:      30000
Failed requests:        0
Total transferred:      4140000 bytes
HTML transferred:       1110000 bytes
Requests per second:    3871.52 [#/sec] (mean)
Time per request:       25.830 [ms] (mean)
Time per request:       0.258 [ms] (mean, across all concurrent requests)
Transfer rate:          521.75 [Kbytes/sec] received
# ab2 -n 10000 -c 100 http://127.0.0.1:8019/

Server Software:        nginx/1.18.0
Server Hostname:        127.0.0.1
Server Port:            8019

Document Path:          /
Document Length:        37 bytes

Concurrency Level:      100
Time taken for tests:   7.741 seconds
Complete requests:      30000
Failed requests:        0
Total transferred:      4800000 bytes
HTML transferred:       1110000 bytes
Requests per second:    3875.46 [#/sec] (mean)
Time per request:       25.803 [ms] (mean)
Time per request:       0.258 [ms] (mean, across all concurrent requests)
Transfer rate:          605.54 [Kbytes/sec] received

严重怀疑ab的测试结果,用不用Nginx做WEB代理,QPS是一样的。而这和wrk2与之后介绍的autocannon结果不一致。难道ab真的只能测试apache、Nginx、Tomcat、IIS等固定几款WEB代理工具吗?

autocannon

以前说过一篇autocannon的文章:/2020/10/07215703-autocannon.html

重点是:这个工具只适合一般的场景测试,复杂的测试应该还是要用wrk2ab等基于静态编译的工具。

hey

HTTP load generator, ApacheBench (ab) replacement

这个工具是用Golang实现的,正如项目简介中说的一样。用Go实现了类似ab的功能。

项目地址:

https://github.com/rakyll/hey

其它

在性能测试方面也有很多其它成熟的工具,比如 LoadRunner,Jmeter 等。但是很多工具都是给专门的性能测试人员使用的,功能虽然强大,但是安装和操作不太方便;这些工具一般专人专岗使用。

(完)