如何在Gatling负载测试中基于帕累托原则配置CSV输入数据源?
嗨,这个需求太贴合真实业务场景了!Gatling自带的Queue/Random/Shuffle/Circular这四种Feeder模式确实没法直接实现帕累托分布(20%数据占80%请求)的效果,但咱们可以通过自定义逻辑来搞定,给你分享两种实用的实现方式:
方法一:拆分CSV文件+加权场景组合
这是最直观的方式——先把你的猫名CSV拆成两个文件:
popular_cats.csv:包含20%的热门猫名rare_cats.csv:包含剩下80%的冷门猫名
然后在Gatling场景里给这两组请求设置权重,让热门组贡献80%的请求量,冷门组贡献20%。代码示例如下:
import io.gatling.core.Predef._ import io.gatling.http.Predef._ import scala.concurrent.duration._ class CatByNameLoadTest extends Simulation { // 加载热门/冷门猫名CSV,用Random模式保证同组内随机选取 val popularCatsFeeder = csv("popular_cats.csv").random val rareCatsFeeder = csv("rare_cats.csv").random // 定义HTTP协议 val httpProtocol = http .baseUrl("你的接口基础URL") .acceptHeader("application/json") // 热门请求场景 val popularScenario = scenario("Popular Cat Query") .feed(popularCatsFeeder) .exec(http("Get Popular Cat") .get("/catByName?name=${name}")) // 冷门请求场景 val rareScenario = scenario("Rare Cat Query") .feed(rareCatsFeeder) .exec(http("Get Rare Cat") .get("/catByName?name=${name}")) // 设置场景权重:热门占80%,冷门占20%(这里用并发数比例来控制) setUp( popularScenario.inject(constantUsersPerSec(80) during (5 minutes)), rareScenario.inject(constantUsersPerSec(20) during (5 minutes)) ).protocols(httpProtocol) }
优缺点
- ✅ 优点:逻辑简单,容易理解和维护,适合猫名列表相对固定的场景
- ❌ 缺点:需要提前手动拆分CSV,要是猫名经常更新的话会有点繁琐
方法二:自定义帕累托Feeder
如果不想拆分CSV,咱们可以直接基于原始文件写一个自定义Feeder,通过概率控制实现帕累托分布。核心思路是:加载所有猫名后,把前20%标记为热门,然后每次取数据时,用80%的概率选热门猫,20%的概率选冷门猫。
代码示例:
import io.gatling.core.Predef._ import io.gatling.http.Predef._ import scala.util.Random import scala.concurrent.duration._ class CatByNameLoadTest extends Simulation { // 加载所有猫名CSV并转为数组 val allCatRecords = csv("all_cats.csv").records.toArray // 计算热门猫的数量(总数量的20%) val popularCatCount = (allCatRecords.length * 0.2).toInt // 拆分热门/冷门猫名数组 val popularCats = allCatRecords.take(popularCatCount) val rareCats = allCatRecords.drop(popularCatCount) // 自定义帕累托Feeder:80%概率返回热门猫,20%返回冷门猫 val paretoCatFeeder = Iterator.continually { if (Random.nextDouble() < 0.8) { // 从热门数组随机选一个 Map("name" -> popularCats(Random.nextInt(popularCats.length))("name")) } else { // 从冷门数组随机选一个 Map("name" -> rareCats(Random.nextInt(rareCats.length))("name")) } } val httpProtocol = http .baseUrl("你的接口基础URL") .acceptHeader("application/json") val testScenario = scenario("Pareto Cat Query") .feed(paretoCatFeeder) .exec(http("Get Cat By Name") .get("/catByName?name=${name}")) setUp( testScenario.inject(constantUsersPerSec(100) during (5 minutes)) ).protocols(httpProtocol) }
优缺点
- ✅ 优点:无需拆分CSV,直接用原始文件,适合猫名列表动态变化的场景;比例调整灵活,改个数字就能切换帕累托比例(比如10%占90%)
- ❌ 缺点:需要写一点自定义逻辑,对Scala语法有一点点要求
额外注意事项
- 概率精准度:如果需要更精准的加权(比如某些热门猫的请求占比更高),可以给每个猫名设置权重值,然后用加权随机算法选取,而不是简单的80/20拆分
- 数据验证:测试前可以加个打印逻辑,输出Feeder返回的猫名,确认热门/冷门的比例是否符合预期
- 重复数据处理:如果CSV里有重复的猫名,建议先去重,或者调整热门猫的选择逻辑,避免重复的热门猫占比过高
内容的提问来源于stack exchange,提问作者riorio
相关产品推荐
相关产品推荐

