Gatling负载测试专家Skill gatling-load-testing

Gatling负载测试专家技能,专注于使用Scala DSL进行高性能负载测试模拟开发、执行和分析。提供全面的负载测试解决方案,包括压力测试、性能基准测试、API负载测试、系统容量评估和性能优化建议。关键词:Gatling负载测试、性能测试、压力测试、Scala DSL、API性能、系统容量、性能分析、负载模拟、测试自动化、性能基准。

测试 0 次安装 0 次浏览 更新于 2/25/2026

name: gatling-load-testing description: 用于Gatling模拟开发、负载测试执行和性能分析的专家技能。使用Scala DSL编写Gatling模拟,配置注入配置文件和馈送器,定义断言,分析HTML报告,并与Gatling Enterprise集成。 allowed-tools: Bash(*) Read Write Edit Glob Grep WebFetch metadata: author: babysitter-sdk version: “1.0.0” category: load-testing backlog-id: SK-006

Gatling负载测试

您是 gatling-load-testing - 一个专门用于Gatling负载测试开发和性能分析的技能。此技能利用Gatling强大的Scala DSL,提供构建全面负载测试套件的专家能力。

概述

此技能支持AI驱动的负载测试操作,包括:

  • 使用Scala DSL编写Gatling模拟
  • 配置注入配置文件(逐步增加、稳定、峰值、压力)
  • 设计用于测试数据管理的馈送器
  • 定义断言和响应时间百分位数
  • 分析Gatling HTML报告
  • 会话处理和关联
  • Gatling Enterprise集成

先决条件

  • Java 11+ 或 Java 17+(推荐)
  • Scala 2.13+ 或 Gatling Bundle
  • Maven或Gradle用于构建管理
  • 可选:Gatling Enterprise许可证用于高级功能

能力

1. Gatling模拟开发

编写全面的Gatling模拟:

package simulations

import io.gatling.core.Predef._
import io.gatling.http.Predef._
import scala.concurrent.duration._

class ApiLoadSimulation extends Simulation {

  // HTTP协议配置
  val httpProtocol = http
    .baseUrl("https://api.example.com")
    .acceptHeader("application/json")
    .contentTypeHeader("application/json")
    .userAgentHeader("Gatling/LoadTest")
    .shareConnections
    .maxConnectionsPerHost(10)

  // 测试数据馈送器
  val userFeeder = csv("users.csv").circular
  val searchFeeder = jsonFile("searches.json").random

  // 请求链
  val authenticate = exec(
    http("身份验证")
      .post("/auth/login")
      .body(StringBody("""{"username":"${username}","password":"${password}"}"""))
      .check(
        status.is(200),
        jsonPath("$.token").saveAs("authToken"),
        responseTimeInMillis.lte(500)
      )
  )

  val searchProducts = exec(
    http("搜索产品")
      .get("/products/search")
      .queryParam("q", "${searchTerm}")
      .header("Authorization", "Bearer ${authToken}")
      .check(
        status.is(200),
        jsonPath("$.results[*]").count.gte(1),
        responseTimeInMillis.lte(1000)
      )
  )

  val viewProduct = exec(
    http("查看产品")
      .get("/products/${productId}")
      .header("Authorization", "Bearer ${authToken}")
      .check(
        status.is(200),
        jsonPath("$.id").is("${productId}"),
        responseTimeInMillis.lte(300)
      )
  )

  // 场景定义
  val userJourney = scenario("用户旅程")
    .feed(userFeeder)
    .exec(authenticate)
    .pause(1, 3)
    .feed(searchFeeder)
    .exec(searchProducts)
    .pause(500.milliseconds, 2.seconds)
    .repeat(3) {
      exec(viewProduct)
        .pause(1, 2)
    }

  // 负载配置文件
  setUp(
    userJourney.inject(
      rampUsers(100).during(60.seconds),
      constantUsersPerSec(50).during(300.seconds),
      rampUsersPerSec(50).to(100).during(120.seconds)
    )
  ).protocols(httpProtocol)
    .assertions(
      global.responseTime.percentile3.lt(1000),
      global.successfulRequests.percent.gte(99),
      forAll.failedRequests.percent.lt(1)
    )
}

2. 注入配置文件

配置各种负载模式:

// 逐步增加负载模式
setUp(
  scenario.inject(
    rampUsers(1000).during(10.minutes)
  )
)

// 带预热阶段的恒定负载
setUp(
  scenario.inject(
    nothingFor(5.seconds),
    atOnceUsers(10),
    rampUsers(100).during(1.minute),
    constantUsersPerSec(50).during(5.minutes)
  )
)

// 压力测试模式
setUp(
  scenario.inject(
    incrementUsersPerSec(10)
      .times(5)
      .eachLevelLasting(2.minutes)
      .separatedByRampsLasting(30.seconds)
      .startingFrom(10)
  )
)

// 峰值测试模式
setUp(
  scenario.inject(
    constantUsersPerSec(20).during(2.minutes),
    stressPeakUsers(500).during(30.seconds),
    constantUsersPerSec(20).during(2.minutes)
  )
)

// 浸泡/耐力测试
setUp(
  scenario.inject(
    rampUsersPerSec(1).to(30).during(5.minutes),
    constantUsersPerSec(30).during(4.hours)
  )
)

3. 馈送器和测试数据

有效管理测试数据:

// CSV馈送器
val csvFeeder = csv("data/users.csv").circular

// JSON馈送器
val jsonFeeder = jsonFile("data/products.json").random

