背景
在开发出的系统在交付上线时候,需要知晓整个系统的运行边界,通常情况下需要了解系统的性能和吞吐量。
关键词解释
- RT(响应时间):系统对请求从请求到做出的响应时间。
- TPS(吞吐量):系统在单位时间内处理请求事务的数量。
- QPS(每秒查询的能力):系统在执行的查询。
压测工具介绍
- jmeter:apache组织开发的基于Java的压力测试工具。
- ab:ab是apache自带的压力测试工具。
- siege:Siege是一个开源的压力测试和基准工具,属于Linux系统下的一个测试工具,完全使用C语言实现,可以对HTTP和FTP服务器进行负载和性能测试,siege的设计主要用于WEB的性能测试。
- wrk:一款针对 Http 协议的基准测试工具,它能够在单机多核 CPU 的条件下,使用系统自带的高性能 I/O 机制,如 epoll,kqueue 等,通过多线程和事件模式,对目标机器产生大量的负载。
- tcpcopy:网易的王斌开发的一款。
jmeter安装使用
Apache JMeter是Apache组织开发的基于Java的压力测试工具
安装
需要提前安装好对应的jdk版本
windows平台
1):下载安装包:点击链接 进入下载官网
2):解压:解压包后放在系统中自定义位置。
3):环境变量:在系统的全局或者某个用户下配置环境变量。变量名称为
JMETER_HOME
,变量值为D:\soft\jmeter\apache-jmeter-xxx
(步骤2中解压后的文件目录,bin
的上一层路径)。
4):在系统变量中的"CLASSPATH"追加
;%JMETER_HOME%\lib\ext\ApacheJmeter_core.jar;\%JMETER_HOME%\lib\jorphan.jar;%JMETER_HOME%\lib\logkit-1.2.jar"
。
注意:
a)分号和斜杠都为英文模式下的分号和斜杠,否则会出现未知错误。
b)如果没有
logkit-xxx.jar
包就需要手动去maven仓库下载,不展开详细讲述。
5):启动:打开相应文件夹,点击
jmeter.exe
即可启动。
mac平台
一般安装
1):下载:下载mac
对应的安装包,参考windows
下 下载步骤。
2):解压:使用命令tar``或者双击这个安装包。 3):运行:进入到相应的文件夹下
sh jemter``即可启动。
brew安装:
1):安装:终端使用命令brew install jmeter
2):启动:终端使用命令jmeter
即可。
linux平台
1):下载:可以同mac下载一样的安装包。也可使用命令wget http://archive.apache.org/dist/jmeter/binaries/apache-jmeter-3.2.zip
2):增加权限:进入相应的文件夹下面后chmod +x jemter
。
3):运行脚本:进入相应的文件夹目录执行./jmeter。
使用
1): 新建一个线程组
2): 设置线程参数
- 线程数(用户):想要模拟的虚拟用户的数量。
- 循环次数:设置一个虚拟用户循环多少次测试,默认为1。选择forever就永远不会停止,自动一直循环下去,只能手动停止。
-
Ramp-Up Period (in seconds)(虚拟用户增长时长):设置的虚拟用户访问url的时长,是在一个时间同时访问,还是在一段时间持续访问。
3): 添加被测试的接口url或者页面
4):点击运行
5):查看运行日志
6):新增监听,辅助用以压测结果
wrk
wrk
是一款简单的HTTP压测工具,托管在gitHub 上
wrk
的一个很好的特性就是能用很少的线程压出很大的并发量. 原因是它使用了一些操作系统特定的高性能 io 机制, 比如 select
,epoll
,kqueue
等. 其实它是复用了 ````redis的
ae异步事件驱动框架. 确切的说
ae事件驱动框架并不是
redis发明的, 它来至于
Tcl的解释器
jim```, 这个小巧高效的框架, 因为被 redis 采用而更多的被大家所熟知.
- 注意:wrk只能运行在unix环境,例如
linux
,mac
,solaris
安装
linux
下载
- 下载代码
git clone https://github.com/wg/wrk.git
或者进入github直接下载,或者使用wget https://github.com/wg/wrk.git
命令 - 进入下载目录
cd wrk/
- 编译wrk文件
make
- 创建软连接到制定目录
ln -s /usr/local/src/wrk/wrk /usr/local/bin
mac平台
安装
brew install wrk
安装成功
在控台台敲命令 wrk
出现
使用
参数解析
-c, --connections
跟服务器建立并保持的TCP连接数量
-d, --duration
压测时间
-t, --threads
使用多少个线程进行压测,压测时,是有一个主线程来控制我们设置的n个子线程间调度
-s, --script
指定Lua脚本路径
-H, --header
为每一个HTTP请求添加HTTP头
-latency
在压测结束后,打印延迟统计信息
--timeout
超时时间
-v, --version
打印正在使用的wrk的详细版本信息
注意:
代表数字参数,支持国际单位 (1k, 1M, 1G) 代表时间参数,支持时间单位 (2s, 2m, 2h)
统计信息分析
Running 30s test @ http://xxx
(压测时间30s)
8 threads and 200 connections
(共8个测试线程,200个连接)
Thread Stats Avg Stdev Max +/- Stdev
(平均值) (标准差)(最大值)(正负一个标准差所占比例)
Latency 46.67ms 215.38ms 1.67s 95.59%
(延迟)
Req/Sec 7.91k 1.15k 10.26k 70.77%
(处理中的请求数)
Latency Distribution
(延迟分布)
50% 2.93ms
75% 3.78ms
90% 4.73ms
99% 1.35s
(99分位的延迟:99%的请求在1.35s以内)
1790465 requests in 30.01s, 684.08MB read
(30.01秒内共处理完成了1790465个请求,读取了684.08MB数据)
Requests/sec: 59658.29
(平均每秒处理完成59658.29个请求)
Transfer/sec: 22.79MB
(平均每秒读取数据22.79MB)
使用lua脚本定制化压测
lua脚本共有三个阶段,启动阶段,运行阶段,结束阶段,wrk可以支持在这三个阶段进行定制化。
- 启动阶段
function setup(thread)
在脚本文件中实现setup方法,wrk就会在测试线程已经初始化但还没有启动的时候调用该方法。wrk会为每一个测试线程调用一次setup方法,
并传入代表测试线程的对象thread作为参数。setup方法中可操作该thread对象,获取信息、存储信息、甚至关闭该线程。 - 运行阶段
function init(args) --由测试线程调用,只会在进入运行阶段时,调用一次。支持从启动wrk的命令中,获取命令行参数;
function delay() --在每次发送request之前调用,如果需要delay,那么delay相应时间;
function request() --用来生成请求;每一次请求都会调用该方法,所以注意不要在该方法中做耗时的操作;
function response(status, headers, body) --在每次收到一个响应时调用;为提升性能,如果没有定义该方法,那么wrk不会解析headers和body;
- 结束阶段
function done(summary, latency, requests)
--在整个测试过程中只会调用一次,可从参数给定的对象中,获取压测结果,生成定制化的测试报告。 - 自定义可访问变量
wrk = {
scheme = "http",
host = "localhost",
port = nil,
method = "GET",
path = "/",
headers = {},
body = nil,
thread = ,
}
- 自定义方法
function wrk.format(method, path, headers, body) --根据参数和全局变量wrk,生成一个HTTP rquest string。
function wrk.lookup(host, service) --给定host和service(port/well known service name),返回所有可用的服务器地址信息。
function wrk.connect(addr) --测试与给定的服务器地址信息是否可以成功创建连接
- 使用案例
1: 携带json参数,post请求
wrk.method = "POST"
wrk.headers["Content-Type"] = "application/json"
wrk.body = '{"charset":"utf-8","data":{}}'
function request()
return wrk.format('POST', nil, nil, body)
end
使用命令 wrk -c 20 -t 8 -d 60 --script=/Users/wanter/foot/lua/wrk_post.lua --latency http://10.49.0.105:8081
2:打印出请求失败的请求
wrk.method = "POST"
wrk.headers["S-COOKIE2"]="a=2&b=Input&c=10.0&d=20191114***"
wrk.body = '{"time":"2021-07-21","data":{}}' --根据需求传自定义参数
wrk.headers["Host"]="api.shouji.**.com"
function response(status,headers,body)
if status ~= 200 then --将服务器返回状态码不是200的请求结果打印出来
print(body)
-- wrk.thread:stop()
end
end
3:实现随机header-cookie
id_arr = {}
falg = 0
wrk.method = "POST"
wrk.body = '{请求参数}'
function init(args)
for line in io.lines("integral/cookies.txt") do
print(line)
idArr[falg] = line
falg = falg+1
end
falg = 0
end
--wrk.method = "POST"
--wrk.body = "a=1"
--wrk.path = "/v1/points/reading"
request = function()
parms = idarr[math.random(0,4)] --随机传递文件中的参数
--parms = idarr[falg%(table.getn(idArr)+1)] 循环传递文件中的参数
wrk.headers["S-COOKIE2"] = parms
falg = falg+1
return wrk.format()
end
4:实现随机参数
id_arr = {};
function init(args)
id_arr[1] = "1";
id_arr[2] = "2";
id_arr[3] = "3";
id_arr[4] = "4";
end
request = function()
parms = id_arr[math.random(1,4)]
path = "/v1/points/reading?id="..parms
return wrk.format("GET",path)
end
ab
ab是apache自带的压力测试工具。ab非常实用,它不仅可以对apache服务器进行网站访问压力测试,也可以对或其它类型的服务器进行压力测试。
安装
windows下安装
1):下载工具包
请点击链接 到apache官网下载。
2):解压
用解压工具解压后放置在某一路径下即可。
3):配置环境变量
讲bin的路径配置到系统path中即可。
linux下安装
1):下载工具包
请点击链接 到apache官网下载。
2):工具包解压
tar -zxvf xxxxxx.zip
3):bin路径配置到path变量
# 或者 vim ~/.bash_profile
vim ~/.bashrc
# 在最后一行加上 将xxx替换成具体路径
export PATH=$PATH:/xxx/xxx/xxx/bin
# 保存后刷新下配置文件
source ~/.bashrc
4):或者使用版本管理工具安装
apt-get/yum -y install httpd-tools
mac下安装
1):预先安装apr和pcre
brew install apr
brew install pcre
2):下载安装包
浏览器打开链接,下载后解压到任意目录中。
3):编译
进入的解压后的目录中,依次执行一下命令
./configure
make
make install
常用基本命令介绍
1):参数详解:
格式:ab [options] [http://]hostname[:port]/path
参数说明:
-n
requests Number of requests to perform //在测试会话中所执行的请求个数(本次测试总共要访问页面的次数)。默认时,仅执行一个请求。
-c
concurrency Number of multiple requests to make //一次产生的请求个数(并发数)。默认是一次一个。
-t
timelimit Seconds to max. wait for responses //测试所进行的最大秒数。其内部隐含值是-n 50000。它可以使对服务器的测试限制在一个固定的总时间以内。默认时,没有时间限制。
-p
postfile File containing data to POST //包含了需要POST的数据的文件,文件格式如“p1=1&p2=2”.使用方法是 -p 111.txt 。 (配合-T)
-T
content-type Content-type header for POSTing //POST数据所使用的Content-type头信息,如 -T “application/x-www-form-urlencoded” 。 (配合-p)
-v
verbosity How much troubleshooting info to print //设置显示信息的详细程度 – 4或更大值会显示头信, 3或更大值可以显示响应代码(404, 200等), 2或更大值可以显示警告和其他信息。
-V
显示版本号并退出。
-w
Print out results in HTML tables //以HTML表的格式输出结果。默认时,它是白色背景的两列宽度的一张表。
-i
Use HEAD instead of GET // 执行HEAD请求,而不是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. -C “c1=1234,c2=2,c3=3″ (repeatable) //-C cookie-name=value 对请求附加一个Cookie:行。 其典型形式是name=value的一个参数对。此参数可以重复,用逗号分割。
提示:可以借助session实现原理传递 JSESSIONID参数, 实现保持会话的功能,如-C 'c1=1234,c2=2,c3=3, JSESSIONID=FF056CD16DA9D71CB131C1D56F0319F8'。
-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. //-P proxy-auth-username:password 对一个中转代理提供BASIC认证信任。用户名和密码由一个:隔开,并以base64编码形式发送。无论服务器是否需要(即, 是否发送了401认证需求代码),此字符串都会被发送。
-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.
-g
filename Output collected data to gnuplot format file.
-e
filename Output CSV file with percentages served
-h
Display usage information (this message)
//-attributes 设置属性的字符串. 缺陷程序中有各种静态声明的固定长度的缓冲区。另外,对命令行参数、服务器的响应头和其他外部输入的解析也很简单,这可能会有不良后果。它没有完整地实现 HTTP/1.x; 仅接受某些’预想’的响应格式。 strstr(3)的频繁使用可能会带来性能问题,即你可能是在测试ab而不是服务器的性能。
2):返回参数详解
Server Software: nginx/1.14.0
// nginx 版本 1.14.0
Server Hostname: youxi.test
// 服务器主机
Server Port: 443
//端口号
SSL/TLS Protocol: TLSv1.2,ECDHE-RSA-AES256-GCM-SHA384,2048,256 //SSL/TLS
协议
TLS Server Name: youxi.test
// TLS服务器名
Document Path: /api/v1/test/
//文档地址
Document Length: 30 bytes
//文档长度
Concurrency Level: 10
//并发数
Time taken for tests: 22.428 seconds
// 整个持续时间
Complete requests: 100
// 完成请求数
Failed requests: 74
// 失败请求次数
(Connect: 0, Receive: 0, Length: 74, Exceptions: 0)
Non-2xx responses: 30
Keep-Alive requests:
0
Total transferred: 258248 bytes
//整个场景中的网络传输量
HTML transferred: 229838 bytes
//整个场景中的HTML内容传输量
Requests per second: 4.46 [#/sec] (mean)
//相当于 LR 中的 每秒事务数 ,后面括号中的 mean 表示这是一个平均值
Time per request: 2242.769 [ms] (mean)
//相当于 LR 中的 平均事务响应时间 ,后面括号中的 mean 表示这是一个平均值
Time per request: 224.277 [ms] (mean, across all concurrent requests)
//每个请求实际运行时间的平均值
Transfer rate: 11.24 [Kbytes/sec] received
//平均每秒网络上的流量,可以帮助排除是否存在网络流量过大导致响应时间延长的问题
使用例子
1):正常使用
ab -c 10 -n 100 http://a.ilanni.com/index.php
-c10表示并发用户数为10
-n100表示请求总数为100
2):post携带参数
abs -n 10 -c 10 -p d:\para.txt -T application/json https://xxx/login
其中 para.txt 中携带的是json请求参数 也有方案说要将.txt后缀修改的.json后缀才生效
siege
Siege是一个压力测试和评测工具,设计用于WEB开发这评估应用在压力下的承受能力:可以根据配置对一个WEB站点进行多用户的并发访问,记录每个用户所有请求过程的相应时间,并在一定数量的并发访问下重复进行。
安装
windows平台
1)下载:点击链接 下载zip包。
2)解压:解压双层包,将解压后的文件配置到c盘根目录。(官方推荐是根目录)。
3)环境变量:将该文件夹放置在系统的环境变量中,即可在全局命令窗口中使用。(详见系统的环境变量设置部分,上面部分操作也有添加环境变量部分)。
环境变量中添加
C:\siege-windows
linux
1)安装openssl:有些请求是https的,为了支持该协议,需要额外安装openssl。(如没有安装git请安装或去github手动下载将包上传)
git clone https://github.com/openssl/openssl
cd openssl
./config --prefix=/usr/local/openssl
make
make install
openssl version``
2)安装siege:和openssl安装类似,都是使用编译安装的。
wget http://download.joedog.org/siege/siege-latest.tar.gz
tar zxvf siege-4.0.5.tar.gz
cd siege-4.0.5
make clean
./configure --prefix=/usr/local/siege --with-ssl=/usr/local/openssl
make
make install
3)修改配置:使用vi命令修改当前~/.siege/siege.conf文件中的limit的值。
mac
1)brew模式安装:brew install siege
即可。
说明和一般使用
参数详解
-
-V, –version
: 打印版本号 -
-h, –help
: 打印帮助信息 -
-C, –config
: 打印当前配置信息 -
-g, –get
: 拉去http头信息 -
-p, –print
:打印 -
-c, –concurrent=NUM
:并发用户数量,默认10个 -
-r, –reps=NUM
:运行次数 -
-d, –delay=NUM
:随机时间延迟(秒) -
-b, –benchmark
:请求没有延迟 -
-i, –internet
:模拟网络用户随机点击url -
-f, –file=FILE
:选择指定的URL文件 -
-R, –rc=FILE
:指定siegerc文件 -
-l, –log[=FILE]
:日志文件,默认是 PREFIX/var/siege.log -
-H, –header="text"
:给请求添加头,支持多个 -
-A, –user-agent=”text”
:给请求设置User-Agent -
-T, –content-type=”text”
:给请求设置Content-Type
响应详解
-
Transactions
: 命中次数 -
Availability
: 命中次数 -
Elapsed time
: 整个压测花费的时间,从第一个开始到最后一个结束 -
Data transferred
: 整个压测数据传输的总和 -
Response time
:响应时间是响应每个模拟用户请求所花费的平均时间 -
Transaction rate
:事务速率是服务器每秒能够处理的平均事务数. 简而言之:事务除以经过的时间。 -
Throughput
:吞吐量是从服务器到所有模拟用户每秒传输的平均字节数 -
Concurrency
:并发是同时连接的平均数,这是一个随服务器性能下降而上升的数字 -
Successful transactions
:成功事务次数 -
Failed transactions
:失败事务次数 -
Longest transaction
:最长事务时间 -
Shortest transaction
:最短事务时间 -
Failed transactions
:失败事务次数
使用案例
1)基础引用:使用并发线程(连接)10测试基准http://127.0.0.1,持续60秒
siege -c10 -t60s http://127.0.0.1
2)不限制并发:测试基准http://127.0.0.1,不限制并发线程(连接)60秒
siege -b -t60s http://127.0.0.1
3)输出日志文件:测试和输出日志到文件
siege -c10 -t60s http://127.0.0.1 > log.txt
流量压测
可以将线上流量拷贝到测试机器,实时的模拟线上环境。在不影响线上用户的情况下,使用线上流量进行测试,以尽早发现bug。也可以通过放大流量,进行压力测试,评估系统承载能力。
tcpcopy可以从线上服务器的IP层抓取在线请求的数据包,修改相关属性,利用raw socket output技术(packet injection 技术之一)将其发送给测试服务器进行测试。
发送到测试服务器的数据包会在TCP/IP协议栈被识别,其中带有payload(tcp data)的数据包最终进入到测试服务器的上层应用(如nginx),上层应用在处理完请求之后,将响应传递给测试服务器的TCP/IP协议栈。
工作原理
1:一个访问到达线上前端机;
2:socket数据包在ip层被拷贝了一份传给tcpcopy进程;
3:tcpcopy修改包的目的及源地址,发给目标测试机;
4:拷贝的包到达目标测试机
5:目标测试机的nginx处理访问,并返回结果;
6:返回结果在ip层被截获、丢弃,由intercpet进程拷贝返回结果的ip header并返回;
7:ip header被发送给线上前端机的tcpcopy进程。
安装和使用
安装和使用暂且比较复杂,且没有实验数据。故后续补全。