此篇译文主要解释 Simulation 的 setup
原文来自:http://gatling.io/docs/2.1.7/general/simulation_setup.html
最近年底忙疯了,刚刚有时间更新博客。
simulation 的 setup 主要用来设置并发模式,类似于 LoadRunner 中的 controller,是 Gatling 中比较重要的一个功能。因此译者也贴出了自己的 setup 源码和对应的测试报告截图。
还是那句,欢迎转载,不过请注明出处。
在 Setup 中,你可以定义你需要注入到 server 的负载。
可以在 setup 中使用如下两个方法:
注入方法用来定义虚拟用户的操作。这个方法可以加入一系列的参数来设置线性注入的步骤。
如下面这个例子:
setUp(
scn.inject(
nothingFor(4 seconds), // 1
atOnceUsers(10), // 2
rampUsers(10) over(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
splitUsers(1000) into(rampUsers(10) over(10 seconds)) separatedBy(10 seconds), // 8
splitUsers(1000) into(rampUsers(10) over(10 seconds)) separatedBy atOnceUsers(30), // 9
heavisideUsers(1000) over(20 seconds) // 10
).protocols(httpConf)
)
解释下上面的代码(译者注:灰常重要!因此每个注入的下面都有译者自己写的注入以及对应的截图,毕竟一图胜千言。其中橙色的线代表活跃用户数,绿色代表请求数):
1.nothingFor(duration):设置一段停止的时间;
不解释
2.atOnceUsers(nbUsers):立即注入一定数量的虚拟用户;
setUp(scn.inject(atOnceUsers(50))
.protocols(httpConf))
3.rampUsers(nbUsers) over(duration):在指定时间内,设置一定数量逐步注入的虚拟用户;
setUp(scn.inject(rampUsers(50) over(30 seconds))
.protocols(httpConf))
4.constantUsersPerSec(rate) during(duration):定义一个在每秒钟恒定的并发用户数,持续指定的时间;
setUp(scn.inject(constantUsersPerSec(30) during(15 seconds))
.protocols(httpConf))
5.constantUsersPerSec(rate) during(duration) randomized:定义一个在每秒钟围绕指定并发数随机增减的并发,持续指定时间;
setUp(scn.inject(constantUsersPerSec(30) during(15 seconds) randomized)
.protocols(httpConf))
6.rampUsersPerSec(rate1) to (rate2) during(duration):定义一个并发数区间,运行指定时间,并发增长的周期是一个规律的值;
setUp(scn.inject(rampUsersPerSec(30) to (50) during(15 seconds))
.protocols(httpConf))
7.rampUsersPerSec(rate1) to(rate2) during(duration) randomized:定义一个并发数区间,运行指定时间,并发增长的周期是一个随机的值;
setUp(scn.inject(rampUsersPerSec(30) to (50) during(15 seconds) randomized)
.protocols(httpConf))
8.heavisideUsers(nbUsers) over(duration):定义一个持续的并发,围绕和海维赛德函数平滑逼近的增长量,持续指定时间(译者解释下海维赛德函数,H(x) 当 x>0 时返回 1,x<0 时返回 0,x=0 时返回 0.5。实际操作时,并发数是一个成平滑抛物线形的曲线);
setUp(scn.inject(heavisideUsers(50) over(15 seconds))
.protocols(httpConf))
9.splitUsers(nbUsers) into(injectionStep) separatedBy(duration):定义一个周期,执行 injectionStep 里面的注入,将 nbUsers 的请求平均分配;
setUp(scn.inject(splitUsers(50) into(rampUsers(10) over(10 seconds)) separatedBy(10 seconds))
.protocols(httpConf))
10.splitUsers(nbUsers) into(injectionStep1) separatedBy(injectionStep2):使用 injectionStep2 的注入作为周期,分隔 injectionStep1 的注入,直到用户数达到 nbUsers;
setUp(scn.inject(splitUsers(100) into(rampUsers(10) over(10 seconds)) separatedBy atOnceUsers(30))
.protocols(httpConf))
注意
请根据实际情况选择合适的注入模块来实现你的 case。
你载入的注入模块不仅关系到你预期的吞吐量(每秒钟发送的请求数),也关系到每秒钟打开/关闭的连接数。
一些基础的负载测试工具,像 wrk 或者 ab 值支持 closed models: 也就是说,我们先假定 keep alive 被启用,然后用户不断循环执行场景,你有多少个用户就有多少个连接,而且这些连接从没有关闭过。这种测试模型对于像 call centers 这种业务的系统来说比较适合,因为新用户一直在排队,由管理员挂断电话来接入下一个用户。
在 Gatling 中,使用 constantUsersPerSec 和 rampUsersPerSec 两个模块,我们可以得到 open models:Gatling 的新用户会一直启用,无论你之前已经启用了多少个用户都可以。甚至是系统已经过载导致运行缓慢或者挂掉,也不会影响新用户的启用。这种模式是绝大部分场景中比较适合的。
所以我们发现,Gatling 中默认的操作方式就是模拟真实的浏览器用户行为,每个虚拟用户都是有他们自己的连接。如果我们的场景是高频率地创建用户,场景的生命周期又短的话,可能我们面临的问题是我们要在每秒中打开/关闭大量的连接。这样就会带来一个问题,我们的系统资源可能会被用光。比如端口号,系统可能不会及时地重新分配端口。这种情况下,我们一般可以使用如下方法:
* 使用横向扩展(译者注,增加集群的服务器数量等);
* 重新考虑你的注入模型:也许你只是在测试一个只有几个客户端使用的 webservice,这种情况下应该使用只有几个连接的 closed model;
* 调整 Gatling 的配置,使虚拟用户之间可以共享连接池,具体看这里:http://gatling.io/docs/2.1.7/http/http_protocol.html#http-protocol-connection-sharing
为了全局暂停时间的配置,Gatling 提供了一系列的方法支持(时间关系,译者并没有来得及逐个尝试过下面的这些方法,下面这段内容只提供了翻译):
注意
暂停时间也可以在场景等级中进行设置
如果你希望设置每秒钟请求的数量,而不是每秒钟的并发数,那么应该考虑使用 constantUsersPerSec(...) 去设置用户的到达比例。在大多数的情况下,请求都是不需要使用请求限制的,或者至少是多余的。
但在某些情况下,我们需要使用 Gatling 自带的 throttle 方法,来对请求数做一个限制。
注意
setUp(scn.inject(constantUsersPerSec(100) during(30 minutes))).throttle(
reachRps(100) in (10 seconds),
holdFor(1 minute),
jumpToRps(50),
holdFor(2 hours)
)
解释下上述代码:
simulation 会限制每秒钟 100 个请求,持续 10 秒钟,然后保持住这个吞吐量并持续 1 分钟;接着跳到每秒钟 50 个请求,再保持这个吞吐量 2 个小时;
这个代码块中设置的请求限制如下:
最后,我们可以使用 maxDuration 来配置 simulation 持续的最大时间。这个方法是当你无法预期测试的执行时间时,用来限制运行时间的边界值。
setUp(scn.inject(rampUsers(1000) over(20 minutes))).maxDuration(10 minutes)