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
相关产品推荐
相关产品推荐

