HelloWorld Gatling 测试教程

Gatling 是一款基于 Scala 的高性能开源压测工具。HelloWorld 教程涵盖:安装 JDK、搭建项目、编写 Simulation、执行压测、生成 HTML 报表与解读。本文提供完整命令、示例代码与调优建议,帮助你迅速上手并分析关键指标。同时覆盖常见错误处理和扩展方案。可复用示例。

HelloWorld Gatling 测试教程

先说结论(想法导向)

想快速验证一个接口能不能顶住并发,最简单的流程就是:准备环境 → 写一个最小的 Simulation → 运行并观察 HTML 报表 → 根据响应时间与错误率调整脚本或后端。下面我会一步一步把每个环节拆开,解释为什么这么做,并给出可直接复制运行的示例代码。

准备工作:环境与方式选择

运行 Gatling 有几种常见方式,按难度和场景分:

  • Standalone Bundle(最简单,适合本地快速试验)
  • sbt / Maven 项目(适合集成到 CI、源码管理)
  • Docker 容器(便于在云端或容器化环境运行)

必备软硬件

  • JDK 11+(Gatling 通常需要 Java)
  • 适量内存(本地小规模测试 2GB 起步;并发增大时需要更高)
  • 网络可达被测目标

推荐:先用 Standalone Bundle 快速跑一个 HelloWorld

优点是零依赖配置:下载解压,放入示例 Simulation 文件夹,直接运行。缺点是对自动化和代码管理不如 sbt/maven 灵活。

项目结构与最小 HelloWorld Simulation(Scala)

Gatling 的核心是 Simulation(Scala 类)。一个最小示例会定义协议、场景(scenario)、以及注入(injection)配置。下面是可以直接运行的最简代码。

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

class HelloWorldSimulation extends Simulation {

  val httpProtocol = http
    .baseUrl("https://httpbin.org") // 被测目标
    .acceptHeader("application/json")

  val scn = scenario("HelloWorld") // 场景名
    .exec(
      http("get-root")
        .get("/get")
        .check(status.is(200))
    )

  setUp(
    scn.inject(
      atOnceUsers(10) // 立刻注入 10 个并发用户
    ).protocols(httpProtocol)
  )
}

把上面文件放到 Standalone 的 user-files/simulations 下(文件名 HelloWorldSimulation.scala),然后运行 bin/gatling.sh(或 Windows 下的 gatling.bat)。

关键点解释(费曼式拆解)

  • httpProtocol:定义目标主机与默认头部,方便复用。
  • scenario:一系列用户行为的编排,类似“脚本”。
  • exec(http(…)):发送 HTTP 请求并可带断言(checks)。
  • inject:注入模型决定负载是瞬间并发、匀速还是渐增。

常用 injection 模式(理解负载形态)

  • atOnceUsers(n):瞬时注入 n 个用户,用于突发流量。
  • rampUsers(n) during(duration):在一段时间内线性增加用户。
  • constantUsersPerSec(rate) during(duration):保持固定到达率(open model)。
  • splitUsers(total) into(atOnceUsers(…)):分批注入,便于模拟批量波峰。

运行方式小结

  • Standalone:bin/gatling.sh → 交互选择 Simulation → 生成 report 到 results/ 下
  • sbt:在项目中使用 Gatling 插件后,通过 sbt gatling:test 或 sbt “gatling:testOnly computerdatabase.HelloWorldSimulation”
  • Maven:使用 gatling-maven-plugin,通过 mvn gatling:test -Dgatling.simulationClass=…

示例:使用 sbt 的最小 build.sbt(可选)

name := "gatling-hello"

version := "0.1"

scalaVersion := "2.13.12"

libraryDependencies ++= Seq(
  "io.gatling" % "gatling-core" % "3.9.5" % Test,
  "io.gatling" % "gatling-http" % "3.9.5" % Test
)

enablePlugins(GatlingPlugin)

(这里演示思路,版本号请以官方仓库为准。)

报告的关键指标与如何读报表

Gatling 生成的 HTML 报表包含丰富的图表与表格,下面列出最常参考的指标:

  • Requests/sec(吞吐量):每秒完成请求数量,衡量系统吞吐能力。
  • Response time percentiles(如 p50/p95/p99):表示大多数请求的延迟分布。
  • Errors / Failure count:失败请求的类型与比例,优先级最高。
  • Active Users:并发用户数随时间波动图。

举一个表格示例帮助理解(示例数字,非真实结果):

