当前位置: 首页 > 测试知识 > 软件压力测试Gatling循环与条件逻辑控制:doIf、doWhile、repeat、foreach与随机化操作
软件压力测试Gatling循环与条件逻辑控制:doIf、doWhile、repeat、foreach与随机化操作
2025-11-24 作者cwb 浏览次数44

Gatling循环和条件逻辑控制:doIf、doWhile、repeat、foreach和随机化操作


1. Gatling控制流架构和执行模型

控制流执行引擎


Gatling的控制流机制建立在Akka Actor系统和状态机模型之上,通过会话转换器和流程控制器实现复杂的用户行为模拟。

Gatling控制流内部执行流程

Session → Condition Evaluation → Flow Controller → Action Execution → Session Update



会话状态管理和上下文


scala

class SessionStateManager {

  // 会话状态键定义

  object SessionKeys {

    val LOOP_COUNTER = "loopCounter"

    val CONDITION_FLAG = "conditionFlag" 

    val ITERATION_INDEX = "iterationIndex"

    val RANDOM_VALUE = "randomValue"

    val COLLECTION_ITEMS = "collectionItems"

  }

  

  // 会话上下文维护

  case class ExecutionContext(

    session: Session,

    conditionStack: List[Boolean],

    loopStack: List[Int],

    randomGenerator: Random

  )

}


2. 条件逻辑控制深度解析

doIf-条件分支执行


scala

class DoIfConditionSimulation extends Simulation {

  

  val httpProtocol = http.baseUrl("https://api.example.com")

  

  val complexConditionScenario = scenario("Advanced Conditional Logic")

    .exec(session => session

      .set("userType", "premium")

      .set("balance", 150.0)

      .set("isAuthenticated", true)

    )

    

    // 基础doIf条件判断

    .doIf(session => session("isAuthenticated").as[Boolean]) {

      exec(http("Authenticated Request")

        .get("/user/profile")

        .check(status.is(200))

        .check(jsonPath("$.premium").saveAs("isPremiumUser")))

    }

    

    // 多条件组合判断

    .doIf(session => {

      val isPremium = session("isPremiumUser").as[Boolean]

      val balance = session("balance").as[Double]

      isPremium && balance > 100.0

    }) {

      exec(http("Premium Feature Access")

        .get("/premium/features")

        .check(status.is(200)))

    }

    

    // 字符串条件判断

    .doIf(session => session("userType").as[String] == "premium") {

      exec(http("Premium Content")

        .get("/premium/content")

        .check(status.is(200)))

    }

    

    // 嵌套条件逻辑

    .doIf(session => session("userType").as[String] == "admin") {

      exec(http("Admin Panel")

        .get("/admin/dashboard")

        .check(status.is(200)))

        .doIf(session => session("balance").as[Double] > 500) {

          exec(http("Super Admin")

            .get("/admin/super")

            .check(status.is(200)))

        }

    }

    

    // doIfElse 条件分支

    .doIfOrElse(session => session("userType").as[String] == "premium") {

      exec(http("Premium Flow")

        .get("/premium/checkout")

        .check(status.is(200)))

    } {

      exec(http("Standard Flow")  

        .get("/standard/checkout")

        .check(status.is(200)))

    }

  

  // doIf的技术实现原理

  object DoIfImplementation {

    

    /**

     * doIf内部执行机制

     * 基于Session状态的条件评估和分支选择

     */

    class ConditionalExecutor(condition: Session => Boolean) {

      

      def evaluate(session: Session): Boolean = {

        try {

          condition(session)

        } catch {

          case e: Exception => 

            // 条件评估异常处理

            println(s"Condition evaluation failed: ${e.getMessage}")

            false

        }

      }

      

      def executeBranch(session: Session, branch: ChainBuilder): Session = {

        if (evaluate(session)) {

          // 执行条件分支

          branch.exec(session)

        } else {

          // 跳过分支,继续执行

          session

        }

      }

    }

  }

}


