此篇译文主要解释Simulation的setup
原文来自:http://gatling.io/docs/2.1.7/general/simulation_setup.html
最近年底忙疯了,刚刚有时间更新博客。
simulation的setup主要用来设置并发模式,类似于LoadRunner中的controller,是Gatling中比较重要的一个功能。因此译者也贴出了自己的setup源码和对应的测试报告截图。
还是那句,欢迎转载,不过请注明出处。
在Setup中,你可以定义你需要注入到server的负载。
可以在setup中使用如下两个方法:
- assertions – 设置assertion用的
- protocols – 设置协议用的
注入方法用来定义虚拟用户的操作。这个方法可以加入一系列的参数来设置线性注入的步骤。
如下面这个例子:
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提供了一系列的方法支持(时间关系,译者并没有来得及逐个尝试过下面的这些方法,下面这段内容只提供了翻译):
- disablePauses :禁用掉simulation中的暂停;
- constantPauses:精确设置定义为pause(duration)的暂停的持续时间;
- exponentialPauses:设置定义为pause(duration)的暂停的持续时间,使停顿时间按照指数分布;
- normalPauses(stdDev: Double):设置定义为pause(duration)的暂停的持续时间,使停顿时间按照正态分布。stdDev用毫秒数表示,默认值为1.0;
- customPauses(custom: Expression[Long]):暂停时间被设置为表达式的时间。这种情况下,填入的时间会被跳过;
- uniformPausesPlusOrMinusPercentage(plusOrMinus: Double) 和 uniformPausesPlusOrMinusDuration(plusOrMinus: Duration):设置定义为pause(duration)的暂停的持续时间,使停顿时间按照均匀分布;
注意
暂停时间也可以在场景等级中进行设置
如果你希望设置每秒钟请求的数量,而不是每秒钟的并发数,那么应该考虑使用constantUsersPerSec(…)去设置用户的到达比例。在大多数的情况下,请求都是不需要使用请求限制的,或者至少是多余的。
但在某些情况下,我们需要使用Gatling自带的throttle方法,来对请求数做一个限制。
注意
- 我们仍然需要在场景等级中注入虚拟用户。请求限制只是用来给定的场景中设置一个确定的吞吐量,以及注入的用户数量和持续时间。这就是设置了一个瓶颈,也就是一个上限。如果没有设置了足够的用户数,则不会达到这个限制。如果注入持续的时间没有达到请求限制的设定,那么所有虚拟用户执行完毕后,simulation会被终止。如果注入的时间超过了请求限制的设定,那么请求限制就会起作用,阻止simulation的执行。
- 请求限制可以在每个场景中进行配置,移步这里找到更多:http://gatling.io/docs/2.1.7/general/scenario.html#scenario-throttling
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个小时;
这个代码块中设置的请求限制如下:
- reachRps(target) in (duration):设置一个恒定的吞吐量,并持续一段时间;
- jumpToRps(target):立即将限制切换为另一个吞吐量;
- holdFor(duration):将当前的吞吐量保持一定的时间;
最后,我们可以使用maxDuration来配置simulation持续的最大时间。这个方法是当你无法预期测试的执行时间时,用来限制运行时间的边界值。
setUp(scn.inject(rampUsers(1000) over(20 minutes))).maxDuration(10 minutes)