gatling 记录

195 阅读4分钟

1、 Gatling Maven Plugin

//该命令用于开发人员或测试人员查看 Gatling Maven 插件中与执行模拟测试相关的配置选项、参数和详细描述
mvn gatling:help -Ddetail=true -Dgoal=test 

1.1 使用maven运行gatling

mvn gatling:test
使用 mvn gatling:test 会进入交互模式
//1、如果src/test/java 只有一个模拟类,会直接启动gatling脚本
//2、如果src/test/java 有多个模拟类,在执行mvn gatling:test 之后让执行自己选择要执行的具体场景

mvn gatling:test -Dgatling.simulationClass=computerdatabase.ComputerDatabaseSimulation

指定具体模拟类启动脚本computerdatabase包下ComputerDatabaseSimulation类

2、Simulation类

2.1 注意事项

  • 在gatling中,推荐模拟类的类名不要用Test开头,推荐并非强制,因为maven可能会尝试启动一些以Test开头的类
  • Simulation为父类,必须要继承此类

2.2 Simulation类的构成

  1. 在脚本的开头,通常会有一系列的导入语句,用于引入Gatling提供的各种功能和DSL(领域特定语言)元素
  2. HTTP协议配置 (HttpProtocolhttp):这部分定义了所有HTTP请求将遵循的基本设置,例如基础URL、连接超时、代理设置、SSL配置等。
  3. 断言和检查 用于验证响应内容是否符合预期,比如状态码、响应时间、返回内容中的特定值等。
  4. 数据供给器 (feed): 数据供给器用于为场景提供动态数据,比如从文件、数据库或编程生成的数据。
  5. 场景定义 (scenario): 场景定义了单个用户的行为模式,包括执行的请求序列、思考时间、循环、条件分支等。它是基于之前定义的请求构建块和数据供给器构建的。
  6. 全局设置 (可选): 可能还会包括一些全局的配置,比如报告的格式、日志级别等。
  7. 辅助函数和变量定义 (可选): 自定义函数或变量,用于复用代码片段或管理复杂逻辑。
  8. 请求构建块 (exec): 这些是构建请求的基本单元,可以串联起来形成更复杂的用户行为序列。
  9. 钩子函数(Hooks)

3、 HTTP Protocol

3.1、启动开销

NIO引擎在初始化时,由于需要加载资源、建立必要的内部结构等,可能导致处理第一个请求时的性能不如之后的请求,这是因为启动过程产生了额外的时间和资源消耗。为了抵消这种影响,Gatling会自动向[gatling.io发送一个请求],让引擎完成预热

3.2、用法

package computerdatabase;

import io.gatling.http.response.Response;
import io.gatling.http.response.ResponseBody;
import io.gatling.http.response.StringResponseBody;
import io.gatling.javaapi.core.ChainBuilder;
import io.gatling.javaapi.core.FeederBuilder;
import io.gatling.javaapi.core.ScenarioBuilder;
import io.gatling.javaapi.core.Simulation;
import io.gatling.javaapi.http.HttpProtocolBuilder;
import io.gatling.recorder.model.HttpResponse;

import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.Scanner;
import java.util.concurrent.ThreadLocalRandom;
import java.util.zip.GZIPInputStream;

import static io.gatling.javaapi.core.CoreDsl.*;
import static io.gatling.javaapi.http.HttpDsl.*;
import static java.awt.SystemColor.text;
import java.io.ByteArrayInputStream;
import java.io.IOException;

public class EngineDatabaseSimulation extends Simulation {


    HttpProtocolBuilder httpProtocol =
        http.baseUrl("https://computer-database.gatling.io")
                //首次启动预热,默认开启,默认请求地址为https://gatling.io,可修改
                .warmUp("https://cn.bing.com/")
//                默认上限 = 6
//    maxConnectionsPerHost = 6 相比于 maxConnectionsPerHost = 1
//    能够提供更高的并发度,使得测试更能反映出系统在实际高并发访问情况下的表现,包括响应时间、吞吐量以及可能的资源瓶颈。
//    当设置为6时,每个虚拟用户可以同时对每个远程主机保持最多6个活跃的连接。在这种情况下,你的100个用户理论上可以同时向同一个主机发起最多600个并发请求
                .maxConnectionsPerHost(6)
                //每个虚拟用户都配备了自己的连接池及独立的SSL上下文。这种设置适用于当你意图模拟互联网流量场景,
                // 其中每个虚拟用户扮演一个网络浏览器的角色。这意味着每个“用户”独立管理网络连接和安全信息,
                // 类似于真实世界中不同用户通过各自的浏览器访问网站,每浏览器维护自己的连接状态和安全会话。
                // 默认就是开启的
                .shareConnections()
                //不开启Referer
                .disableAutoReferer()
                //禁用缓存,如果需要对response进行断言,不能禁用缓存
                .disableCaching()
                //跟随重定向最大次数
                .maxRedirects(20)
                //禁止跟随重定向
//                .disableFollowRedirect()
                .userAgentHeader("value")
                .header("foo", "bar")
                .headers(Map.of("foo", "bar"))
//                禁止对url进行编码
                .disableUrlEncoding()
                .transformResponse((response, session) -> {
                    if (response.headers().get("Content-Encoding").contains("gzip")) {
                        try (InputStream gzipInputStream = new GZIPInputStream(response.body().byteStream());
                             Scanner scanner = new Scanner(gzipInputStream, StandardCharsets.UTF_8.name())) {

                            String decompressedText = scanner.useDelimiter("\A").next();
                            session.set("decompressedBody", decompressedText);
                            return response; // 返回原始的响应,但数据已保存在会话中
                        } catch (Exception e) {
                            throw new RuntimeException("Failed to decompress GZIP response", e);
                        }
                    } else {
                        return response;
                    }
                }).
                check(
                        status().is(200),
                        currentLocation().saveAs("url"),
                        currentLocationRegex(""https://(.*)/.*"").saveAs("url1"),
                        header("Content-Type").saveAs("contentType"),
                        header("Content-Encoding").saveAs("contentEncoding"),
                        headerRegex("Content-Type", ".*json.*")


                )
                .disableFollowRedirect()
                //默认同步开启
                //Gatling测试配置中使用 http.asyncNameResolution(),可以确保域名解析操作不会成为性能测试的瓶颈,使得测试结果更能准确反映被测系统的实际处理能力,尤其是在处理高并发请求时
                .asyncNameResolution();
        //    http.disableWarmUp(); 关闭
    ScenarioBuilder scn = scenario("Scenario");
    {
        setUp(
                scn.injectOpen(atOnceUsers(2))
        ).protocols(httpProtocol);
    }

}