doIfEquals-特定值条件判断


scala

class DoIfEqualsSimulation extends Simulation {

  

  val specificConditionScenario = scenario("Specific Value Conditions")

    .exec(session => session

      .set("httpStatus", 200)

      .set("contentType", "application/json")

      .set("apiVersion", "v2")

    )

    

    // 数值相等判断

    .doIfEquals("${httpStatus}", 200) {

      exec(http("Success Handler")

        .get("/success")

        .check(status.is(200)))

    }

    

    // 字符串相等判断  

    .doIfEquals("${contentType}", "application/json") {

      exec(http("JSON Processor")

        .get("/json-data")

        .check(status.is(200)))

    }

    

    // 多值判断

    .doIfEquals("${apiVersion}", "v2") {

      exec(http("V2 API")

        .get("/v2/endpoint")

        .check(status.is(200)))

    }

    

    // 会话属性存在性判断

    .doIf(session => session.contains("specialFeature")) {

      exec(http("Special Feature")

        .get("/special")

        .check(status.is(200)))

    }

}

3. 循环控制结构专业实现

repeat-固定次数循环


scala

class RepeatLoopSimulation extends Simulation {

  

  val fixedLoopScenario = scenario("Fixed Iteration Loops")

    .exec(session => session.set("baseProductId", 1001))

    

    // 基础固定次数循环

    .repeat(5) { // 循环5次

      exec(http("Repeated API Call")

        .get("/product/${baseProductId}")

        .check(status.is(200)))

        .pause(1)

    }

    

    // 动态循环次数

    .repeat("${loopCount}") { // 从会话中获取循环次数

      exec(http("Dynamic Loop Request")

        .get("/items")

        .check(status.is(200)))

        .pause(500.milliseconds, 2.seconds)

    }

    

    // 循环计数器访问

    .repeat(10, "iterationIndex") { // 将循环索引保存到会话

      exec(session => {

        val index = session("iterationIndex").as[Int]

        val productId = 1000 + index

        session.set("currentProductId", productId)

      })

      .exec(http("Iterative Product Query")

        .get("/product/${currentProductId}")

        .check(status.is(200)))

    }

    

    // 嵌套循环结构

    .repeat(3, "outerLoop") { // 外层循环

      repeat(2, "innerLoop") { // 内层循环

        exec(session => {

          val outer = session("outerLoop").as[Int]

          val inner = session("innerLoop").as[Int]

          val compositeId = s"${outer}_${inner}"

          session.set("compositeId", compositeId)

        })

        .exec(http("Nested Loop Call")

          .get("/composite/${compositeId}")

          .check(status.is(200)))

      }

    }

  

  // repeat循环的数学建模

  object RepeatMathematics {

    

    /**

     * 循环执行时间预测模型

     */

    case class LoopTimingModel(

      iterations: Int,

      requestTime: FiniteDuration, 

      pauseTime: FiniteDuration

    ) {

      

      def totalExecutionTime: FiniteDuration = {

        val totalRequestTime = requestTime * iterations

        val totalPauseTime = pauseTime * (iterations-1)

        totalRequestTime + totalPauseTime

      }

      

      def estimatedCompletion(startTime: Long, currentIteration: Int): Long = {

        val elapsed = System.currentTimeMillis()-startTime

        val avgTimePerIteration = totalExecutionTime.toMillis / iterations

        startTime + (avgTimePerIteration * iterations)

      }

    }

    

    // 示例计算

    val model = LoopTimingModel(

      iterations = 10,

      requestTime = 2.seconds,

      pauseTime = 1.second

    )

    println(s"预计总执行时间: ${model.totalExecutionTime}") // 29秒

  }

}


doWhile-条件循环执行


scala

class DoWhileSimulation extends Simulation {

  

  val conditionalLoopScenario = scenario("Conditional While Loops")

    .exec(session => session

      .set("pageNumber", 1)

      .set("hasMorePages", true)

      .set("maxPages", 10)

    )

    

