基础
性能测试
性能测试主要分类
- 负载测试(Load Testing)
- 确保系统在超过最大预计工作量时也能正常运行。
- 压力测试(Stress Testing)
- 不断施加压力,观察系统状况,赶到出现瓶颈或崩溃。
- 容量测试(Volume Testing)
- 确定系统可处理同时在线最大用户数。
性能测试主要指标
基本指标:CPU占用率、内存占用率、数据库连接池。
B-S架构普遍关注
- Avg Rps
- 平均每秒响应次数 = 总请求次数 / 秒数。
- Avg time to last byte per terstion(mstes)
- 平均每少业务脚本迭代次数。
- Successful Rounds
- 成功请求。
- Failed Rounds
- 失败的请求。
- Successful Hits
- 成功点击次数。
- Failed Hits
- 失败的点击次数。
- Successful Hits Per Second
- 每秒成功点击次数。
- Failed Hits Per Second
- 每秒失败的点击次数。
- Attempted Connections
- 尝试连接数。
- Throughtput
- 吞吐率。
C-S架构普遍关注
- User Connections
- 用户连接数。
- Number of Deadlocks
- 数据库死锁。
- Butter Cache Hit
- 数据库缓存命中情况。
性能测试基本方案
响应时长
关键功能 | 平均使用次数 | 平均用户数 | 高峰时段用户数 | 平均响应时长 | 要接受最长响应时长 | 使用时间段 |
---|---|---|---|---|---|---|
XXX 功能 | 20,000 | 23,000 | < 4s | <= 7s | 8:00 ~ 21:00 | |
XXX 功能 | 20,000 | 23,000 | < 4s | <= 7s | 8:00 ~ 21:00 | |
XXX 功能 | 20,000 | 23,000 | < 4s | <= 7s | 8:00 ~ 21:00 | |
XXX 功能 | 20,000 | 23,000 | < 4s | <= 7s | 8:00 ~ 21:00 | |
XXX 功能 | 20,000 | 23,000 | < 4s | <= 7s | 8:00 ~ 21:00 |
测试环境指标折算
\[ 测试环境平均并发数 = \frac{ 最大在线人数 \times 1.1 }{ \frac{生产环境机器数}{测试环境机器数} \times \frac{生产环境内存}{测试环境内存} } \]每秒增加5个用户,直到达到平均并发数量。然后再持续运行几个小时。
后台监控
监控对象 | 指标 | 工具 |
---|---|---|
应用服务器 | CPU、MEM、IO | openview |
数据库服务器 | CPU、MEM、IO | openview |
数据库 | TOP、SQL等 | APM |
中间件 | 队列 | Console |
测试通过标准
- 平均响应时长满足测试指标要求。
- 90%响应时长满足测试指标要求。
- 2小时压力测试中脚本没有出错。
JMeter概览
主要工具
- Test Plan(测试计划):整个的测试脚本。
- Thread Group(线程组):模拟一组用户,大家都用同样的测试脚本。
- WorkBench(工作台):暂时不用的测试元素,不会在保存测试计划时一起被保存。
- Configuration Elements(配置元素):存放测试脚本的共享信息。
- Samplers(采样器):发请求到服务器。
- Pre-Processors(前置定时器):采样器执行前。
- Post-Processors(后置定时器):采样器执行后。
- Logic Controllers(逻辑控制器):控制执行顺序。
- Listener(监听器):收集测试结果。
- Assertions(断言):判断返回结果是否符合预期。
- Timers(定时器)。
主要结果字段
- Label:HTTP请求的名称。
- Samples:本次测试中一共发了多少请求。
- Average:请求或事务的平均时长。
- Median:中位数(50%用户)的响应时长。
- 90% Line:90%用户的响应时长。
- Min:最小时长。
- Max:最大时长。
- Error %:错误率。
- Throughput:每秒完成的请求或事务数量。
- KB/Sec:每秒收到的数据量。
配置
JVM参数在bin/jmeter.bat
或bin/jmeter.sh
中配置。HEAP
大小默认512m
,根据经验
最大不要超过物理内存的一半。不然运行速度会变慢甚至内存溢出。
日志级别调整在jmeter.properties
中的log_level.jmeter=INFO
。
以上属性也可以在GUI中设置:
文档
-
docs
目录下是Java Docs。 -
printable_docs/usermanual
用户手册。-
component_reference.html
是最常用的核心组件。
-
Ant支持
extras
目录下提供了Ant构造支持。JMeter把测试数据生成的.jtl
文件放到extras
目录下,运行:
ant -Dtest=data.jtl report
生成测试统计报表。
如果用户有自己扩展包,直接放lib
下。
运行JMeter
Windows下:
-
jmeter.bat
:GUI启动 -
jmeter-t.cmd
:加载JMX文件,GUI -
jmeter-n.cmd
:加载JMX文件,非GUI -
jmeter-n-r.cmd
:加载JMX文件,非GUI,远程 -
jmeter-server.bat
:服务器模式 -
mirror-server.cmd
:镜像服务器,非GUI -
shutdown.cmd
:关闭非GUI实例(优雅地) -
stoptest.cmd
:关闭非GUI实例(中断式)
添加启动参数:
set JVM_ARGS="-Xms1024m -Xmx1024m =Dpropname=propvalue" jmeter -t test.jmx ...
Unix下:
-
jmeter
:GUI启动 -
jmeter.sh
:GUI启动,不带JVM参数 -
jmeter-server
:服务器模式 -
mirror-server.sh
:镜像服务器,非GUI -
shutdown.sh
:关闭非GUI实例(优雅地) -
stoptest.sh
:关闭非GUI实例(中断式)
添加启动参数:
JVM_ARGS="-Xms1024m -Xmx1024m =Dpropname=propvalue" jmeter -t test.jmx ...
classpath
-
lib
:公用包,如测试数据库的JDBC驱动,测试JMS的类。 -
lib\ext
:JMeter核心类库、组件与补丁都放在下。如果自己写的扩展组件也放这里。 如果不想把扩展包放在这里,就要在jmeter.properties
文件中定义search_paths
。 这里只放JMeter用的组件,不要放公用包。 -
lib\junit
:Junit脚本。 -
$JAVA_HOME/jre/lib/ext
下的公用包。 -
jmeter.properties
中定义user.classpath
属性。
注意:
-
其他以「java-jar」方式启动的方式一样,JMeter会忽视
CLASSPATH
变量。要在另外 在-jar
的-classpath
或-cp
中指定。 - JMeter只查找jar,忽略zip。
代理服务器
启动jmeter
命令后面加上参数:
-
-H
:代理服务器的IP -
-P
:代理服务器的端口 -
-u
:代理服务器用户名 -
-u
:代理服务器密码 -
-N
:指定哪些目标不用代理服务器
用命令行方式运行
-
-n
:以命令行运行 -
-t [file.jmx]
:JMX脚本文件 -
-l [file.jtl]
:JTL采样数据文件 -
-j [file]
:JMeter日志文件 -
-r
:在远程remote_hosts
定义的服务器上运行测试 -
-R [server-list]
:在指定的远程服务器上运行测试
服务器模式
jmeter-server
以服务器模式运行,在另一台机器上可以通过GUI来遥控。
jmeter-server -H my.proxy.server -P 8000
如果希望远程服务器在单次运行以后退出,指定JMeter属性server.exitaftertest=true
。
以命令行在客户端运行测试:
jmeter -n -t testplan.jmx -r [-Gprop=val] [-Gglobal.properties] [-Z]
-
-G
:定义要在服务器中设置的JMeter属性。 -
-Z
:测试结束后退出服务器。 -
-Rserver1,serve2
:可以代替-r
用来指定服务器,但不会改变remote_hosts
属性。
在命令行中重置JMeter属性
在不修改jmeter.properties
文件的情况下,直接修改属性:
-
-Dprop=value
:定义Java系统属性。 -
-Jprop=value
:定义本地JMeter属性。 -
-Gprop=value
:定义JMeter属性并影响远程服务器。 -
-Gpropertyfile
:指定包含属性的文件。 -
-Lcategory=priority
:重置日志设置,对特定类型的日志设定优先级。
例子:
jmeter -Duser.dir=/home/mstover/jmeter_stuff \ -Jremote_hosts=127.0.0.1 -Ljmeter.engine=DEBUG
配置JMeter
属性配置在bin/jmeter.properties
里。
用户还可以根据它在bin
目录下建立system.properties
和user.properties
,
JMeter会加载它们分别作为系统配置和用户配置。
-
system.properties
:会在-S
和-D
参数前加载。 -
user.properties
:在初始属性文件之后、-q
和-J
参数之前加载。
常见属性:
-
ssl.provider
:SSL实现类,可以改成自己实现的。 -
xml.parser
:默认org.apache.xerces.parsers.SAXParser
。 -
remote_hosts
:逗号分隔的多个主机。 -
not_in_menu
:要排除的测试组件列表。 -
search_paths
:搜索扩展类的路径。 -
user.classpath
:搜索公用类的路径
JMeter脚本录制
基本操作
- 添加测试组件:要添加的地方「右键 > 合并 > 选择外部文件」。
- 组件可以直接拖动,用来调整顺序。
-
运行:「运行 > 启动」或是
Control + R
。 -
停止所有线程:
Control + .
,在默认超时时间内检查是否全部线程停止。 如果没有停止,弹框报错,必须要退出JMeter才能恢复干净的执行环境。 -
关闭:
Control + ,
,要求线程在当前工作完成后停止,不会中断采样器的工作。 关闭对话框会一直处于激活状态,赶到所有线程都已经停止。 -
命令行状态下,使用
bin/shutdown.sh
或bin/stoptest.sh
脚本来关闭。
常用测试组件
线程组
「逻辑控制器」与「采样器」必须在线程组下; 其他的组件(如监听器)可以在测试计划下。
- Number of Threads:最大线程数量。
- Ramp-Up Period:达到最大线程数量所需要的秒数。建议一开始设置值等于最大线程数。 然后再一点点减少。
- Loop Count:循环次数
-
Scheduler:选择以后,还可以定义启动时间、结束时间、启动延迟、持续时间。
- 「启动延迟」会让「启动时间」无效。
- 「持续时间」会让「结束时间」无效。
控制器:采样器
采样器(Sampler)发送请求,主要包括:
- FTP Request
- HTTP Request
- JDBC Request
- Java Object Request
- LDAP Request
- SOAP/XML-RPC Request
- WebService(SOAP) Request
每一类采样器还可以在 Config Element 里找到对应的 Request Default, 可以给多个采样配置统一的默认参数。
采样器还可以加上断言。
控制器:逻辑控制器
主要包括:
- Test Plan
- Thread Group
- Once Only COntroller:比如登录逻辑,只执行一次。
- Login Request (an HTTP Request)
- Load Search Page (HTTP Samper)
- Interleave Controller
- Switch Controller:在每个循环中交替执行多个逻辑中的一个。
- HTTP Default Request (Configuration Element)
- Cookie Manager (Configuration Element)
监听器
记录返回的结果,以图表等多种形式。
定时器
默认情况下,请求的发送没有间歇。定时器可以给加上间隔。
断言
检查某个查询响应中的特定信息,兼容Per的正则。断言会影响作用域中所有的采样器, 如果要限制就要让断言成为某个采样器的子类。
配置组件
配置组件只对其所在的测试树分支有效,如果在逻辑控制器里放一个HTTP Cookie管理器, 那就Cookie管理器只在同一个逻辑控制器里的其他逻辑控制器生效。
和用户的习惯一样,内部作用域的配置会覆盖外部作用域的设置。
前置处理器
后置处理器
JMeter测试脚本规则
JMeter执行顺序规则
- 配置组件
- 前置处理器
- 定时器
- 采样器
- 后置处理器(除非服务器响应为空)
- 断言(除非服务器响应为空)
- 监听器(除非服务器响应为空)
作用域
断言等默认组件生效的范围是当前子树与下级子树,不会影响到上级子树。
配置组件(HTTP信息头管理器、Cookie管理器、HTTP授权管理器)与默认组件不同, 默认组件被合并为一系列的变量值(采样器可以访问),而配置组件的设置不会被合并。 同一个作用域里的多个配置组件只有一个会生效,而且目前无法指定生效的是哪一个。
JMeter属性与变量
JMeter属性是全局的,统一定义在jmeter.properties
。
通过函数_p
可以取得属的值。
JMeter变量可以通过「测试计划」和配置组件「用户定义变量」定义。 变量是局部的,每个测试线程中的变量 可以 是不同的。
使用变量参数化测试
测试人员可以在「测试计划」中命名变量:
HOST www.example.com THREADS 10 LOOPS 20
在测试计划中可以用\({HOST}
、\){THREADS}
来引用测试变量。
如果对并发压力的要求更加高的要求,最好使用JMeter属性,例如:
HOST ${_P(host, www.example.com)} THREADS ${_P(threads, 10)} LOOPS ${_P(loops, 20)} #
这些属性的值可以从命令行中设置属性的值:
jmeter ..... -Jhost=www.example2.com -Jloops=13
Web测试脚本
创建Web测试计划
- 「Test Plan」下添加「Threads(Users) / Thread Group」
- 「Thread Group」下添加「Config Element / HTTP Request Defaults」设置请求的默认参数。
- 「Thread Group」下添加「Config Element / HTTP Cookie Manager」设置Cookie支持。
- 「Thread Group」下添加「Sampler / HTTP Request」设置Cookie支持。
- 「Thread Group」下添加「Listener / Graph Results」设置Cookie支持。
录制Web测试脚本
- 「Test Plan」下添加「Threads(Users) / Thread Group」。
- 「Thread Group」下添加「Config Element / HTTP Request Defaults」设置请求的默认参数。
-
「WorkBench」下添加「Non-test Elements / HTTPProxy Server」。
- 配置端口号
- Target Controller中选择「Test Plan / Thread Group」指明录制到哪个线程下面去。
-
Patterns to Include中添加匹配的模式,比如
.*\.html
、.*\.gif
、.*
。
- 浏览器用代理访问以后线程组下会录有多个Sampler。
- 在线程组中添加「Listener / Aggregate Report」。
Badboy录制HTTPS脚本
Badboy类似一个浏览器,可以录下操作。然后导出为JMX格式给JMeter。
URL回写处理的会话
有些网站禁用Cookie,而是用URL回写来保存会话。这时要在HTTP Request里配置 「Session Argument Name」值为SessionId参数名。
使用HTTP信息头管理
HTTP Header Manager应该像是HTTP Cookie Manager一样,尽可能地放在线程组一级。 除非在有些特殊的情况下,希望不同的线程有不同的请求头。
数据库性能测试
-
JDBC驱动放在
lib
目录下。 -
线程组下添加「Config Element / JDBC Connection Configuration」。
- Variable Name Bound to Pool:两个测试计划中唯一,用来区分不同的连接配置。
- Database URL
- JDBC Driver Class
-
线程组下添加「Sampler / JDBC Request」。
- Variable Name Bound to Pool指定一个现有的配置名字。
- 输入SQL语句。
常见的数据库配置:
# MySQL com.mysql.jdbc.Driver # classname jdbc:mysql://localhost:3306/mydb # URL # Oracle oracle.jdbc.driver.OracleDriver jdbc:oracle:thin:@192.168.0.126:1521:ydgl