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

为何Gatling在单个场景结束后终止模拟而非等待全部完成?

嘿,这个问题我之前帮人排查过好几次,核心是Gatling里throttle和forever()的配合逻辑容易踩坑,我给你拆解清楚:

为什么模拟会在10秒后提前停止?

问题出在throttle的作用逻辑上:它不只是控制请求速率,还会直接定义场景的生命周期时长。

你给scn1配置了holdFor(10 seconds),这意味着Gatling会严格执行这个流量控制阶段10秒——哪怕你在场景里写了forever()循环,一旦10秒的hold阶段结束,Gatling就会认为这个场景的“流量计划”完成了,直接终止scn1的那个用户。

而Gatling的默认行为是:当所有被注入的用户都完成了他们的场景任务后,整个模拟就会终止。虽然scn2的用户还在运行,但scn1的用户提前终止后,会触发整个模拟的提前结束。

怎么解决才能让模拟运行20秒直到所有场景完成?

给你三个实用的解决方案,按需选择:

方案1:给整个模拟设置全局最大时长

最简单的方式是在setUp末尾添加maxDuration(20 seconds),强制让模拟运行满20秒再终止,不管单个场景是否提前结束:

setUp(
  scn("scn1").inject(atOnceUsers(1))
    .throttle(
      jumpToRps(1), holdFor(10 seconds)
    ),
  scn("scn2").inject(atOnceUsers(1))
    .throttle(jumpToRps(1), holdFor(20 seconds))
).protocols(http.baseURLs(url))
.maxDuration(20 seconds) // 这行是关键

方案2:让所有场景的throttle时长对齐最长场景

如果你希望scn1在10秒后停止发请求,但模拟继续等待scn2完成,可以调整scn1的throttle配置,让它的总时长和scn2一致:

scn("scn1").inject(atOnceUsers(1))
  .throttle(
    jumpToRps(1), holdFor(10 seconds), // 前10秒按1RPS发请求
    jumpToRps(0), holdFor(10 seconds)  // 后10秒停止请求,保持场景存活
  )

这样scn1的用户会在20秒后才正式完成,整个模拟就会和scn2一起结束。

方案3:用during()替代forever()+throttle的组合

如果你的需求本来就是让场景在指定时长内循环发请求,其实可以直接用during()来实现,逻辑更清晰,也不会踩throttle的坑:

// 重构场景定义,直接传入运行时长
val scn = (name: String, duration: FiniteDuration) => scenario(name)
  .during(duration) {
    exec(request)
  }

setUp(
  scn("scn1", 10 seconds).inject(atOnceUsers(1))
    .throttle(jumpToRps(1)),
  scn("scn2", 20 seconds).inject(atOnceUsers(1))
    .throttle(jumpToRps(1))
).protocols(http.baseURLs(url))

这种方式下,每个场景会严格在指定时长内循环执行请求,时间到了自动结束,整个模拟会等待所有场景的用户都完成后才终止。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 12:24:11