    // 基础doWhile循环

    .doWhile(session => session("hasMorePages").as[Boolean]) {

      exec(http("Paginated Request")

        .get("/items?page=${pageNumber}")

        .check(status.is(200))

        .check(jsonPath("$.hasMore").saveAs("hasMorePages")))

        .exec(session => {

          val currentPage = session("pageNumber").as[Int]

          session.set("pageNumber", currentPage + 1)

        })

        .pause(1)

    }

    

    // 带保护条件的doWhile

    .doWhile(session => {

      val hasMore = session("hasMorePages").as[Boolean]

      val currentPage = session("pageNumber").as[Int]

      val maxPages = session("maxPages").as[Int]

      hasMore && currentPage <= maxPages

    }, "paginationGuard") {

      exec(http("Protected Pagination")

        .get("/protected/items?page=${pageNumber}")

        .check(status.is(200))

        .check(jsonPath("$.hasMore").saveAs("hasMorePages")))

        .exec(session => {

          val currentPage = session("pageNumber").as[Int]

          session.set("pageNumber", currentPage + 1)

        })

    }

    

    // 复杂业务逻辑循环

    .doWhile(session => {

      val balance = session("accountBalance").as[Double]

      val minBalance = session("minRequiredBalance").as[Double]

      val transactionCount = session("transactionCount").as[Int]

      balance >= minBalance && transactionCount < 5

    }) {

      exec(http("Transaction Processing")

        .post("/transaction")

        .body(StringBody("""{"amount": 100}"""))

        .check(status.is(200))

        .check(jsonPath("$.newBalance").saveAs("accountBalance")))

        .exec(session => {

          val count = session("transactionCount").as[Int]

          session.set("transactionCount", count + 1)

        })

        .pause(2)

    }

  

  // doWhile循环的工程技术实现

  object DoWhileImplementation {

    

    /**

     * doWhile循环的状态机实现

     */

    class WhileLoopStateMachine(

      condition: Session => Boolean,

      counterName: String = "whileCounter"

    ) {

      

      private var iterationCount = 0

      private val maxIterations = 1000 // 防止无限循环

      

      def shouldContinue(session: Session): Boolean = {

        iterationCount += 1

        if (iterationCount > maxIterations) {

          println(s"警告: 循环超过最大迭代次数 $maxIterations")

          false

        } else {

          try {

            condition(session)

          } catch {

            case e: Exception =>

              println(s"循环条件评估失败: ${e.getMessage}")

              false

          }

        }

      }

      

      def updateSession(session: Session): Session = {

        session.set(counterName, iterationCount)

      }

    }

  }

}


foreach-集合遍历循环


scala

class ForeachSimulation extends Simulation {

  

  val collectionIterationScenario = scenario("Collection Iteration")

    .exec(session => {

      val productIds = Seq(1001, 1002, 1003, 1004, 1005)

      val userNames = Seq("alice", "bob", "charlie", "diana")

      session

        .set("productIds", productIds)

        .set("userNames", userNames)

        .set("searchTerms", List("laptop", "phone", "tablet", "watch"))

    })

    

    // 基础集合遍历

    .foreach("${productIds}", "currentProductId") {

      exec(http("Product Detail")

        .get("/product/${currentProductId}")

        .check(status.is(200)))

        .pause(1)

    }

    

    // 字符串集合遍历

    .foreach("${userNames}", "currentUser") {

      exec(http("User Profile")

        .get("/user/${currentUser}/profile")

        .check(status.is(200)))

        .pause(500.milliseconds)

    }

    

    // 复杂对象集合处理

    .exec(session => {

      val complexItems = Seq(

        Map("id" -> "A1", "type" -> "premium", "price" -> 99.99),

        Map("id" -> "A2", "type" -> "standard", "price" -> 49.99),

        Map("id" -> "A3", "type" -> "premium", "price" -> 149.99)

      )

      session.set("complexItems", complexItems)

    })

