JMeter技术实现:从数据库加载百万电话号码后多线程调用REST接口
JMeter实现单次加载数据库手机号并多线程复用请求REST接口
步骤1:创建前置线程组加载数据库数据
- 添加Setup Thread Group(该线程组会在所有测试线程启动前仅执行一次,完美匹配"仅加载一次数据"的需求),设置线程数为1,循环次数为1。
- 在Setup Thread Group内添加JDBC Connection Configuration,配置数据库连接信息:
- 填入对应数据库的URL、驱动类、用户名、密码(比如MySQL用
com.mysql.cj.jdbc.Driver,Oracle用oracle.jdbc.OracleDriver)。
- 填入对应数据库的URL、驱动类、用户名、密码(比如MySQL用
- 添加JDBC Request,配置SQL查询:
- 输入SQL语句:
SELECT phone_number FROM your_phone_table(替换为你的表名和手机号字段名) - 在"Variable Names"栏填写
phone_num,查询结果会自动存入一个ArrayList变量中。
- 输入SQL语句:
- 添加JSR223 PostProcessor,将手机号列表存入JMeter全局属性,供其他线程组调用:
// 从JDBC请求结果中获取手机号列表 def phoneList = vars.getObject("phone_num") // 存入全局属性,其他线程组可直接访问 props.put("GLOBAL_PHONE_LIST", phoneList)
步骤2:创建并发线程组复用数据
- 添加普通Thread Group,设置你需要的并发线程数(比如50/100,根据接口承载能力调整),循环次数设为"永远"(后续通过代码控制停止时机)。
- 在该Thread Group内添加JSR223 PreProcessor,实现线程安全的手机号分配:
import java.util.concurrent.atomic.AtomicInteger // 从全局属性获取手机号列表 def phoneList = props.get("GLOBAL_PHONE_LIST") // 初始化全局索引计数器(仅第一次执行时创建) if (!props.containsKey("PHONE_INDEX")) { props.put("PHONE_INDEX", new AtomicInteger(0)) } AtomicInteger currentIndex = props.get("PHONE_INDEX") // 原子性获取下一个索引,避免线程冲突 int index = currentIndex.getAndIncrement() if (index < phoneList.size()) { // 将当前手机号存入线程变量,供HTTP请求使用 vars.put("current_phone", phoneList.get(index)) } else { // 所有手机号已用完,停止当前线程组 log.info("所有手机号已分配完毕,终止测试线程") ctx.getThreadGroup().stop() }
步骤3:添加REST接口请求
- 在并发Thread Group内添加HTTP Request,配置REST接口的URL、请求方法(如POST/GET):
- 如果接口需要在参数或请求体中传入手机号,直接引用变量
${current_phone}即可。
- 如果接口需要在参数或请求体中传入手机号,直接引用变量
- 按需添加View Results Tree、Summary Report等监听器,查看请求结果和性能数据。
注意事项
- 调整JMeter内存:100万数据量较大,需修改
jmeter.bat(Windows)或jmeter.sh(Linux)中的HEAP参数,比如设置HEAP="-Xms4g -Xmx8g",避免内存溢出。 - 调试时先小批量测试:在JDBC Request的SQL中添加
LIMIT 100,验证流程正确后再加载全量数据。 - 数据库连接池配置:在JDBC Connection Configuration中适当增大"Max Connections",避免加载数据时出现连接不足的问题。
内容的提问来源于stack exchange,提问作者R.Srivastava
相关产品推荐
相关产品推荐

