Gatling中如何为JSON内同名变量传入不同随机数生成唯一客户编号
问题场景
构造包含customers数组的JSON请求体时,要求数组内每个客户条目的customerNo(客户编号)全局唯一,需实现为该字段传入不重复随机数的效果。
初始示例JSON结构如下:
{ "customers": [ { "customerNo": "123", "Name": "Joe" }, { "customerNo": "456", "Name": "Jane" } ] }
初始实现与问题
初始实现步骤如下:
- 在JSON模板中为两个
customerNo字段配置相同占位符${customerNo}:
{ "customers": [ { "customerNo": "${customerNo}", "Name": "Joe" }, { "customerNo": "${customerNo}", "Name": "Jane" } ] }
- 编写Scala代码构造随机数数据源:
val customerNumber = Iterator.continually( Map("customerNumber" -> Random.nextInt(Integer.MAX_VALUE)) )
- 通过
feed(customerNumber)注入数据源,执行后发现两个customerNo字段被赋值为同一个生成的随机数,无法满足唯一值要求。
根因分析
feed机制是按单次请求/单个虚拟用户维度拉取一次数据源数据,同一次请求内引用相同占位符时,会直接复用已经存入会话上下文的变量值,不会重复从Iterator迭代器中拉取新值,因此数组内复用同一占位符的字段会拿到相同的随机数。
可行解决方案
方案1:构造数组级数据源(适配动态数组长度场景)
放弃单值注入逻辑,直接在feed层构造完整的customers数组数据,每个客户条目的customerNo在构造列表时独立生成,从数据源层面保证值唯一:
import scala.util.Random import io.gatling.core.Predef._ // 每次迭代生成包含唯一customerNo的完整客户列表,可根据需求动态调整数组长度 val customerFeed = Iterator.continually( Map( "customerList" -> List( Map("customerNo" -> Random.nextInt(Integer.MAX_VALUE).toString, "Name" -> "Joe"), Map("customerNo" -> Random.nextInt(Integer.MAX_VALUE).toString, "Name" -> "Jane") ) ) ) // 对应JSON模板调整为,直接用json化的列表替换整个数组节点 // { // "customers": ${customerList.jsonStringify()} // } // 注入方式不变:feed(customerFeed)
方案2:使用实时解析的随机函数(适配固定长度数组场景)
无需调整feed逻辑,替换占位符为每次解析时实时生成值的内置函数,避免复用会话缓存值:
{ "customers": [ { "customerNo": "${randomInt(2147483647)}", "Name": "Joe" }, { "customerNo": "${randomInt(2147483647)}", "Name": "Jane" } ] }
说明:
randomInt为常用压测框架(如Gatling)内置的EL函数,每次匹配到占位符时都会独立触发随机数计算,不会复用之前的生成结果,可保证同请求内多个字段值不重复。如果是自定义模板引擎,可参考该逻辑:将占位符对应的值设置为每次调用都生成新值的函数,而非固定静态值。
内容的提问来源于stack exchange,提问作者Stacky
相关产品推荐
相关产品推荐