    .foreach("${complexItems}", "currentItem") {

      exec(session => {

        val item = session("currentItem").as[Map[String, Any]]

        session

          .set("itemId", item("id"))

          .set("itemType", item("type"))

          .set("itemPrice", item("price"))

      })

      .doIf(session => session("itemType").as[String] == "premium") {

        exec(http("Premium Item Processing")

          .post("/premium/items")

          .body(StringBody("""{"id":"${itemId}","price":${itemPrice}}"""))

          .check(status.is(200)))

      }

    }

    

    // 动态集合遍历

    .exec(http("Get Item List")

      .get("/items")

      .check(jsonPath("$[*].id").findAll.saveAs("dynamicItemIds")))

    .foreach("${dynamicItemIds}", "dynamicItemId") {

      exec(http("Process Dynamic Item")

        .get("/item/${dynamicItemId}/details")

        .check(status.is(200)))

    }

  

  // foreach性能优化策略

  object ForeachOptimization {

    

    /**

     * 大集合分批次处理策略

     */

    def processLargeCollection[T](

      collection: Seq[T],

      batchSize: Int,

      processor: T => ChainBuilder

    ): List[ChainBuilder] = {

      

      collection.grouped(batchSize).zipWithIndex.map { case (batch, batchIndex) =>

        foreach(batch, s"itemInBatch$batchIndex") { item =>

          processor(item)

        }

      }.toList

    }

    

    // 使用示例

    val largeProductList = (1 to 1000).map(i => s"product_$i")

    val batchProcessors = processLargeCollection(

      largeProductList, 

      50, 

      (productId: String) => {

        exec(http("Batch Product Request")

          .get(s"/product/$productId")

          .check(status.is(200)))

      }

    )

  }

}


4. 随机化操作高级实现

随机数生成和控制


scala

class RandomizationSimulation extends Simulation {

  

  val randomOperationsScenario = scenario("Advanced Random Operations")

    .exec(session => session

      .set("randomSeed", System.currentTimeMillis())

    )

    

    // 基础随机数生成

    .exec(session => {

      val random = new Random(session("randomSeed").as[Long])

      session

        .set("randomUserId", random.nextInt(10000))

        .set("randomAmount", random.nextDouble() * 1000)

        .set("randomChoice", random.nextBoolean())

    })

    

    // 范围内随机值

    .exec(session => {

      val random = new Random()

      session

        .set("pauseDuration", random.nextInt(5) + 1) // 1-5秒

        .set("productIndex", random.nextInt(100))

        .set("discountPercent", random.nextInt(50) + 10) // 10-59%

    })

    

    // 随机选择器

    .randomSwitch(

      60.0 -> exec(http("Common Path")  // 60%概率

        .get("/common/endpoint")

        .check(status.is(200))),

      

      25.0 -> exec(http("Alternative Path")  // 25%概率  

        .get("/alternative/endpoint")

        .check(status.is(200))),

      

      15.0 -> exec(http("Rare Path")  // 15%概率

        .get("/rare/endpoint")

        .check(status.is(200)))

    )

    

    // 均匀随机选择

    .uniformRandomSwitch(

      exec(http("Option A")

        .get("/option/a")

        .check(status.is(200))),

        

      exec(http("Option B")  

        .get("/option/b")

        .check(status.is(200))),

        

      exec(http("Option C")

        .get("/option/c")

        .check(status.is(200)))

    )

    

    // 圆形随机选择(概率和为100%)

    .roundRobinSwitch(

      exec(http("Server 1")  // 33.3%概率

        .get("/server1/api")),

        

      exec(http("Server 2")  // 33.3%概率

        .get("/server2/api")),

        

      exec(http("Server 3")  // 33.3%概率  

        .get("/server3/api"))

    )

  

  // 高级随机分布策略

  object AdvancedRandomDistributions {

    

    /**

     * 正态分布随机数生成

     */

