2

我正在尝试测试一个在内部根据输入执行不同操作的 API:

  • 国家
  • 顾客
  • 物品数量

以下模拟是我想出的:

val countries = List("US", "CAN")
val customerTypes = List("TYPE1", "TYPE2")
val basketSizes = List(1, 10, 50)

val scenarioGenerator: Seq[(String, String, Int)] = for {
  country <- countries
  customerType <- customerTypes
  basketSize <- basketSizes
} yield (country, customerType, basketSize)

def scenarios(): Seq[PopulationBuilder] = {
  var scenarioList = new ArraySeq[PopulationBuilder](countries.size * customerTypes.size * basketSizes.size)
  var i = 0;
  for ((country: String, customerType: String, basketSize: Int) <- scenarioGenerator) {
    // fetch customer data for scenario
    val customers = DataFetcher.customerRequest(country, customerType)
    // fetch product data for scenario
    val products = DataFetcher.productRequest(country)

    // generate a scenario with given data and parameters
    val scen = scenario(s"Pricing-(${country},${customerType},${basketSize})")
      // feeder that creates the request object for the gatling user
      .feed(new PricingFeeder(country, customers, products, basketSize))
      .repeat(10) {
        exec(Pricing.price)
          .pause(500 milliseconds)
      }
      .inject(
        rampUsers(10) over (10 seconds)
      )
    scenarioList(i) = scen

    i = i + 1
  }

  scenarioList
}

setUp(scenarios: _*).protocols(httpProto)

这是使用 maven 插件运行的(并使用 gatling 插件在 jenkins 中进行跟踪),但这会导致单个跟踪案例:Pricing. 这是没有用的,因为即使项目数量也将接近响应时间的线性增加。

具有每种场景类型的simulation.log数据,但开箱即用的报告将其作为单一类型的查询处理,并将所有结果合并到一个图表中,这意味着无法查看某个组合是否会导致峰值计算或数据错误。

我想为每个组合获取单独的指标,因此很容易看到例如 API 中的代码或数据更改导致Pricing-(US,TYPE1,50)场景中的延迟峰值。

用加特林实现这一目标的惯用方式是什么?我不想为每种情况创建模拟,因为这将是管理的一场噩梦(我们正在努力实现使用 jmeter 摆脱手动管理的数据和詹金斯作业)。

4

1 回答 1

2

第一件事 - 在一个模拟中运行这么多场景不是一个好习惯,因为它并行运行它们而不是按顺序运行,所以你应该确保它是你想要的。

如果是这样,您可以使用加特林报告允许显示每组图表的事实。因此,您可以将所有请求包装在基于参数命名的组中,这样在报告的详细视图中,您将能够选择要显示的组,例如:

 val singleScenario = scenario(s"Pricing-(${country},${customerType},${basketSize})")
   .group(s"Pricing-(${country},${customerType},${basketSize})"){
      .feed(new PricingFeeder(country, customers, products, basketSize))
        .repeat(10) {
          exec(Pricing.price)
            .pause(500 milliseconds)
        }
    }

如果您不需要所有场景并行运行,并且想要为单独的场景提供单独的报告,最好的方法是将模拟类实现为参数化抽象类并为每个参数集添加单独的类,如在 Gatling 中,一个模拟等于报告,fe。 :

package com.performance.project.simulations

import io.gatling.core.Predef.Simulation
import scala.concurrent.duration._

class UsType1Simulation1 extends ParametrizedSimulation("US", "TYPE1", 1)
class UsType1Simulation10 extends ParametrizedSimulation("US", "TYPE1", 10)
class UsType1Simulation50 extends ParametrizedSimulation("US", "TYPE1", 50)

class UsType2Simulation1 extends ParametrizedSimulation("US", "TYPE2", 1)
class UsType2Simulation10 extends ParametrizedSimulation("US", "TYPE2", 10)
class UsType2Simulation50 extends ParametrizedSimulation("US", "TYPE2", 50)

class CanType1Simulation1 extends ParametrizedSimulation("CAN", "TYPE1", 1)
class CanType1Simulation10 extends ParametrizedSimulation("CAN", "TYPE1", 10)
class CanType1Simulation50 extends ParametrizedSimulation("CAN", "TYPE1", 50)

class CanType2Simulation1 extends ParametrizedSimulation("CAN", "TYPE2", 1)
class CanType2Simulation10 extends ParametrizedSimulation("CAN", "TYPE2", 10)
class CanType2Simulation50 extends ParametrizedSimulation("CAN", "TYPE2", 50)

sealed abstract class ParametrizedSimulation(country: String, customerType: String, basketSize: Int) extends Simulation{

  val customers = DataFetcher.customerRequest(country, customerType)
  val products = DataFetcher.productRequest(country)

  val singleScenario = scenario(s"Pricing-(${country},${customerType},${basketSize})")
    .feed(new PricingFeeder(country, customers, products, basketSize))
    .repeat(10) {
      exec(Pricing.price)
      .pause(500 milliseconds)
    }
    .inject(
      rampUsers(10) over (10 seconds)
    )

  setUp(singleScenario).protocols(httpProto)
}

当然,只有当有少量组合时才有意义,如果有数百个组合,它就会变得混乱。

于 2018-06-20T13:35:54.210 回答