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控制流实现了从基础条件判断到复杂业务工作流,保证了性能测试场景的真实性和复杂性模拟能力。