    case class GaussianRandom(mean: Double, stdDev: Double, seed: Long = System.currentTimeMillis()) {

      private val random = new Random(seed)

      

      def nextValue(): Double = {

        mean + random.nextGaussian() * stdDev

      }

      

      def nextBoundedValue(min: Double, max: Double): Double = {

        val value = nextValue()

        Math.max(min, Math.min(max, value))

      }

    }

    

    /**

     * 指数分布随机数(用于模拟真实用户行为)

     */

    case class ExponentialRandom(mean: Double, seed: Long = System.currentTimeMillis()) {

      private val random = new Random(seed)

      

      def nextValue(): Double = {

        -mean * Math.log(1-random.nextDouble())

      }

    }

    

    // 使用高级分布

    val gaussian = GaussianRandom(5.0, 2.0) // 均值5,标准差2

    val exponential = ExponentialRandom(3.0) // 均值3的指数分布

    

    val advancedRandomScenario = scenario("Statistical Distributions")

      .exec(session => {

        val thinkTime = exponential.nextValue()

        val requestSize = gaussian.nextBoundedValue(1.0, 10.0)

        session

          .set("thinkTime", thinkTime)

          .set("requestSize", requestSize)

      })

      .pause("${thinkTime}")

      .exec(http("Sized Request")

        .get("/data?size=${requestSize}")

        .check(status.is(200)))

  }

}


随机循环和条件控制


scala

class RandomLoopControlSimulation extends Simulation {

  

  val randomControlScenario = scenario("Random Loop and Condition Control")

    .exec(session => {

      val random = new Random()

      session

        .set("randomLoopCount", random.nextInt(5) + 3) // 3-7次循环

        .set("randomCondition", random.nextDouble() > 0.3) // 70%为true

    })

    

    // 随机次数循环

    .repeat("${randomLoopCount}", "randomIteration") {

      exec(session => {

        val iteration = session("randomIteration").as[Int]

        val random = new Random()

        session.set("itemId", 1000 + iteration * random.nextInt(10))

      })

      .exec(http("Random Loop Request")

        .get("/item/${itemId}")

        .check(status.is(200)))

      .pause(500.milliseconds, 2.seconds)

    }

    

    // 随机条件执行

    .doIf(session => session("randomCondition").as[Boolean]) {

      exec(http("Conditional Random Request")

        .get("/conditional/feature")

        .check(status.is(200)))

    }

    

    // 动态概率条件

    .exec(session => {

      val random = new Random()

      val userTier = random.nextInt(3) match {

        case 0 => "basic"    // 33%概率

        case 1 => "premium"  // 33%概率  

        case 2 => "vip"      // 33%概率

      }

      session.set("userTier", userTier)

    })

    .doIf(session => session("userTier").as[String] != "basic") {

      exec(http("Premium Feature Access")

        .get("/premium/features")

        .check(status.is(200)))

    }

  

  // 蒙特卡洛随机模拟

  object MonteCarloSimulation {

    

    /**

     * 基于蒙特卡洛方法的随机决策

     */

    class MonteCarloDecision(probabilities: Map[String, Double]) {

      require(probabilities.values.sum == 1.0, "概率总和必须为1.0")

      

      private val sortedProbabilities = probabilities.toList.sortBy(-_._2)

      private val random = new Random()

      

      def decide(): String = {

        val randValue = random.nextDouble()

        var cumulative = 0.0

        

        for ((choice, prob) <- sortedProbabilities) {

          cumulative += prob

          if (randValue <= cumulative) {

            return choice

          }

        }

        sortedProbabilities.last._1

      }

    }

    

    // 复杂决策场景

    val decisionMaker = new MonteCarloDecision(Map(

      "aggressive" -> 0.2,    // 20%概率选择激进策略

      "moderate" -> 0.5,      // 50%概率选择中等策略  

      "conservative" -> 0.3   // 30%概率选择保守策略

    ))

    

    val monteCarloScenario = scenario("Monte Carlo Decision Making")

