性能测试相关分享
程序员文章站
2024-03-23 22:02:10
...
性能测试相关
1.为什么要做性能测试
.基于网络的分布式应用
.用户数量增加-系统负载
.能够承受的并发用户数量
.带宽-CPU-内存的占用
.硬盘速度是否跟得上
.系统稳定性-响应时间
2.性能测试概念
-负载测试:Load Testing 用户数量性能
-压力测试:Stress Testing 高压力:系统奔溃,卡死
-容量测试:Volumn Testing 最大支撑数量,响应时间
-吞吐量/吞吐率: IO 对应:
3.性能测试关注点
4 性能测试原理
示例:
Jmeter性能测试
Jmeter性能测试
一 Jmeter简单使用
1、创建一个线程组
添加之后如下所示:
参数解释:
Number of Threads (users):虚拟用户数,一个虚拟用户占用一个进程或线程,设置多少虚拟用户数在这里也就是设置多少个线程数。
Ramp-Up Period (in seconds):准备时长,设置的虚拟用户数需要多长时间全部启动。如果线程数为10,准备时长为2,那么需要2秒钟启动10个线程,也就是每秒钟启动5个线程。
Loop Count:循环次数,如果勾选Forever,那么所有线程会一直发送请求,一到选择停止运行脚本。
Delay Thread creation until needed:直到需要时延迟线程的创建。
Scheduler:调度器(配置调度器时,需要勾选循环次数为永远)
Duration (seconds):持续时间
Startup delay:启动延迟时间
2、创建一个HTTP请求
添加之后如下:
这里我们用百度做测试,用GET请求去请求百度搜索"testSomething"关键字(params需要点击add添加,关键字需要点击URL Encode)
3、添加察看结果树
4、点击运行查看结果
这里我们可以看到请求是200成功
二 Jmeter性能测试
1、Java脚本代码编写
1、从Jmeter的安装目录lib/ext中拷贝两个文件ApacheJMeter_core.jar和ApacheJMeter_java.jar到项目中,然后引入这两个JAR包。
或者在maven项目的pom.xml文件中添加:
<dependencies>
<!--jmeter-->
<dependency>
<groupId>org.apache.jmeter</groupId>
<artifactId>ApacheJMeter_core</artifactId>
<version>5.0</version>
</dependency>
<dependency>
<groupId>org.apache.jmeter</groupId>
<artifactId>ApacheJMeter_java</artifactId>
<version>5.0</version>
</dependency>
<!--jmeter-->
...
</dependencies>
然后用maven install,会自动下载插件
2、创建一个类TestSomething,需要继承于AbstractJavaSamplerClient,同时需要重写几个方法:
package com.fshows.test.performance;
import com.alibaba.fastjson.JSONObject;
import okhttp3.*;
import org.apache.jmeter.config.Arguments;
import org.apache.jmeter.protocol.java.sampler.AbstractJavaSamplerClient;
import org.apache.jmeter.protocol.java.sampler.JavaSamplerContext;
import org.apache.jmeter.samplers.SampleResult;
import java.io.IOException;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
public class TestSomething extends AbstractJavaSamplerClient {
private String encoding = "utf-8";
private String url = "https://www.baidu.com/";
/*
* 初始化方法,初始化性能测试时的每个线程
* 实际运行时仅执行一次,在测试方法运行前执行,类似于init方法
*/
@Override
public void setupTest(JavaSamplerContext context) {
super.setupTest(context);
// 这里做测试前提条件的准备
}
/*
* 性能测试时的线程运行体
* 测试执行的循环体,根据线程数和循环次数的不同可执行多次
*/
@Override
public SampleResult runTest(JavaSamplerContext javaSamplerContext) {
SampleResult result = new SampleResult();
result.setDataType(SampleResult.TEXT);
// 根据被测接口创建请求,组装参数
// 放置请求参数requestDate,可以在Jmeter结果树的request看到
result.setSamplerData(requestDate.toString());
// 定义一个事务,表示这是事务的起始点
result.sampleStart();
// 请求接口,拿到返回值response
//定义一个事务,表示这是事务的结束点
results.sampleEnd();
// 解析response
String responseBody = Objects.requireNonNull(response.body()).string();
JSONObject jsonObject = JSONObject.parseObject(responseBody);
if (jsonObject.getBoolean("success")) {
result.setSuccessful(true);
result.setResponseMessage(responseBody);
result.setResponseData(responseBody, encoding);
} else {
result.setSuccessful(false);
result.setResponseData("response content error:" + responseBody, encoding);
}
// 某些post请求传递json数据的实现,这里我们用OkHttpClient去发送请求
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.connectTimeout(10, TimeUnit.SECONDS)//设置连接超时时间
.readTimeout(20, TimeUnit.SECONDS)//设置读取超时时间
.build();
// 拼接json参数
JSONObject jsonObj = new JSONObject();
jsonObj.put("jsonKey", "jsonValue");
MediaType JSON = MediaType.parse("application/json; charset=utf-8");
RequestBody requestJsonBody = RequestBody.create(JSON, jsonObj.toString());
Request request = new Request.Builder()
.url(url) // 目标url
.post(requestJsonBody) // json数据
.addHeader("headersKey", "headersValue") // 某些请求头传递的数据
.addHeader("content-type", "application/json")
.build();
Call call = okHttpClient.newCall(request);
result.setSamplerData(request.toString());
try {
// 请求获取response
Response response = call.execute();
// 解析response
} catch (IOException e) {
result.setResponseData("request to server error:" + e, encoding);
result.setSuccessful(false);
return result;
} catch (Exception e) {
result.setResponseData("other error:" + e, encoding);
result.setSuccessful(false);
return result;
}
// 最后需return result
return result;
}
// 入口函数
public static void main(String[] args) {
JavaSamplerContext arg0 = new JavaSamplerContext(new Arguments());
TestSomething test = new TestSomething();
test.setupTest(arg0);
test.runTest(arg0);
}
}
2、Jmeter运行
1、首先需要将代码打包,将得到的jar包放在apache-jmeter-5.0\lib\ext目录下,然后重启Jmeter
启动如果出现内存溢出的异常 java.lang.OutOfMemoryError: Java heap space
在apache-jmeter-5.0\bin目录下根据系统找到对应的启动项进行修改
if not defined HEAP (
rem See the unix startup file for the rationale of the following parameters,
rem including some tuning recommendations
set HEAP=-Xms1g -Xmx8g -XX:MaxMetaspaceSize=512m
)
2、这次添加完线程组之后需要添加一个 Java Request
添加之后就可以看到打的jar包内写的代码用例
3、对Java Request添加查看响应结果
View Results Tree : 结果树查看
Aggregate Report:聚合报告
我们在线程组里模拟100个users - Number of Threads (users),然后运行一个Java Request,查看聚合报告
参数解释:
Label:每个JMeter的element(例如 Java Request)都有一个Name属性,这里显示的就是Name属性的值
#Samples:请求数,表示这次测试中一共发出了多少个请求
Average:平均响应时间,默认情况下是单个Request的平均响应时间
Median:中位数,也就是 50% 用户的响应时间
90% Line:90% 用户的响应时间
Min:最小响应时间
Max:最大响应时间
Error%:错误率,错误请求数/请求总数
Throughput:吞吐量,默认情况下表示每秒完成的请求数(Request per Second)
KB/Sec:每秒从服务器端接收到的数据量
3、Jmeter并发
1、Jmeter启动了之后线程就会直接发送测试请求,但是如果要模拟在一瞬间高并发量测试的时候,需要调高线程数量,这很耗测试机器的性能,往往无法支持较大的并发数,无法控制每次测试的瞬间并发量,这时候需要使用synchronized timer阻塞线程,直到指定的线程数量到达后,再一起释放,可以瞬间产生很大的压力
添加synchronized timer
参数解释:
Number of Simulated Users to Group by:每集合够多少个模拟用户(线程)后发送一次测试请求;如果设置为0,等同于设置为线程租中的线程数;确保设置的值不大于它所在线程组包含的用户数(线程数),否则会一直集结线程而不发出测试请求,直到超时(如果设置了的话)
Example:Number of Simulated Users to Group by: 100 表示并发量是100,也就是说,Jmeter会等到100个线程都运行到此处时,这100个线程才开始执行后面的操作,先到达的线程将会在此等候
Timeout in milliseconds:超时时间,即多少毫秒后同时释放已集结的的线程,发送测试请求;如果设置为0,Timer将等待线程数达到了"Number of Simultaneous Users to Group"中设置的值才释放
Example:Timeout in milliseconds: 100 表示超时时间为100ms,当100ms后还没达到"Number of Simultaneous Users to Group"中设置的值,Timer将不再等待,直接释放已到达的线程
当我们要进行并发测试时,比如要进行500的并发量测试,需要进行的设置如下:
这样Jmeter就会集结500个线程(users),集结完成后会在0s内发送完请求,达到并发效果
2、synchronized timer放置位置说明
如果希望定时器仅应用于其中一个sampler,则把该定时器作为子节点加入,如下图
如果希望synchronizing timer应用于多个sampler,如下图,当执行一个sampler之前时,和sampler处于相同作用域的定时器都会被执行
注意:
在Jmeter中,timer是在sampler之前执行的。不管这个定时器的位置放在sampler之后,还是之前。当然,如果有多个timer的时候,在相同作用域下,会按上下顺序执行timer,这个就需要慎重放置timer的顺序;不过,为了更好的可读性,还是建议将timer放在对应的sampler前面或子节点中
4、Jmeter分布式
待补充
三 相关下载
1、Jmeter
Jmeter下载:http://jmeter.apache.org/download_jmeter.cgi
apache-jmeter-5.0.zip(54.3 MB)
2、插件
此外,Jmeter还提供了插件来满足不同情况下的需求
插件下载:https://jmeter-plugins.org/install/Install/
如果不想看,可阔以,把下面这个东东放到lib/ext目录,然后重启JMeter,在options下选择自己需要的安装
https://jmeter-plugins.org/get/ < 就这个
可能,大概,也许会用到的插件:
aaa@qq.com - Active Threads Over Time -- 活跃线程数量随时间的推移变化
aaa@qq.com Transaction per Second -- 每秒事务处理量
aaa@qq.com Response Times Over Time -- 响应时间随着时间的推移变化