JMeter多用户场景下如何将一个API生成的参数传递给另一个API
JMeter多线程场景下跨API参数传递解决方案
核心问题说明
你当前的方案在多用户场景下失效,主要是因为多线程并发读写CSV会出现时序错乱、参数错位问题,且未做变量隔离的情况下不同线程的参数会出现串用。
方案1:线程绑定参数传递(单线程生成的参数仅当前线程使用,最常用)
该方案适用于每个线程先执行参数生成API,再执行参数消费API的一对一调用场景:
- 将两个API放在同一个线程组内,调整执行顺序保证参数生成API始终在参数消费API之前执行
- 在参数生成API后添加JSON提取器/Path Extractor插件,配置提取规则:
- 分别设置两个提取项,引用名称填写
filename、id - 匹配数字填
1(单响应只返回一对参数的场景),如果需要取随机匹配项填0
- 分别设置两个提取项,引用名称填写
- 直接在第二个API的请求参数/请求路径/请求头中,通过
${filename}、${id}引用提取到的变量即可
该方案利用JMeter默认变量线程隔离的特性,每个线程存储的
filename、id不会被其他线程读取或篡改,完全不需要中间存储到CSV,避免并发读写冲突。
方案2:全局参数池共享(所有生成的参数可被任意线程的消费API调用)
该方案适用于所有生成的参数需要统一存入公共池,后续消费API可随机/按顺序取用的场景:
- 先添加
setUp线程组,添加JSR223采样器,初始化线程安全的全局参数队列:
props.put("filenamePool", new java.util.concurrent.CopyOnWriteArrayList()); props.put("idPool", new java.util.concurrent.CopyOnWriteArrayList());
- 在参数生成API后添加JSR223后置处理器,把提取到的参数写入全局队列:
// 读取当前线程提取到的参数,写入全局池 String currentFilename = vars.get("filename"); String currentId = vars.get("id"); props.get("filenamePool").add(currentFilename); props.get("idPool").add(currentId);
- 在参数消费API前添加JSR223前置处理器,从全局池获取参数存入当前线程变量:
// 可根据需求选择随机取或者按顺序取 int randomIndex = org.apache.commons.lang3.RandomUtils.nextInt(0, props.get("filenamePool").size()); String useFilename = props.get("filenamePool").get(randomIndex); String useId = props.get("idPool").get(randomIndex); // 如果参数消费后不可重复使用,可删除对应条目 // props.get("filenamePool").remove(randomIndex); // props.get("idPool").remove(randomIndex); // 存入当前线程变量供请求调用 vars.put("use_filename", useFilename); vars.put("use_id", useId);
- 在第二个API中通过
${use_filename}、${use_id}引用参数即可
注意事项
- 如果两个API分属不同线程组,不能使用默认线程变量传递参数,必须通过全局属性(props)传递
- 不推荐用CSV作为中间存储介质,多线程并发写CSV容易出现半行、乱序问题,读取时也会出现多线程重复读取同一条数据的情况
内容的提问来源于stack exchange,提问作者James P.
相关产品推荐
相关产品推荐