      .exec(session => {

        val strategy = decisionMaker.decide()

        session.set("tradingStrategy", strategy)

      })

      .doIf(session => session("tradingStrategy").as[String] == "aggressive") {

        exec(http("Aggressive Trading")

          .post("/trade/aggressive")

          .body(StringBody("""{"risk":"high"}"""))

          .check(status.is(200)))

      }

      .doIf(session => session("tradingStrategy").as[String] == "moderate") {

        exec(http("Moderate Trading")  

          .post("/trade/moderate")

          .body(StringBody("""{"risk":"medium"}"""))

          .check(status.is(200)))

      }

      .doIf(session => session("tradingStrategy").as[String] == "conservative") {

        exec(http("Conservative Trading")

          .post("/trade/conservative") 

          .body(StringBody("""{"risk":"low"}"""))

          .check(status.is(200)))

      }

  }

}


5. 复合控制流模式

复杂业务逻辑流程


scala

class ComplexWorkflowSimulation extends Simulation {

  

  val businessWorkflowScenario = scenario("Complex Business Workflow")

    .exec(session => session

      .set("userLevel", "premium")

      .set("retryCount", 0)

      .set("maxRetries", 3)

      .set("itemsToProcess", List("A", "B", "C", "D", "E"))

    )

    

    // 条件循环组合

    .doWhile(session => {

      val retryCount = session("retryCount").as[Int]

      val maxRetries = session("maxRetries").as[Int]

      val isSuccess = session.contains("operationSuccess") && 

                     session("operationSuccess").as[Boolean]

      retryCount < maxRetries && !isSuccess

    }) {

      exec(http("Retry Operation")

        .post("/operation")

        .check(status.saveAs("httpStatus"))

        .check(if (session => session("httpStatus").as[Int] == 200) {

          jsonPath("$.success").saveAs("operationSuccess")

        } else {

          status.not(200)

        }))

        .exec(session => {

          val count = session("retryCount").as[Int]

          session.set("retryCount", count + 1)

        })

        .pause(1)

    }

    

    // 集合处理和条件分支

    .foreach("${itemsToProcess}", "currentItem") {

      exec(session => {

        val random = new Random()

        val shouldSkip = random.nextDouble() < 0.1 // 10%跳过概率

        session.set("skipItem", shouldSkip)

      })

      .doIf(session => !session("skipItem").as[Boolean]) {

        exec(http("Process Item")

          .post("/process/${currentItem}")

          .check(status.is(200)))

          .doIf(session => session("userLevel").as[String] == "premium") {

            exec(http("Premium Processing")

              .post("/premium/process/${currentItem}")

              .check(status.is(200)))

          }

      }

    }

    

    // 随机路径选择

    .randomSwitch(

      40.0 -> exec( // 40%走标准路径

        http("Standard Path")

          .get("/standard/complete")

          .check(status.is(200))

      ),

      

      35.0 -> exec( // 35%走增强路径

        http("Enhanced Path")  

          .get("/enhanced/complete")

          .check(status.is(200))

          .repeat(2) {

            exec(http("Additional Step")

              .get("/additional/step")

              .check(status.is(200)))

          }

      ),

      

      25.0 -> exec( // 25%走高级路径

        http("Advanced Path")

          .get("/advanced/complete") 

          .check(status.is(200))

          .foreach(Seq("X", "Y", "Z"), "advancedItem") {

            exec(http("Advanced Item Processing")

              .post("/advanced/process/${advancedItem}")

              .check(status.is(200)))

          }

      )

    )

  

  // 控制流性能监控

  object ControlFlowMonitoring {

    

    /**

     * 控制流执行时间追踪

     */

    class ExecutionTimer(operationName: String) {

      private val startTime = System.currentTimeMillis()

      

      def recordCompletion(session: Session): Session = {

        val endTime = System.currentTimeMillis()

        val duration = endTime-startTime

        session.set(s"${operationName}Duration", duration)

      }

    }

    

