Featured image of post 常用压测工具

常用压测工具

盘一盘常用的压测工具...

ApacheBench

简介

ApacheBench 是 Apache 服务器自带的一个web压力测试工具,简称 ab。

ab 工具小巧简单,上手学习较快,可以提供需要的基本性能指标,但是没有图形化结果,不能监控。

需要指出,ab 属于一个轻量级的压测工具,结果不会特别准确,可以用作参考。

Apache 服务器是一个开源的、跨平台的web服务器软件。它提供了一个强大的基础设施和框架,允许用户根据自己的需求进行定制化开发。Apache通过模块化的设计和配置文件的方式,使用户能够灵活的配置和扩展服务器的功能。

安装

我用的是WSL2,安装的Ubuntu 22.04.2 LTS,所以就以Ubuntu系统为例。

执行下面的安装命令:

1
2
#sudo apt-get install apache2-utils
sudo apt install apache2-utils

推荐使用apt命令,它与apt-get大部分功能都是相似的,可以互换使用。但apt 被认为是对 apt-get 的增强和更现代的替代,更为用户友好。

安装完之后,可以执行如下命令查看软件包的文件列表:

1
dpkg -L apache2-utils

命令将显示 apache2-utils 软件包中所有文件的路径。

也可以执行如下命令查看ab版本:

1
ab -V

正常显示版本代表安装成功。

卸载apache2-utils请执行如下命令:

1
2
# sudo apt remove apache2-utils
sudo apt purge apache2-utils # 连同软件包的配置文件一并删除

用法

ab 是一个命令行工具,对发起负载的客户端机器要求很低。利用 ab 命令可以创建很多的并发访问线程,模拟多个访问者同时对某一 URL 地址进行访问,因此可以用来测试目标服务器的负载压力。

它的用法如下:

