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

Gatling场景中如何并行发起HTTP请求?

Gatling 并行请求接口的解决方案

问题描述

我在Gatling中构建了如下场景:先通过feeder生成参数,再构造动态请求数组,之后调用两个接口。当前代码中endpoint1执行完成后才会触发endpoint2,我需要让这两个接口并行请求。尝试使用.resources方法但未生效,请问还有其他可行方案吗?

初始串行执行代码

val scenario9 = scenario("All end points")
  .feed(feeder)
  .exec(session => {
    val uniqueId = session("uniqueId").as[Int]

    val startIdx = Math.min(30 * (uniqueId - 1) + 0, 49951)
    val endIdx = Math.min(startIdx + 30 + 0, 49951)

    val dynamicArray = fullarray.slice(startIdx, endIdx)
                                .map(elm => s"""\"$elm\"""")
                                .mkString("[", ",", "]")

    session.set("requestArray", dynamicArray)
  })
  .exec(http("test1" )
    .post("/endpoint1")
    .body(ElFileBody("./performance/resources/Req1.json")).asJson
    .check(status.in(200))
  )
  .exec(http("test2" )
    .post("/endpoint2")
    .body(ElFileBody("./performance/resources/Req1.json")).asJson
    .check(status.in(200))
  })

使用.resources的尝试代码(未生效)

val scenario9 = scenario("All end points")
  .feed(feeder)
  .exec(session => {
    val uniqueId = session("uniqueId").as[Int]

    val startIdx = Math.min(30 * (uniqueId - 1) + 0, 49951)
    val endIdx = Math.min(startIdx + 30 + 0, 49951)

    val dynamicArray = fullarray.slice(startIdx, endIdx)
                                .map(elm => s"""\"$elm\"""")
                                .mkString("[", ",", "]")

    session.set("requestArray", dynamicArray)
  })
  .resources(
      http("test1" )
          .post("/endpoint1")
          .body(ElFileBody("./performance/resources/Req1.json")).asJson
          .check(status.in(200)),    
      http("test2" )
          .post("/endpoint2")
          .body(ElFileBody("./performance/resources/Req1.json")).asJson
          .check(status.in(200))
  })

可行解决方案

方案1:使用.parallel块(Gatling 3.7+ 支持)

Gatling 3.7及以上版本引入了parallel块,可直接包裹需要并行执行的请求,是最直观的并行实现方式:

val scenario9 = scenario("All end points")
  .feed(feeder)
  .exec(session => {
    val uniqueId = session("uniqueId").as[Int]

    val startIdx = Math.min(30 * (uniqueId - 1) + 0, 49951)
    val endIdx = Math.min(startIdx + 30 + 0, 49951)

    val dynamicArray = fullarray.slice(startIdx, endIdx)
                                .map(elm => s"""\"$elm\"""")
                                .mkString("[", ",", "]")

    session.set("requestArray", dynamicArray)
  })
  .parallel(
    exec(http("test1")
      .post("/endpoint1")
      .body(ElFileBody("./performance/resources/Req1.json")).asJson
      .check(status.in(200))
    ),
    exec(http("test2")
      .post("/endpoint2")
      .body(ElFileBody("./performance/resources/Req1.json")).asJson
      .check(status.in(200))
    )
  )

方案2:使用.forkJoin(兼容旧版本Gatling)

如果你的Gatling版本低于3.7,可使用forkJoin实现并行逻辑:

val scenario9 = scenario("All end points")
  .feed(feeder)
  .exec(session => {
    val uniqueId = session("uniqueId").as[Int]

    val startIdx = Math.min(30 * (uniqueId - 1) + 0, 49951)
    val endIdx = Math.min(startIdx + 30 + 0, 49951)

    val dynamicArray = fullarray.slice(startIdx, endIdx)
                                .map(elm => s"""\"$elm\"""")
                                .mkString("[", ",", "]")

    session.set("requestArray", dynamicArray)
  })
  .forkJoin(
    exec(http("test1")
      .post("/endpoint1")
      .body(ElFileBody("./performance/resources/Req1.json")).asJson
      .check(status.in(200))
    ),
    exec(http("test2")
      .post("/endpoint2")
      .body(ElFileBody("./performance/resources/Req1.json")).asJson
      .check(status.in(200))
    )
  )

为什么.resources没生效?

.resources方法的设计初衷是处理主请求的附属资源(比如页面加载时的静态资源:CSS、JS、图片等),它会在主请求完成后并行加载这些资源,但不能用来让两个独立的业务接口并行执行,因此你的场景下该方法不适用。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 16:43:19