    // 带监控的控制流执行

    val monitoredScenario = scenario("Monitored Control Flow")

      .exec(session => {

        val timer = new ExecutionTimer("mainWorkflow")

        session.set("workflowTimer", timer)

      })

      .repeat(5) { i =>

        exec(session => {

          val loopTimer = new ExecutionTimer(s"loop$i")

          session.set(s"loop${i}Timer", loopTimer)

        })

        .exec(http("Monitored Request")

          .get("/monitored/endpoint")

          .check(status.is(200)))

        .exec(session => {

          val timer = session(s"loop${i}Timer").as[ExecutionTimer]

          timer.recordCompletion(session)

        })

      }

      .exec(session => {

        val timer = session("workflowTimer").as[ExecutionTimer]

        timer.recordCompletion(session)

      })

  }

}


错误处理和恢复模式


scala

class ErrorHandlingSimulation extends Simulation {

  

  val resilientScenario = scenario("Resilient Control Flow")

    .exec(session => session

      .set("attemptCount", 0)

      .set("maxAttempts", 3)

      .set("fallbackEnabled", true)

    )

    

    // tryMax错误恢复模式

    .tryMax(3) { // 最大重试3次

      exec(http("Unreliable Operation")

        .get("/unreliable/endpoint")

        .check(status.is(200))

        .check(jsonPath("$.success").is("true")))

    }

    .exitHereIfFailed // 如果重试都失败则退出

    

    // 条件错误恢复

    .doIf(session => session.contains("shouldRetry") && session("shouldRetry").as[Boolean]) {

      tryMax(2) {

        exec(http("Conditional Retry")

          .get("/conditional/retry")

          .check(status.is(200)))

      }

    }

    

    // 错误分支处理

    .doIfOrElse(session => session.contains("operationFailed") && session("operationFailed").as[Boolean]) {

      exec(http("Fallback Operation")

        .get("/fallback/operation")

        .check(status.is(200)))

        .exec(session => session.set("usedFallback", true))

    } {

      exec(http("Normal Continuation")

        .get("/normal/continuation")

        .check(status.is(200)))

    }

    

    // 循环错误恢复

    .repeat(5, "retryLoop") {

      exec(session => session.set("currentAttempt", 0))

      .doWhile(session => {

        val currentAttempt = session("currentAttempt").as[Int]

        val maxAttempts = 2

        val isSuccess = session.contains("loopSuccess") && session("loopSuccess").as[Boolean]

        currentAttempt < maxAttempts && !isSuccess

      }) {

        exec(http("Loop Operation")

          .get("/loop/operation")

          .check(status.saveAs("loopStatus"))

          .check(if (session => session("loopStatus").as[Int] == 200) {

            jsonPath("$.success").saveAs("loopSuccess")

          } else {

            status.not(200)

          }))

          .exec(session => {

            val attempt = session("currentAttempt").as[Int]

            session.set("currentAttempt", attempt + 1)

          })

          .pause(1)

      }

    }

  

  // 高级错误处理策略

  object AdvancedErrorHandling {

    

    /**

     * 指数退避重试策略

     */

    class ExponentialBackoffRetry(

      maxRetries: Int,

      initialDelay: FiniteDuration,

      maxDelay: FiniteDuration

    ) {

      

      def retryWithBackoff(operation: ChainBuilder): ChainBuilder = {

        var chain = operation

        var currentDelay = initialDelay

        

        for (attempt <- 1 to maxRetries) {

          chain = chain.tryMax(1) {

            operation

          }.pause(currentDelay)

          

          currentDelay = (currentDelay * 2).min(maxDelay)

        }

        

        chain

      }

    }

    

    // 使用指数退避

    val backoffRetry = new ExponentialBackoffRetry(

      maxRetries = 4,

      initialDelay = 1.second,

      maxDelay = 30.seconds

    )

    

    val backoffScenario = scenario("Exponential Backoff Retry")