1
2
3
4
5
6
7
8
9
Usage: ab [options] [http[s]://]hostname[:port]/path
用法:ab [选项] 地址

选项:
Options are:
    -n requests      #执行的请求数,即一共发起多少请求。
    -c concurrency   #请求并发数。
    -s timeout       #指定每个请求的超时时间,默认是30秒。
    -k               #启用HTTP KeepAlive功能,即在一个HTTP会话中执行多个请求。默认时,不启用KeepAlive功能。

压测命令

这里我对自己本地运行的一个web服务做压测。

项目地址:wonderful-pages

执行压测命令:

1
2
# 请求1000次,并发数100
ab -n 1000 -c 100 http://localhost:9090/rotating

压测结果:

点击查看压测结果
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
This is ApacheBench, Version 2.3 <$Revision: 1879490 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking xxx.xxx.xxx.xxx (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Completed 700 requests
Completed 800 requests
Completed 900 requests
Completed 1000 requests
Finished 1000 requests


Server Software:
Server Hostname:        xxx.xxx.xxx.xxx
Server Port:            9090

Document Path:          /rotating
Document Length:        2459 bytes

Concurrency Level:      100
Time taken for tests:   0.315 seconds
Complete requests:      1000
Failed requests:        0
Total transferred:      2555000 bytes
HTML transferred:       2459000 bytes
Requests per second:    3176.90 [#/sec] (mean)
Time per request:       31.477 [ms] (mean)
Time per request:       0.315 [ms] (mean, across all concurrent requests)
Transfer rate:          7926.74 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.5      0       3
Processing:     4   28   6.1     27      51
Waiting:        1   28   6.0     27      51
Total:          4   29   6.0     28      52

Percentage of the requests served within a certain time (ms)
  50%     28
  66%     29
  75%     30
  80%     32
  90%     38
  95%     41
  98%     44
  99%     46
 100%     52 (longest request)

主要关注的指标

上面的测试结果会有很多指标,我们重点关注以下这些:

  • Concurrency Level 并发请求数
  • Time taken for tests 整个测试时间
  • Complete requests 完成请求个数
  • Failed requests 失败个数
  • Requests per second 吞吐量,指的是某个并发用户下单位时间内处理的请求数。等效于 QPS,其实可以看作同一个统计方式,只是叫法不同而已。
  • Time per request 用户平均请求等待时间
  • Time per request 服务器处理时间

Locust

简介

是一款开源的、简单易用、分布式、python 开发的压力测试工具。有图形化界面,支持将压测数据导出。

地址:Locust

安装

确保本地已经安装好了python环境,并且pip已经配置好了环境变量。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# 从清华镜像源安装locust 默认安装在 (python env)\Lib\site-
# simple 不能少, 是 https 而不是 http
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple locust

# 查看 locust 是否安装成功
locust -h

# 安装pyzmq库 
# 该库用于在多个进程或机器上运行Locust分布式测试功能
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple pyzmq

# 安装webSocket 
# 该库用于支持WebSocket协议的压测
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple websocket-client

用法

  1. 编写压测脚本 test.py

    这段脚本定义了一个简单的locust用户,该用户在每个事务中访问"/rotating"这个路由。脚本可用于执行基本的性能测试,模拟多个用户同时访问网站的情况。

    可以根据需求扩展和修改"UserBehavior"类,实现更复杂的用户行为。

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    
    from locust import HttpUser, TaskSet, task
    
    # 定义用户行为
    class UserBehavior(TaskSet):
        @task
        def local_index(self):
            self.client.get("/rotating")
    
    class WebsiteUser(HttpUser):
        # 这里tasks是locust预定义的,不能改为其他名字
        tasks = [UserBehavior] # 指向一个定义的用户行为类
        min_wait = 3000 # 执行事务之间用户等待时间的下界(单位:毫秒)
        max_wait = 6000 # 执行事务之间用户等待时间的上界(单位:毫秒)
    
  2. 启动压测

    1
    2
    
    # -f 指定测试脚本 host协议是http 不是https
    locust -f locust_test.py --host=http://localhost:9090
    
  3. 访问 http://localhost:8089 进入压测首页

    页面内容如图:

    Number of users to simulate 模拟用户数;

    Hatch rate (users spawned/second) 每秒钟增加用户数;

    点击 “Start swarming” 进入压测页面。

    压测界面右上角有:被压测的地址当前状态RPS失败率开始重启按钮

性能测试参数

使用 Locust 进行压测,我们重点关注以下参数指标:

  • Type 请求的类型,例如GET/POST

  • Name 请求的路径

  • Request 当前请求的数量

  • Fails 当前请求失败的数量

  • Median 中间值,单位毫秒,请求响应时间的中间值

  • Average 平均值,单位毫秒,请求的平均响应时间

  • Min 请求的最小服务器响应时间,单位毫秒

  • Max 请求的最大服务器响应时间,单位毫秒

  • Average size 单个请求的大小,单位字节

  • Current RPS 代表吞吐量(Requests Per Second的缩写),指的是某个并发用户数下单位时间内处理的请求数。等效于QPS,其实可以看作同一个统计方式,只是叫法不同而已。

JMeter

Apache JMeter是Apache组织开发的基于Java的压力测试工具。它最初被设计用于Web应用测试,但后来扩展到其他测试领域。

JMeter能够对应用程序做功能/回归测试,通过创建带有断言的脚本来验证你的程序返回了你期望的结果。

JMeter的功能过于强大,这里暂时不介绍用法,可以查询相关文档使用(参考文献中有推荐的教程文档)

云压测

简介

顾名思义,就是将压测脚本部署在云端,通过云端对对我们的应用进行全方位压测,只需要配置压测的参数,无需准备实体机,云端自动给我们分配需要压测的云主机,对被压测目标进行压测。

云压测的优势:

  1. 轻易的实现分布式部署
  2. 能够模拟海量用户的访问
  3. 流量可以从全国各地发起,更加真实的反映用户的体验
  4. 全方位的监控压测指标
  5. 文档比较完善

当然了云压测是一款商业产品,在使用的时候自然还是需要收费的,而且价格还是比较昂贵的~

阿里云 性能测试 PTS

PTS(Performance Testing Service)是面向所有技术背景人员的云化测试工具。

有别于传统工具的繁复,PTS以互联网化的交互,提供性能测试、API调试和监测等多种能力。自研和适配开源的功能都可以轻松模拟任意体量的用户访问业务的场景,任务随时发起,免去繁琐的搭建和维护成本。更是紧密结合监控、流控等兄弟产品提供一站式高可用能力,高效检验和管理业务性能。

阿里云同样还是支持渗透测试,通过模拟黑客对业务系统进行全面深入的安全测试。

腾讯云 压测大师 LM

通过创建虚拟机器人模拟多用户的并发场景,提供一整套完整的服务器压测解决方案。

go-stress-testing

简介

go-stress-testing 是go语言实现的简单压测工具,源码开源、支持二次开发,可以压测httpwebSocket请求私有rpc调用,使用协程模拟单个用户,可以更高效的利用CPU资源。

项目地址 https://github.com/link1st/go-stress-testing

安装

  1. 直接安装可执行文件

    地址:go-stress-testing

  2. 源码运行

    把项目clone到$GOPATH目录。

用法

以windows为例,执行go-stress-testing-win,即可查看go-stress-testing支持的参数:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
Usage of go-stress-testing-win:
  -H value
        自定义头信息传递给服务器 示例:-H 'Content-Type: application/json'
  -c uint
        并发数 (default 1)
  -code int
        请求成功的状态码 (default 200)
  -cpuNumber int
        CUP 核数默认为一核 (default 1)
  -d string
        调试模式 (default "false")
  -data string
        HTTP POST方式传送数据
  -http2
        是否开http2.0
  -k    是否开启长连接
  -m int
        单个host最大连接数 (default 1)
  -n uint
        请求数(单个并发/协程) (default 1)
  -p string
        curl文件路径
  -timeout int
        超时时间 单位 ,默认不设置
  -u string
        压测地址
  -v string
        验证方法 http 支持:statusCodejson webSocket支持:json

-n 是单个用户请求的次数,请求总次数 = -c* -n, 这里考虑的是模拟用户行为,所以这个是每个用户请求的次数。

安装完go-stress-testing命令之后,执行下面命令即可压测:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# 请求测试本地web服务
./go-stress-testing-win -c 1 -n 100 -u http://localhost:9090/rotating

# 使用debug模式请求测试本地web服务 会打印出网页请求内容
./go-stress-testing-win -c 1 -n 1 -d true -u http://localhost:9090/rotating

# 使用 curl文件(文件在curl目录下) 的方式请求百度
./go-stress-testing-win -c 1 -n 1 -p curl/baidu.curl.txt

# 压测webSocket连接
./go-stress-testing-win -c 10 -n 10 -u ws://127.0.0.1:8089/acc

一个完整的压测命令实例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
# 更多参数 支持 headerpost body
go run main.go -c 1 -n 1 -d true -u 'https://page.aliyun.com/delivery/plan/list' \
  -H 'authority: page.aliyun.com' \
  -H 'accept: application/json, text/plain, */*' \
  -H 'content-type: application/x-www-form-urlencoded' \
  -H 'origin: https://cn.aliyun.com' \
  -H 'sec-fetch-site: same-site' \
  -H 'sec-fetch-mode: cors' \
  -H 'sec-fetch-dest: empty' \
  -H 'referer: https://cn.aliyun.com/' \
  -H 'accept-language: zh-CN,zh;q=0.9' \
  -H 'cookie: aliyun_choice=CN; JSESSIONID=J8866281-CKCFJ4BUZ7GDO9V89YBW1-KJ3J5V9K-GYUW7; maliyun_temporary_console0=1AbLByOMHeZe3G41KYd5WWZvrM%2BGErkaLcWfBbgveKA9ifboArprPASvFUUfhwHtt44qsDwVqMk8Wkdr1F5LccYk2mPCZJiXb0q%2Bllj5u3SQGQurtyPqnG489y%2FkoA%2FEvOwsXJTvXTFQPK%2BGJD4FJg%3D%3D; cna=L3Q5F8cHDGgCAXL3r8fEZtdU; isg=BFNThsmSCcgX-sUcc5Jo2s2T4tF9COfKYi8g9wVwr3KphHMmjdh3GrHFvPTqJD_C; l=eBaceXLnQGBjstRJBOfwPurza77OSIRAguPzaNbMiT5POw1B5WAlWZbqyNY6C3GVh6lwR37EODnaBeYBc3K-nxvOu9eFfGMmn' \
  -data 'adPlanQueryParam=%7B%22adZone%22%3A%7B%22positionList%22%3A%5B%7B%22positionId%22%3A83%7D%5D%7D%2C%22requestId%22%3A%2217958651-f205-44c7-ad5d-f8af92a6217a%22%7D'

使用 curl文件进行压测

curl是Linux在命令行下的工作的文件传输工具,是一款很强大的http命令行工具。

使用curl文件可以压测使用非GET的请求,支持设置http请求的 method、cookies、header、body等参数。

curl文件可由以下两种方式生成:

I: chrome 浏览器生成 curl文件,打开开发者模式(快捷键F12),如图所示,生成 curl 在终端的执行命令。

依次选择 Network -> 选择需要的链接 -> Copy -> Copy as cURL

就能得到如下的内容:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
curl "http://localhost:9090/rotating" ^
  -H "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7" ^
  -H "Accept-Language: zh-CN,zh-TW;q=0.9,zh;q=0.8,en-US;q=0.7,en;q=0.6" ^
  -H "Cache-Control: max-age=0" ^
  -H "Connection: keep-alive" ^
  -H "Cookie: Goland-4a9a2012=5615decd-c03c-43d9-bba0-a91c3d6242b0; Webstorm-9bb8294=c01b90e9-5a82-40d1-a7a0-b02d3e4e4ea4" ^
  -H "Sec-Fetch-Dest: document" ^
  -H "Sec-Fetch-Mode: navigate" ^
  -H "Sec-Fetch-Site: none" ^
  -H "Sec-Fetch-User: ?1" ^
  -H "Upgrade-Insecure-Requests: 1" ^
  -H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36" ^
  -H "sec-ch-ua: ^\^"Google Chrome^\^";v=^\^"119^\^", ^\^"Chromium^\^";v=^\^"119^\^", ^\^"Not?A_Brand^\^";v=^\^"24^\^"" ^
  -H "sec-ch-ua-mobile: ?0" ^
  -H "sec-ch-ua-platform: ^\^"Windows^\^"" ^
  --compressed

II: postman 生成 curl 命令

生成内容粘贴到压测命令目录下的curl/baidu.curl.txt文件中,执行下面命令就可以从curl.txt文件中读取需要压测的内容进行压测了

1
2
# 使用 curl文件(文件在curl目录下) 的方式请求
go run main.go -c 1 -n 1 -p curl/baidu.curl.txt

实现

建议参考项目源码。项目目录结构:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
|____main.go                      // main函数,获取命令行参数
|____server                       // 处理程序目录
| |____dispose.go                 // 压测启动,注册验证器、启动统计函数、启动协程进行压测
| |____statistics                 // 统计目录
| | |____statistics.go            // 接收压测统计结果并处理
| |____golink                     // 建立连接目录
| | |____http_link.go             // http建立连接
| | |____websocket_link.go        // webSocket建立连接
| |____client                     // 请求数据客户端目录
| | |____http_client.go           // http客户端
| | |____websocket_client.go      // webSocket客户端
| |____verify                     // 对返回数据校验目录
| | |____http_verify.go           // http返回数据校验
| | |____websokcet_verify.go      // webSocket返回数据校验
|____heper                        // 通用函数目录
| |____heper.go                   // 通用函数
|____model                        // 模型目录
| |____request_model.go           // 请求数据模型
| |____curl_model.go              // curl文件解析
|____vendor                       // 项目依赖目录

web 压测

grpc压测

压测工具的比较

如何选择压测工具

这个世界上没有最好的,只有最适合的,工具千千万,选择一款适合你的才是最重要的。

在实际使用中有各种场景,选择工具的时候就需要考虑这些:

  • 明确你的目的,需要做什么压测、压测的目标是什么?
  • 使用的工具你是否熟悉,你愿意花多大的成本了解它?
  • 你是为了测试还是想了解其中的原理?
  • 工具是否能支持你需要压测的场景。
我的玫瑰,种在繁星中的一颗~
Built with Hugo
主题 StackJimmy 设计