性能测试工具 Gatling 学习笔记 (三)---场景设置及基本概念

ZengTester · 2020年02月07日 · 1612 次阅读

简述

Gatling 是基于 AKKA 和 Netty 开发的一款高性能压测工具,本章节主要讲述 Gatling 提供的 API 和一些基本概念


1. 施压场景设置

gatling 主要压测的关键在于场景设置,这决定了你要干什么和你的目标
一般可以使用以下两种方法配置断言和协议:

  • assertions:在模拟中设置断言
  • protocols:设置协议定义

1.1 注入

1.1.1 注入模型基本概念

在使用 gatling 的时候我们会发现有时候 gatling 的一些注入方案和我们设想的方便并不相同,使得我们的方案出现偏差或者交流问题。前面说过我曾经加入过一个 Gatling 的技术分享群,我发现其实很多人并没有理解 gatling 中的开放模型 (Open Model) 和封闭模型 (Closed Model) 是什么意思,所以这里会对 gatling 的两种模型进行描述,我的理解是这两种模型分别代表了现在主流的两种压测模式 RPS 和并发这两种模式,关于这两种模式的差异我在这里面不做过多的描述,大家可以看这篇文章,里面有具体的描述传送门
开放模型 (Open Model)
开放模型中我们可以主动的控制用户的到达率,这个和我们 jmeter 或者 ab 的并发概念会有出入,次模型中涉及的方法均为 RPS 的压测模式,使用开放模型会有什么好处呢?

  1. 了解每阶段用户真实的请求量,与并发的不可控的情况下,这种场景会更加偏向于真实
  2. 每个请求链或者请求都是一个新的连接,复用较少,会发现以前一些因为连接数不够而为发现的问题
  3. 请求持续注入,当系统已经达到性能瓶颈时,不会与并发一样减少请求量,而是会以设置的请求量持续注入

开放模型的坏处:

  1. 每个虚拟用户都有自己的连接。如果您的生命周期短,用户创造率很高,那么您每秒将不得不打开和关闭大量连接。结果,您可能会用完资源(例如临时端口,因为您的操作系统无法足够快地回收它们)
  2. 与服务端连接数较多,当服务端处理过慢出现堆积的时候,会导致压测脚本崩溃

封闭模型
封闭模型可控制并发用户数,这与 jmeter 的线程组和 ab 的并发概念相同,保持一定的连接数并复用,减少因为建立连接所导致的问题,满负荷运行时,新用户只有在另一个用户退出后才能有效地进入系统。
封闭模型的好处:

  1. 可以快速了解到系统的极限值在哪里
  2. 线程复用,不会每秒打开或者关闭连接导致系统资源出现问题

封闭模型的坏处:

  1. 无法复现因为连接数导致的问题
  2. 无法模拟真实用户的场景

1.1.2 注入方式

Gatling 是通过 inject 注入方式来模拟用户操作的场景
开放模型

setUp(
  scn.inject(
    nothingFor(4 seconds), // 1
    atOnceUsers(10), // 2
    rampUsers(10) during (5 seconds), // 3
    constantUsersPerSec(20) during (15 seconds), // 4
    constantUsersPerSec(20) during (15 seconds) randomized, // 5
    rampUsersPerSec(10) to 20 during (10 minutes), // 6
    rampUsersPerSec(10) to 20 during (10 minutes) randomized, // 7
    heavisideUsers(1000) during (20 seconds) // 8
  ).protocols(httpProtocol)
)
  1. nothingFor(duration):设置一段停止的时间,这段时间什么都不做
  2. atOnceUsers(nbUsers):立即注入一定数量的虚拟用户
  3. rampUsers(nbUsers) during(duration):在指定时间内,设置一定数量逐步注入的虚拟用户
  4. constantUsersPerSec(rate) during(duration):定义一个在每秒钟恒定的并发用户数,持续指定的时间
  5. constantUsersPerSec(rate) during(duration) randomized:定义一个在每秒钟围绕指定并发数随机增减的并发,持续指定时间
  6. rampUsersPerSec(rate1) to (rate2) during(duration):定义一个并发数区间,运行指定时间,并发增长的周期是一个规律的值
  7. rampUsersPerSec(rate1) to(rate2) during(duration) randomized:定义一个并发数区间,运行指定时间,并发增长的周期是一个随机的值
  8. heavisideUsers(nbUsers) during(duration) :按照延伸到给定持续时间的重阶梯函数的平滑近似值,注入给定数量的用户

封闭模式

setUp(
  scn.inject(
    constantConcurrentUsers(10) during (10 seconds), // 1
    rampConcurrentUsers(10) to (20) during (10 seconds) // 2
  )
)
  1. constantConcurrentUsers(nbUsers) during(duration): 在指定时间段内保持恒定的并发用户数量
  2. rampConcurrentUsers(10) to (20) during (10 seconds): 注入,以便系统中的并发用户数从一个数字线性增加到另一个

==注意点==

开放模型和封闭模型在工作负载模型具有相反的含义,不能将它们混合在同一 Injection 配置文件中