指标 意义
总请求数 1000 整个测试期间发送的请求数量
成功率 99.2% 成功响应占比,低于 99% 需要关注
平均响应 230 ms 平均延迟,受极端值影响
p95 480 ms 95% 请求在此延迟以内
吞吐量 80 req/s 系统在该负载下稳定输出的请求率

常见断言与 Checks(保证测试可信)

在脚本中添加断言可以自动判断测试是否通过,例如:

.check(status.is(200))
.assertions(
  global.successfulRequests.percent.gt(99),
  global.responseTime.mean.lt(500)
)

断言的好处是 CI 自动化:当断言失败时,流水线可以自动报错并拦截不合格版本。

进阶技巧:参数化、Feeder 与 Session

  • Feeder(数据驱动):通过 CSV、JSON 或内存数组为不同用户提供不同输入。
  • Session:模拟用户状态(如登录后的 token),使用 saveAs / session 操作共享数据。
  • Checks 和 saveAs:提取响应字段并用于后续请求,例如提取 auth token。
val feeder = csv("users.csv").circular

val scn = scenario("WithFeeder")
  .feed(feeder)
  .exec(
    http("login")
      .post("/login")
      .formParam("user", "${username}")
      .check(jsonPath("$.token").saveAs("token"))
  )
  .exec(
    http("getProfile")
      .get("/profile")
      .header("Authorization", "Bearer ${token}")
  )

调优建议(从发包端和服务端两方面思考)

  • 避免在压测机上做繁重的计算或 GUI 操作,压测机应该专注于发送请求;
  • 逐步放大负载:先 small → medium → large,观察拐点(资源饱和);
  • 使用断言和统计来判定“系统是否承受住”,不要只看单个指标;
  • 如果出现高错误率,先检查网络和 DNS,再看后端日志;
  • 适当加入 thinkTime(pause)来模拟真实用户行为,避免所有用户同步请求造成非真实峰值;

常见问题与排查(边想边写的提醒)

  • “找不到 Simulation”:确认包名与类路径、文件放置目录是否正确(Standalone 要放 user-files/simulations)。
  • “内存溢出”:增加 JVM 堆内存,或减少本机并发用户数,使用多台压测机分担。
  • “吞吐量低于预期”:检查目标是否限流、DNS 延迟、压测机网络带宽。
  • “报告没有生成”:检查运行日志,看是否有编译错误或测试过程中抛出了异常。

在 CI 中集成的建议

把 Gatling 放到 CI 流程有两个常见目标:回归性能检查和发布前的冒烟压测。实践中我通常会把它做成一个单独的管道步骤,设置合理的断言和资源隔离。

  • 使用容器或专用压测节点,避免 CI 共享节点干扰;
  • 将结果以 artefact 形式保存(HTML 报表或 JSON 结果),便于后续分析;
  • 对关键路径做轻量级测试(短跑),对阶段性发布做更深入的压力测试(长跑)。

一些实际小贴士(来自实战,可能会派上用场)

  • http.headhttp.get 的请求名(request name)来区分关键事务,方便在报表中过滤;
  • 把断言放在关键场景而非每个请求,以免测试因微小波动全部失败;
  • 用 csv feeder 的循环策略(circular、random)模拟不同用户行为;
  • 当需要模拟高并发时,优先考虑扩展压测机数量而不是单台机器的并发数。

示例故障排查记录(实操笔记)

有一次我在本地跑 1000 并发失败,报错大部分为连接超时。排查顺序是:

  • 检查本机端口限制(ulimit、ephemeral port 用尽)
  • 把并发分成几台机器跑,确认是不是单机瓶颈
  • 在低并发下复现超时,查看目标服务日志发现后端线程池耗尽,进一步优化后端

这个过程说明:性能问题通常是多环节叠加,需要分层排查。

参考资料(便于深挖)

  • Gatling 官方文档(Gatling Documentation)
  • 《Performance Testing with Gatling》系列教程
  • 常见工具:httpbin.org(用于测试 HTTP 请求)

收尾(不用太正式)

如果你现在只想验证某个接口能不能承受并发,直接用 Standalone Bundle 把上面的 HelloWorldSimulation 放进去跑一遍,观察 p95 和错误率;如果要把测试放到 CI,就按项目需要选 sbt/maven 或 Docker 化。跑的时候我常常一边看报告一边想“嗯,好像这里的 p95 偏高,是不是因为连接池?”然后就去看后端日志——这类来回其实挺正常。希望这些步骤和示例代码能帮你快速上手,后面你会慢慢形成自己的一套测试小流程。