Gatling中设计高级负载时候,在固定时长、精确控制并发用户数和分阶段调整压力方面需要一些技巧。
Gatling的负载模型和配置
Gatling的负载模型是设计高级场景的基础,分为开放模型和封闭模型。
开放模型 :通过控制用户到达速率来施压。例如,使用 constantUsersPerSec(20) during (10 minutes) 意味着每秒尝试启动20个用户,无论系统响应如何。这模拟了用户不断独立到达的场景。
封闭模型 :通过控制系统中的并发用户数来施压。例如,constantConcurrentUsers(50) during (10 minutes) 能保证系统中始终有50个活跃的并发用户。当一个用户任务完成退出时,Gatling会立即注入一个新用户来维持总数。这对于模拟固定规模的用户群(如特定数量的连接池或已登录用户)非常有用。
要精确控制测试时长,特别是搭配throttle或maxDuration使用时,需要注意:
用户注入和测试时长:测试的实际持续时间由用户注入的持续时间和虚拟用户执行场景所需的时间共同决定。如果场景执行时间很短,即使设置了during (10 minutes),测试也可能提前结束。为了让测试精确运行指定时长,你需要确保用户注入的持续时间和期望的测试时长一致,并且场景能够持续运行。
实现固定持续时间测试
让测试精确运行特定时长,有两种方法:
1. 使用组合注入方式
通过组合不同的注入步骤,让用户注入过程填满整个测试周期。
scala
setUp(
scn.inject(
// 在10分钟内,逐步将并发用户数从10增加到100
rampConcurrentUsers(10) to 100 during (10 minutes)
).protocols(httpProtocol)
// 确保测试总时长不超过10分钟
.maxDuration(10 minutes)
)
2. 创建循环场景和持续注入
如果单个场景很短,可以将其放入循环,并持续注入用户。
scala
// 定义一个会循环执行多次的场景
val loopingScn = scenario("Looping Scenario")
// 循环100次,或直到测试被强制结束
.forever() {
exec(http("API Call").get("/endpoint"))
.pause(1 second)
}
setUp(
loopingScn.inject(
// 在2秒内启动100个用户,然后让他们持续运行(循环)
rampUsers(100) during (2 seconds)
).protocols(httpProtocol)
).maxDuration(10 minutes) // 无论场景如何,10分钟后强制结束测试
控制最大并发数
需要精确控制系统中活跃用户的总数,封闭模型就是你的最佳选择。
scala
setUp(
scn.inject(
// 在1分钟内保持20个并发用户
constantConcurrentUsers(20) during (1 minute)
).protocols(httpProtocol)
)
constantConcurrentUsers 通过"完成一个,立刻补充一个"的机制维持着并发数。意味着你必须注入足够的用户来维持并发。如果场景执行时间很短,用户会快速完成并重启,导致报告中的"活跃用户数"出现波动。如果需要用户执行长时间任务,可以在场景中加入pause或循环来延长其生命周期。
设计分阶段压力调整
模拟真实的压力变化,如逐渐增压、稳定压力和峰值测试,需要组合多种注入方式了。
scala
setUp(
scn.inject(
// 1. 热身阶段:30秒内逐渐增加到10个并发用户
rampConcurrentUsers(1) to 10 during (30 seconds),
// 2. 稳定阶段:保持10个并发用户,持续2分钟
constantConcurrentUsers(10) during (2 minutes),
// 3. 压力阶段:1分钟内将并发用户数提升到50个
rampConcurrentUsers(10) to 50 during (1 minute),
// 4. 峰值维持:保持50个并发用户,持续3分钟
constantConcurrentUsers(50) during (3 minutes),
// 5. 下降阶段:1分钟内将并发用户数减少到0
rampConcurrentUsers(50) to 0 during (1 minute)
).protocols(httpProtocol)
).maxDuration(8 minutes) // 总测试时长约8分钟
另一种思路是控制请求速率 (RPS),可以使用throttle功能。但请记住,throttle是一个限制器,让它生效,必须注入足够多的用户,以便有能力达到你设定的目标RPS。如果用户数量不足或响应时间过长,将无法达到目标RPS。
scala
setUp(
scn.inject(
constantUsersPerSec(5) during (10 minutes) // 持续注入用户
).protocols(httpProtocol)
).throttle(
// 分阶段调整RPS限制
reachRps(20) in (30 seconds), // 30秒内逐步将RPS限制提高到20
holdFor(5 minutes), // 在20 RPS下保持5分钟
jumpToRps(50), // 瞬间将RPS限制提高到50
holdFor(3 minutes) // 在50 RPS下保持3分钟
).maxDuration(10 minutes)
实战技巧
这里有一个上述概念的完整示例,并附带一些进阶技巧。
scala
import io.gatling.core.Predef._
import io.gatling.http.Predef._
import scala.concurrent.duration._
class AdvancedLoadSimulation extends Simulation {
val httpProtocol = http
.baseUrl("https://your-api.com")
.shareConnections // 连接复用,提升效率
// 定义一个包含思考时间和复杂操作的用户场景
val complexScn = scenario("Complex User Journey")
.forever() { // 让场景循环执行,以配合固定时长测试
exec(http("Get Homepage").get("/"))
.pause(2, 5) // 随机停顿,模拟用户阅读
.exec(http("API Request").get("/api/data")
.check(status.is(200)))
.pause(1)
.exec(http("Post Data").post("/api/submit")
.body(StringBody("""{"data": "payload"}"""))
.asJson
.check(jsonPath("$.status").is("ok")))
.pause(3, 7) // 更长的随机停顿
}
// 封闭模型:精确控制并发用户数
val closedModelInjection =
constantConcurrentUsers(15) during (5 minutes) // 保持15个并发用户5分钟
// 开放模型:控制用户到达速率,用于RPS目标
val openModelInjection =
rampUsersPerSec(1) to 10 during (2 minutes) // 在2分钟内,每秒到达用户数从1增加到10
setUp(
// 可以切换不同的注入配置
complexScn.inject(closedModelInjection).protocols(httpProtocol)
// complexScn.inject(openModelInjection).protocols(httpProtocol)
)
// 可选:添加节流阀来控制RPS上限
/*
.throttle(
reachRps(25) in (1 minute),
holdFor(4 minutes)
)
*/
.maxDuration(5 minutes) // 安全网,确保测试准时结束
// 添加断言,验证性能指标是否达标
.assertions(
global.responseTime.max.lt(1500), // 全局最大响应时间小于1.5秒
global.successfulRequests.percent.gt(99) // 成功率高于99%
)
}
一点点技巧:
使用断言 (Assertions):在测试配置的最后加入 .assertions,可以为响应时间、成功率等关键指标设置质量门禁 (Quality Gates)。如果指标不达标,测试将标记为失败,这在CI/CD流水线中非常有用。
理解活跃用户数 (Active Users):Gatling报告中的"活跃用户数"是一个混合指标,代表在给定秒内系统上活动的用户。在封闭模型中,它通常接近你设置的并发用户数。在开放模型中,取决于用户到达速率和场景执行时间。
固定时长测试:结合持续的用户注入(如循环场景)和maxDuration。
精确并发用户控制:使用封闭模型注入策略,如constantConcurrentUsers。
分阶段压力调整:在inject方法中组合多种注入步骤(如 rampConcurrentUsers 和 constantConcurrentUsers)。
控制请求速率 (RPS):使用 throttle,但要确保注入了足够的用户。
如果你的测试目标和同时在线用户数相关(如服务器连接池测试),选择封闭模型。
如果你的测试目标和事务吞吐量(如每秒处理订单数)相关,或者模拟用户独立到达的场景(如网站访问),选择开放模型并结合throttle。