Meta DSL
在我们日常的工作中有时候并不知道接口的性能瓶颈在哪里,当我们使用开放模型测试时,会不停的进行重复的操作来定义每次爬升的值,为了解决这个问题 Gatling 在 3.0 开始添加了一种Meta DSL新的方法来方便我们操作

  • incrementUsersPerSec(usersPerSecAddedByStage) java // generate an open workload injection profile // with levels of 10, 15, 20, 25 and 30 arriving users per second // each level lasting 10 seconds // separated by linear ramps lasting 10 seconds setUp( scn.inject( incrementUsersPerSec(5) // Double .times(5) .eachLevelLasting(10 seconds) .separatedByRampsLasting(10 seconds) .startingFrom(10) // Double ) )
    • incrementConcurrentUsers(concurrentUsersAddedByStage) java // generate a closed workload injection profile // with levels of 10, 15, 20, 25 and 30 concurrent users // each level lasting 10 seconds // separated by linear ramps lasting 10 seconds setUp( scn.inject( incrementConcurrentUsers(5) // Int .times(5) .eachLevelLasting(10 seconds) .separatedByRampsLasting(10 seconds) .startingFrom(10) // Int ) )

incrementUsersPerSec 用于开放模型负载测试和 incrementConcurrentUsers 封闭模型负载 (users/sec vs concurrent users)

separatedByRampsLasting 并且 startingFrom 都是可选的。如果未指定坡度,则测试将在完成后立即从一个级别跳到另一级别。如果未指定起始用户数,则测试将从 0 个并发用户或 0 个用户/秒开始,并立即进行下一步。

1.2 全局暂停配置

当我们需要使用暂停时,可以使用Simulation的多种方法配置暂停,而且暂停定义也可以放在 scenario 中进行配置:

  1. disablePauses:禁用模拟暂停
  2. constantPauses:每个暂停的持续时间正是 pause(duration) 元素中指定的持续时间。
  3. exponentialPauses:每个暂停的持续时间平均为 pause(duration) 元素中指定的持续时间,并遵循指数分布。
  4. normalPausesWithStdDevDuration(stdDev: Duration):每个暂停的持续时间平均为 pause(duration) 元素中指定的时间,并遵循正态分布。stdDev 是持续时间。
  5. normalPausesWithPercentageDuration(stdDev: Double):每个暂停的持续时间平均为 pause(duration) 元素中指定的时间,并遵循正态分布。stdDev 是暂停值的百分比。
  6. customPauses(custom: Expression[Long]):暂停持续时间由提供的计算 Expression[Long]。在这种情况下,将跳过填充时间。
  7. uniformPausesPlusOrMinusPercentage(plusOrMinus: Double)uniformPausesPlusOrMinusDuration(plusOrMinus: Duration):每个暂停的持续时间平均为元素中指定的时间,并且遵循均匀分布
setUp(
  ...
 ).protocols(protocol)
   .pauses(uniformPausesPlusOrMinusPercentage(1))
   .disablePauses
   .constantPauses
   .exponentialPauses
   .uniformPauses(1.5)
   .uniformPauses(1337 seconds)

1.3 节流 (Throttling)

如果需要 RPS 而不是并发用户数进行压测,可以使用 constantUsersPerSec(…) 来设置用户的到达率,因此无需节流即可设置请求,因为这在大多数情况下都是多余的,如果由于某种原因这还不够,那么可以使用 Gatling 的 throttle 方法进行节流,节流是按协议实现的,并支持常规 HTTP 和 JMS 请求
==注意==
仍然必须在 scenario 注入用户。节流尝试使用给定 scenario 及其注入配置文件(用户数和持续时间)来确保目标吞吐量。这是一个上限,如果当预设值没有达到指定的,将无法达到节流所设置的目标。如果施压时间少于节流设置的时间,则在所有用户完成后施压会主动停止,如果的设置的持续时间超过节流时间,则施压将在节流所设置的末端停止
也可以根据情况配置节流。

setUp(scn.inject(constantUsersPerSec(100) during (30 minutes))).throttle(
  reachRps(100) in (10 seconds),
  holdFor(1 minute),
  jumpToRps(50),
  holdFor(2 hours)
)

此段代码是模拟为 10 秒内达到 100req/s,然后保持 1 分钟这个吞吐量后请求量跳到 50 req/s 并保持两小时

节流的基础是:

reachRps(target) in (duration):在指定的 RPS 达到指定目标
jumpToRps(target):立即跳转到指定的目标 RPS
holdFor(duration):在指定的时间段内保持当前的吞吐量

1.4 最长持续时间

在有时候压测过程中,会因为各种原因我们无法估计脚本结束的时间,例如当服务端无法处理请求且未设置
maxDuration 即使某些虚拟用户仍在运行,您也可以根据持续时间限制来强制终止运行。

如果您需要在无法预测的情况下限制仿真的持续时间,这将非常有用。

setUp(scn.inject(rampUsers(1000) during (20 minutes))).maxDuration(10 minutes)
暂无回复。
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册