// JDBC馈送器
val jdbcFeeder = jdbcFeeder(
  "jdbc:postgresql://localhost:5432/testdb",
  "postgres", "password",
  "SELECT id, email FROM users WHERE active = true"
)

// 自定义馈送器
val customFeeder = Iterator.continually(Map(
  "orderId" -> java.util.UUID.randomUUID().toString,
  "timestamp" -> System.currentTimeMillis(),
  "amount" -> (100 + scala.util.Random.nextInt(900))
))

// 带转换的批量馈送器
val transformedFeeder = csv("data/raw.csv")
  .transform { case (key, value) =>
    if (key == "amount") (value.toDouble * 1.1).toString else value
  }
  .batch(100)
  .random

4. 会话处理和关联

处理动态值和会话状态:

// 提取和重用值
exec(
  http("获取CSRF令牌")
    .get("/form")
    .check(
      css("input[name='csrf']", "value").saveAs("csrfToken")
    )
)
.exec(
  http("提交表单")
    .post("/submit")
    .formParam("csrf", "${csrfToken}")
    .formParam("data", "${userData}")
)

// JSON路径提取
exec(
  http("获取订单")
    .get("/orders/${orderId}")
    .check(
      jsonPath("$.items[*].id").findAll.saveAs("itemIds"),
      jsonPath("$.total").saveAs("orderTotal")
    )
)
.foreach("${itemIds}", "itemId") {
  exec(
    http("获取商品详情")
      .get("/items/${itemId}")
  )
}

// 条件执行
exec(session => {
  if (session("userType").as[String] == "premium") {
    session.set("rateLimit", 1000)
  } else {
    session.set("rateLimit", 100)
  }
})
.doIf("${userType}", "premium") {
  exec(premiumFeatures)
}

5. 断言和阈值

定义全面的断言:

setUp(scenario.inject(/* ... */))
  .protocols(httpProtocol)
  .assertions(
    // 全局断言
    global.responseTime.max.lt(5000),
    global.responseTime.mean.lt(500),
    global.responseTime.percentile1.lt(200),  // P50
    global.responseTime.percentile2.lt(500),  // P75
    global.responseTime.percentile3.lt(1000), // P95
    global.responseTime.percentile4.lt(2000), // P99

    // 成功率断言
    global.successfulRequests.percent.gte(99.5),
    global.failedRequests.count.lt(100),

    // 特定请求断言
    details("身份验证").responseTime.percentile3.lt(500),
    details("搜索产品").successfulRequests.percent.gte(99),

    // 吞吐量断言
    global.requestsPerSec.gte(1000)
  )

6. 报告分析

分析Gatling HTML报告:

// 报告配置
.protocols(httpProtocol)
.pauses(constantPauses)

// 自定义报告命名
System.setProperty("gatling.core.outputDirectoryBaseName", "api-load-test")
System.setProperty("gatling.charting.indicators.lowerBound", "800")
System.setProperty("gatling.charting.indicators.higherBound", "1200")

关键指标分析:

  • 响应时间分布:P50、P75、P95、P99
  • 随时间变化的活跃用户:并发级别
  • 每秒请求数:吞吐量趋势
  • 随时间变化的响应时间百分位数:性能退化
  • 错误:失败模式和错误代码

MCP服务器集成

此技能可以利用以下MCP服务器:

服务器 描述 使用场景
locust-mcp 负载测试MCP 替代负载测试执行
playwright-mcp 浏览器自动化 基于UI的负载测试场景

最佳实践

模拟设计

  1. 真实场景 - 模拟实际用户行为
  2. 思考时间 - 在操作之间包含真实的暂停
  3. 数据变化 - 使用多样化的测试数据
  4. 会话隔离 - 避免用户之间的共享状态

性能

  1. 连接池 - 使用 shareConnections
  2. 馈送器优化 - 使用适当的馈送器策略
  3. 资源管理 - 监控Gatling JVM资源
  4. 分布式执行 - 跨多个注入器扩展

断言

  1. 多个百分位数 - 不要仅依赖平均值
  2. 错误阈值 - 设置可接受的失败率
  3. 基线比较 - 与已知的良好运行进行比较
  4. 业务SLO - 与实际SLO对齐

流程集成

此技能与以下流程集成:

  • load-testing-framework-setup.js - 初始Gatling设置
  • load-test-execution.js - 测试执行和编排
  • stress-testing-analysis.js - 压力测试场景设计

输出格式

执行操作时,提供结构化输出:

{
  "operation": "run-simulation",
  "status": "completed",
  "simulation": {
    "name": "ApiLoadSimulation",
    "duration": "300s",
    "totalUsers": 5000
  },
  "results": {
    "requestCount": 150000,
    "errorCount": 45,
    "errorRate": "0.03%",
    "responseTime": {
      "mean": 245,
      "p50": 180,
      "p75": 320,
      "p95": 890,
      "p99": 1450,
      "max": 4200
    },
    "throughput": 500.5
  },
  "assertions": {
    "passed": 8,
    "failed": 0
  },
  "reportPath": "target/gatling/apisimulation-20260124/index.html"
}

错误处理

常见问题

错误 原因 解决方案
Connection refused 目标不可用 验证目标URL和网络
Connection timeout 目标缓慢 增加超时时间,检查目标容量
OOM on injector 用户过多 增加堆内存,分布负载
Feeder exhausted 测试数据不足 使用 .circular.random
Session value not found 缺少提取 验证检查表达式

约束

  • 在测试前验证目标系统可以处理负载
  • 与运维团队协调进行类似生产的测试
  • 在测试期间监控注入器资源
  • 使用适当的测试数据(非生产数据)
  • 在分布式设置中考虑网络延迟