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
的增强和更现代的替代,更为用户友好。
安装完之后,可以执行如下命令查看软件包的文件列表:
命令将显示 apache2-utils
软件包中所有文件的路径。
也可以执行如下命令查看ab
版本:
正常显示版本代表安装成功。
卸载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
|
用法
-
编写压测脚本 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 # 执行事务之间用户等待时间的上界(单位:毫秒)
|
-
启动压测
1
2
|
# -f 指定测试脚本 host协议是http 不是https
locust -f locust_test.py --host=http://localhost:9090
|
-
访问 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的功能过于强大,这里暂时不介绍用法,可以查询相关文档使用(参考文献中有推荐的教程文档)
云压测
简介
顾名思义,就是将压测脚本部署在云端
,通过云端对对我们的应用进行全方位压测,只需要配置压测的参数,无需准备实体机,云端自动给我们分配需要压测的云主机,对被压测目标进行压测。
云压测的优势:
- 轻易的实现分布式部署
- 能够模拟海量用户的访问
- 流量可以从全国各地发起,更加真实的反映用户的体验
- 全方位的监控压测指标
- 文档比较完善
当然了云压测是一款商业产品,在使用的时候自然还是需要收费的,而且价格还是比较昂贵的~
阿里云 性能测试 PTS
PTS
(Performance Testing Service)是面向所有技术背景人员的云化测试工具。
有别于传统工具的繁复,PTS以互联网化的交互,提供性能测试、API调试和监测等多种能力。自研和适配开源的功能都可以轻松模拟任意体量的用户访问业务的场景,任务随时发起,免去繁琐的搭建和维护成本。更是紧密结合监控、流控等兄弟产品提供一站式高可用能力,高效检验和管理业务性能。
阿里云同样还是支持渗透测试,通过模拟黑客对业务系统进行全面深入的安全测试。
腾讯云 压测大师 LM
通过创建虚拟机器人模拟多用户的并发场景,提供一整套完整的服务器压测解决方案。
go-stress-testing
简介
go-stress-testing
是go语言实现的简单压测工具,源码开源、支持二次开发,可以压测http
、webSocket请求
、私有rpc调用
,使用协程模拟单个用户,可以更高效的利用CPU资源。
项目地址 https://github.com/link1st/go-stress-testing
安装
-
直接安装可执行文件
地址:go-stress-testing
-
源码运行
把项目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 支持:statusCode、json 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
|
# 更多参数 支持 header、post 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压测
压测工具的比较
如何选择压测工具
这个世界上没有最好的,只有最适合的,工具千千万,选择一款适合你的才是最重要的。
在实际使用中有各种场景,选择工具的时候就需要考虑这些:
- 明确你的目的,需要做什么压测、压测的目标是什么?
- 使用的工具你是否熟悉,你愿意花多大的成本了解它?
- 你是为了测试还是想了解其中的原理?
- 工具是否能支持你需要压测的场景。