性能测试相关分享

性能测试相关
1.为什么要做性能测试
.基于网络的分布式应用
.用户数量增加-系统负载
.能够承受的并发用户数量
.带宽-CPU-内存的占用
.硬盘速度是否跟得上
.系统稳定性-响应时间
2.性能测试概念
-负载测试:Load Testing 用户数量性能
-压力测试:Stress Testing 高压力:系统奔溃,卡死
-容量测试:Volumn Testing 最大支撑数量,响应时间
-吞吐量/吞吐率: IO 对应: -吞吐量/吞吐率: 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/  < 就这个


可能,大概,也许会用到的插件:
 jp@gc - Active Threads Over Time -- 活跃线程数量随时间的推移变化
 jp@gc Transaction per Second -- 每秒事务处理量
 jp@gc Response Times Over Time -- 响应时间随着时间的推移变化
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章