Gatling学习笔记(三)---场景设置及基本概念

喜你入骨 提交于 2020-02-04 16:50:08


简述

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)
// 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)
// 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)
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!