Jade Dungeon

基础

性能测试

性能测试主要分类

负载测试(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

测试通过标准

  1. 平均响应时长满足测试指标要求。
  2. 90%响应时长满足测试指标要求。
  3. 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.batbin/jmeter.sh中配置。HEAP大小默认512m,根据经验 最大不要超过物理内存的一半。不然运行速度会变慢甚至内存溢出。

日志级别调整在jmeter.properties中的log_level.jmeter=INFO

以上属性也可以在GUI中设置:

sample

文档

  • 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.propertiesuser.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.shbin/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执行顺序规则

  1. 配置组件
  2. 前置处理器
  3. 定时器
  4. 采样器
  5. 后置处理器(除非服务器响应为空)
  6. 断言(除非服务器响应为空)
  7. 监听器(除非服务器响应为空)

作用域

断言等默认组件生效的范围是当前子树与下级子树,不会影响到上级子树。

配置组件(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测试计划

  1. 「Test Plan」下添加「Threads(Users) / Thread Group」
  2. 「Thread Group」下添加「Config Element / HTTP Request Defaults」设置请求的默认参数。
  3. 「Thread Group」下添加「Config Element / HTTP Cookie Manager」设置Cookie支持。
  4. 「Thread Group」下添加「Sampler / HTTP Request」设置Cookie支持。
  5. 「Thread Group」下添加「Listener / Graph Results」设置Cookie支持。

录制Web测试脚本

  1. 「Test Plan」下添加「Threads(Users) / Thread Group」。
  2. 「Thread Group」下添加「Config Element / HTTP Request Defaults」设置请求的默认参数。
  3. 「WorkBench」下添加「Non-test Elements / HTTPProxy Server」。
    • 配置端口号
    • Target Controller中选择「Test Plan / Thread Group」指明录制到哪个线程下面去。
    • Patterns to Include中添加匹配的模式,比如.*\.html.*\.gif.*
  4. 浏览器用代理访问以后线程组下会录有多个Sampler。
  5. 在线程组中添加「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