      .exec(backoffRetry.retryWithBackoff(

        exec(http("Backoff Operation")

          .get("/backoff/endpoint")

          .check(status.is(200)))

      ))

  }

}


6. 性能优化

控制流性能调优


scala

object ControlFlowOptimization {

  

  // 循环性能优化策略

  def optimizedLoop(iterations: Int, operation: ChainBuilder): ChainBuilder = {

    if (iterations <= 0) {

      // 空循环处理

      exec(session => session)

    } else if (iterations == 1) {

      // 单次迭代优化

      operation

    } else if (iterations <= 10) {

      // 小循环直接展开

      repeat(iterations) {

        operation

      }

    } else {

      // 大循环分批处理

      val batchSize = Math.min(iterations, 50)

      repeat(iterations / batchSize) {

        repeat(batchSize) {

          operation

        }

        .pause(100.milliseconds) // 防止资源耗尽

      }

    }

  }

  

  // 条件评估优化

  def cachedCondition(condition: Session => Boolean): Session => Boolean = {

    var lastSession: Option[Session] = None

    var lastResult: Option[Boolean] = None

    

    session => {

      if (lastSession.contains(session) && lastResult.isDefined) {

        lastResult.get

      } else {

        val result = condition(session)

        lastSession = Some(session)

        lastResult = Some(result)

        result

      }

    }

  }

}


// 内存使用优化

object MemoryOptimization {

  

  /**

   * 大集合处理的内存优化策略

   */

  def processLargeDataset[T](

    dataset: Seq[T],

    chunkSize: Int,

    processor: Seq[T] => ChainBuilder

  ): ChainBuilder = {

    

    val chunks = dataset.grouped(chunkSize).toList

    

    chunks.zipWithIndex.foldLeft(exec(session => session)) { case (chain, (chunk, index)) =>

      chain

        .exec(session => session.set(s"chunk_$index", chunk))

        .exec(processor(chunk))

        .exec(session => session.remove(s"chunk_$index")) // 及时清理内存

    }

  }

}


监控和调试配置


scala

class ControlFlowMonitoringSimulation extends Simulation {

  

  val monitoredScenario = scenario("Control Flow Monitoring")

    .exec(session => session

      .set("debugEnabled", true)

      .set("startTime", System.currentTimeMillis())

    )

    

    // 调试信息记录

    .doIf(session => session("debugEnabled").as[Boolean]) {

      exec(session => {

        println(s"开始执行控制流-会话ID: ${session.userId}")

        session

      })

    }

    

    .repeat(3, "monitoredLoop") {

      exec(session => {

        val loopIndex = session("monitoredLoop").as[Int]

        if (session("debugEnabled").as[Boolean]) {

          println(s"循环迭代: $loopIndex")

        }

        session.set("loopStartTime", System.currentTimeMillis())

      })

      .exec(http("Monitored Request")

        .get("/monitored/endpoint")

        .check(status.is(200)))

      .exec(session => {

        val duration = System.currentTimeMillis()-session("loopStartTime").as[Long]

        if (session("debugEnabled").as[Boolean]) {

          println(s"循环迭代完成,耗时: ${duration}ms")

        }

        session

      })

    }

    

    .exec(session => {

      val totalTime = System.currentTimeMillis()-session("startTime").as[Long]

      println(s"控制流执行完成,总耗时: ${totalTime}ms")

      session

    })

  

  // 性能断言配置

  val assertions = Seq(

    global.allRequests.percent.is(100),

    global.responseTime.percentile4.lt(800),

    

    // 控制流特定断言

    details("Monitored Request").requestsPerSec.gt(10),

    details("Monitored Request").responseTime.max.lt(1000)

  )

}


这种专业的Gatling控制流实现了从基础条件判断到复杂业务工作流,保证了性能测试场景的真实性和复杂性模拟能力。


文章标签: 压力测试 软件测试 测试工具 软件测评 负载测试
咨询软件测试