You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Gatling压测时如何设置所有虚拟用户共用的可动态更新全局变量

问题根因

你之前的方案不生效是因为Gatling DSL属于构建期逻辑:所有在请求定义里直接传入的固定参数,都会在Simulation初始化阶段就被解析固化,不会在每次请求运行时重新读取。你代码里.header("LIMIT", GLOBAL_LIMIT)在压测启动时就把当时的"49"存成了请求头的固定值,后续修改GLOBAL_LIMIT变量自然不会对已经构建完成的请求逻辑生效。

实现方案

需要同时满足两个要求:

  • 全局共享变量要保证多线程可见性,避免并发读写的一致性问题
  • 请求头的取值改为动态表达式,每次请求发送前实时读取最新的全局值

单节点压测可以直接用JDK自带的原子类实现,修改后的代码如下:

import java.util.concurrent.atomic.AtomicReference
import io.gatling.core.Predef._
import io.gatling.http.Predef._
import scala.concurrent.duration._

class MySimulation extends Simulation {
  // 用原子引用存储全局共享值,保证多线程可见性
  private val GLOBAL_LIMIT = new AtomicReference[String]("49")

  def myRequest: HttpRequestBuilder =
    http("My request")
      .get("/")
      // 传入动态表达式,每次请求运行时实时读取当前最新值
      .header("LIMIT", _ => GLOBAL_LIMIT.get())
      .check(status.is(200))

  def myScenario: ScenarioBuilder =
    scenario("Poll")
      .forever(
        pace(1.second)
          .exec(myRequest)
      )

  def changeLimit(limit: String): ScenarioBuilder =
    scenario("Change limit")
      .exec(session => {
        GLOBAL_LIMIT.set(limit)
        session
      })

  setUp(
    myScenario.inject(
      constantUsersPerSec(1) during 30.seconds
    ),
    changeLimit("59").inject(
      nothingFor(10.seconds),
      atOnceUsers(1)
    )
  ).protocols(http.baseUrl("http://localhost:8081"))
}
注意事项

如果是使用Gatling Enterprise的分布式集群压测,上述基于JVM内原子类的方案只能在单节点生效,多节点同步全局值需要额外引入分布式缓存组件来实现,单节点压测无需额外调整。

内容的提问来源于stack exchange,提问作者Lukasz Wyporek

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.09 12:06:01