一, 接口及数据库压测
1. http(s)接口测试
a)打开 Jmeter, 右键测试计划 -- 添加 --Threads(users)-- 线程组
在线程组属性中可以设置线程数, Ramp-Up Period(in seconds)(即开始测试后在多少秒内达到设置的线程数 (并发数)) 以及循环次数. 默认都是 1, 即在一秒内起一个线程发起一次请求.
b)右键线程组 -- 添加 --Sampler--HTTP 请求
在 web 服务器区域设置测试接口的服务器名或 ip, 端口号, 连接或响应超时时间(ms), 在 HTTP 请求区域设置接口的协议, 方法, 编码以及路径, 在同请求一起发送参数区域点击添加按钮, 添加接口所需的参数, 需要几个添加几个. 填写示例如下:
完成 a),b)两步后, 一个最简单的 HTTP 请求类型的接口就配置完成了, 接下来需要配置对测试过程及结果的监控和记录.
c)右键线程组 -- 添加 -- 监听器 -- 查看结果树, 右键线程组 -- 添加 -- 监听器 -- 聚合报告
查看结果树用来查看单次请求的请求及响应情况, 包括请求耗时, 请求参数, 响应结果等, 具体示例如下:
测试结束可以在聚合报告中查看本次测试的整体性能指标, 主要看平均响应时间, 90%line, 错误率, Throughput 以及网络传输速率.
平均响应时间: 默认情况下是单个 Request 的平均响应时间(ms)
Median: 中位数, 也就是 50% 请求的响应时间
90%line:90% 的请求的响应时间
错误率: 本次测试中失败的请求数在所有请求中所占的比例
Throughput: 简称 tps, 默认情况下表示每秒处理的请求数, 也就是指服务器处理能力, tps 越高说明服务器处理能力越好
网络传输速率: 每秒从服务器端接收到的数据量, 当系统性能瓶颈不在于服务端处理速度, 而在于网络传输速率时, 提高网络传输速率在一定程度上能提高 Throughput
d)当需要使用大量数据源压测时, 可以右键接口名 -- 添加 -- 配置元件 --CSV Data Set Config 工具从本地加载事先准备好的. txt 或. CSV 文件, 如有多个参数在文件里可以用, 或 tab 分隔. 然后在接口的参数列表中使用 ${参数名}调用文件里的参数. 示例如下:
Filename: 和脚本 (保存的压测文件) 同路径只需填写文件名称, 如果不是需填写全路径
File encoding: 编码和文件保持一致即可, 默认是 ANSI, 如有中文建议 utf-8
Variable names: 参数名称, 参数之间可用, 或 tab 分隔
Delimiter: 分隔符
Allow Quoated data: 双引号相关, 例: 如果参数中需包含, 或者 " 等, 该项可以选择 True
Recycle on EOF: 设置为 True 后, 允许循环取值
Stop Thread EOF: 当 Recycle on EOF 为 false 并且 Stop Thread EOF 为 true, 则读完 CSV 文件中的记录后, 停止运行, 线程数及执行次数无效
Sharing Mode: 共享模式:
All threads: 所有线程, 所有线程循环取值, 线程 1 取第一行, 线程二取下一行
Current thread group: 当前线程组, 各个线程组分别循环取值
Current thread: 当前线程, 该测试计划内的所有线程都取第一行
(ps: 以上所说的接口不涉及登录, 涉及登录的也简单, 添加个 HTTP Cookie 管理器和登录接口即可)
2. 数据库压测
a) 加载数据库驱动程序
在测试计划中添加 Oracle 数据库的驱动程序 jar 包, 添加的 jar 包要与所压测的 Oracle 数据库版本一致, jar 包放在 Jmeter 的 lib 目录下, 我们用的是 ojdbc6.jar 这个 jar 包. 示例如下:
b) 与测试接口一样, 添加线程组
这里设置并发数和循环次数, 和测试接口一样
c) 右键线程组 -- 添加 -- 配置元件 --JDBC Connection Configuration
在次界面进行连接具体数据库的配置, 示例如下:
Variable Name:JDBC Request 中的 Variable Name 要和其保持一致, 这样才能正确调用此配置的数据库
Max Number of Connection: 最大连接数, 一般和线程数比较接近, 可设置为线程数的 1/5, 但一般数据库都有最大连接数限制, 如果连接数过大, 可能需要调优 JVM 或数据库的连接数配置
Database URL: 不同数据库的 URL 不一样, Oracle 的长这样: jdbc:oracle:thin:@10.14.201.203:1555:templatedb
JDBC Driver class: 填固定的 oracle.jdbc.driver.OracleDriver
d) 右键线程组 -- 添加 --Sampler--JDBC Request
这里的 Variable Name 和 JDBC Connection Configuration 中的要一致, 此外由于是查询, Query Type 这里选择 Select, 如果是插入和删除则是 Update
二, Jmeter 配置优化及常见问题分析
Jmeter 的一些默认配置较为保守, 高并发压测中很可能会由于配置不满足测试场景, 从而出现一些非被测系统的性能问题而是测试工具的问题, 此时可以通过修改 Jmeter 的默认配置来尽可能规避这些问题
a) 高并发测试过程中, Jmeter 出现内存溢出错误
出现这个问题, 一般是由于 Jmeter 的 JVM 堆内存设置的过小, 找到 JMeter bin 目录下的 jmeter.bat 文件, 用记事本等文本工具打开, 编辑
找到如下内容,
- rem See the unix startup file for the rationale of the following parameters,
- rem including some tuning recommendations
- set HEAP=-Xms512m -Xmx512m
- set NEW=-XX:NewSize=128m -XX:MaxNewSize=128m
- set SURVIVOR=-XX:SurvivorRatio=8 -XX:TargetSurvivorRatio=50%
- set TENURING=-XX:MaxTenuringThreshold=2
修改带背景色, 文字带颜色内容如下
- set HEAP=-Xms1024m -Xmx1024m
- set NEW=-XX:NewSize=640m -XX:MaxNewSize=640m
说明:
-Xms512m: 初始化堆内存大小 -Xmx512m: 最大堆内存大小, 这里的内存大小建议为 512 的整数倍, 可以根据机器实际内存进行合理的设置, 建议最大值 - Xmx 不要超过剩余物理内存的 50%
通常会将 -Xms 与 -Xmx 两个参数的配置相同的值, 其目的是为了能够在 java 垃圾回收机制清理完堆区后不需要重新分隔计算堆区的大小而浪费资源
set NEW=-XX:NewSize=640m -XX:MaxNewSize=640m
1)-XX:newSize: 新生代初始内存的大小, 应该小于 -Xms 的值
2) -XX:MaxnewSize: 表示新生代可被分配的内存的最大上限; 当然这个值应该小于 - Xmx 的值, 因为新生代占内存来自整个堆内存. 为了优化 GC(内存垃圾回收), 最好设置 - XX:MaxnewSize 值约等于 - Xmx 的 1/3
注意: jvm 在执行 GC 时, 会停止工作. MaxnewSize 的增大, 可以降低 GC 频率
b) 指定测试结果数据存储文件
如上, JMeter 中很多插件都提供了结果文件存储设置, 为了避免请求测试结果数据都存储到 JVM 内存(因常驻数据无法回收, 量大的话会很快压垮 jmeter), 需要为插件指定一个文件, 把数据存储到该文件, 测试前务必要进行这类设置检查.
另外, 通常结果文件要保存为 CSV 格式(比起 xml 格式, 可以少写入好多数据)
c) 针对某些监听器, 设置仅记录错误日志
根据第二点的分析, 针对某些监听器(比如查看结果树), 我们只需关注错误日志信息的情况下, 需要勾选 "仅日志错误", 这样只会保存错误日志到内存, 数据不会多.
d) 通过保存的结果文件 "重绘" 测试监听结果图表
针对一些不需要在测试过程中 "实时" 查看的测试 "监听器" 图表, 可以考虑 "线下" 生成图表. 具体做法如下所例.
eg:
如上图, 这里添加了监听器 "聚合报告" 插件, 因为我们需要查看相关数据, 比如吞吐量, 请求耗时等, 但是我们不需要实时查看结果, 所以把对监听结果 "聚合报告" 给禁用了(更重要的别因是聚合报告非常消耗 CPU.
然后, 我们添加了监听器 "Simple Data Writer", 并设置结果数据存放文件(例子中为 "测试结果. csv"), 如果有必要的话还可以点击 Configure 设置需要保存的条目, 文件格式等(通常默认设置就可以了)
注: Simple Data Writer: 该监听器可用于记录测试结果到某个文件, 但不提供 ui 展示.
最后, 等测试完成后, 我们在插件控制面板中, 点击浏览按钮, 打开上述保存的文件, 结果如下, 可以看到生成的分析数据了.
注意:
1)Log/Display Only: 仅错误日志 Successes
这里如果勾选了仅错误日志, 那么记录数据, 展示数据的时候只会记录 / 展示错误日志, 如果勾选了 Successes, 则只会记录 / 展示成功执行的记录, 两个都不勾选, 则默认记录全部信息. 这点针对其它插件也是如此
2)打开保存的数据文件, 默认会分析数据文件中的所有内容, 所以, 每次执行前都应该重新命名结果文件(可以在输入框中直接输入新的文件名, 或者找到存储目录下, 备份结果文件后, 把结果文件删了), 防止每次测试的数据都写入到一个文件里, 叠加统计了. 这点针对其它插件也是如此
3)每次打开保存的结果数据文件之前, 要点击工具栏的 清除, 清除全部按钮, 清除展示的数据, 否则展示的数据会在上次的基础上叠加显示. 这点针对其它插件也是如此
e) Jmeter java.NET.SocketTimeoutException: connect timed out,Read timed out 分析
先交代下测试计划的设置:
JMeter 测试计划线程组设置: Ramp-UP Period 为 5 秒. 勾选[delay thread creation until needed ] 允许需要时创建线程. 循环次数设为 10.
线程组包含两个请求, 分别是1上传数据,2下载数据. 设置两个请求之间 sleep 3000ms. 其他为缺省设置.
每个请求 connect time out:3000ms
每个请求 response time out:3000ms
分别以递增线程数执行测试, 由两个 agent 分别执行. 在线程数为 500 时, 产生错误:
错误 1:Response message: Non HTTP response message: connect timed out
错误分析: 通过 Load time 值看, 由于该线程耗费时间 (3002) 大于设置的 connect time out(3000ms), 因此抛出该异常. 问题可能是由于服务端有较多请求正在处理(且处理时间较长), 导致 JMeter 不能连接上服务器而产生的.
JMeter 原始错误信息:
概要:
Thread Name: 线程组 1-367
- Sample Start: 2013-07-05 11:04:17 CST
- Load time: 3002
- Latency: 0
- Size in bytes: 1677
- Headers size in bytes: 0
- Body size in bytes: 1677
- Sample Count: 1
- Error Count: 1
- Response code: Non HTTP response code: java.NET.SocketTimeoutException
- Response message: Non HTTP response message: connect timed out
详细信息:
- java.NET.SocketTimeoutException: connect timed out
- at java.NET.PlainSocketImpl.socketConnect(Native Method)
- at java.NET.PlainSocketImpl.doConnect(PlainSocketImpl.java:351)
- at java.NET.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:213)
- at java.NET.PlainSocketImpl.connect(PlainSocketImpl.java:200)
- at java.NET.SocksSocketImpl.connect(SocksSocketImpl.java:366)
- at java.NET.Socket.connect(Socket.java:529)
- at sun.NET.NetworkClient.doConnect(NetworkClient.java:158)
- at sun.NET.www.http.HttpClient.openServer(HttpClient.java:395)
- at sun.NET.www.http.HttpClient.openServer(HttpClient.java:530)
- at sun.NET.www.http.HttpClient.<init>(HttpClient.java:234)
- at sun.NET.www.http.HttpClient.New(HttpClient.java:307)
- at sun.NET.www.http.HttpClient.New(HttpClient.java:324)
- at sun.NET.www.protocol.http.HttpURLConnection.getNewHttpClient(HttpURLConnection.java:970)
- at sun.NET.www.protocol.http.HttpURLConnection.plainConnect(HttpURLConnection.java:911)
- at sun.NET.www.protocol.http.HttpURLConnection.connect(HttpURLConnection.java:836)
- at org.apache.jmeter.protocol.http.sampler.HTTPJavaImpl.sample(HTTPJavaImpl.java:487)
- at org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy.sample(HTTPSamplerProxy.java:62)
- at org.apache.jmeter.protocol.http.sampler.HTTPSamplerBase.sample(HTTPSamplerBase.java:1088)
- at org.apache.jmeter.protocol.http.sampler.HTTPSamplerBase.sample(HTTPSamplerBase.java:1077)
- at org.apache.jmeter.threads.JMeterThread.process_sampler(JMeterThread.java:428)
- at org.apache.jmeter.threads.JMeterThread.run(JMeterThread.java:256)
- at java.lang.Thread.run(Thread.java:662)
错误 2:Response message: Non HTTP response message: Read timed out
错误分析: 通过返回错误信息看, 发生该错误时, JMeter 已经连接上服务器, 但是产生 read time out. 从 load time(2998)看, 所用时间并没有超过设定超时时间(3000), 因此错误不大可能是 JMeter 本身产生的. 一种可能是, 服务器那边未处理该线程的请求, 或者为保证服务能力, 断掉了连接.
JMeter 原始错误信息:
概要:
Thread Name: 线程组 1-10
- Sample Start: 2013-07-05 11:12:45 CST
- Load time: 2988
- Latency: 0
- Size in bytes: 2431
- Headers size in bytes: 0
- Body size in bytes: 2431
- Sample Count: 1
- Error Count: 1
- Response code: Non HTTP response code: java.NET.SocketTimeoutException
- Response message: Non HTTP response message: Read timed out
详细信息:
- at java.NET.SocketInputStream.socketRead0(Native Method)
- at java.NET.SocketInputStream.read(SocketInputStream.java:129)
- at java.io.BufferedInputStream.fill(BufferedInputStream.java:218)
- at java.io.BufferedInputStream.read1(BufferedInputStream.java:258)
- at java.io.BufferedInputStream.read(BufferedInputStream.java:317)
- at sun.NET.www.http.HttpClient.parseHTTPHeader(HttpClient.java:697)
- at sun.NET.www.http.HttpClient.parseHTTP(HttpClient.java:640)
- at sun.NET.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1195)
- at sun.NET.www.protocol.http.HttpURLConnection.getHeaderField(HttpURLConnection.java:2300)
- at java.NET.URLConnection.getHeaderFieldInt(URLConnection.java:579)
- at java.NET.URLConnection.getContentLength(URLConnection.java:474)
- at org.apache.jmeter.protocol.http.sampler.HTTPJavaImpl.readResponse(HTTPJavaImpl.java:230)
来源: http://www.bubuko.com/infodetail-3350701.html