1.简介
在本教程中,我们将了解如何使用Gatling进行分布式性能测试。在此过程中,我们将创建一个简单的应用程序以使用Gatling进行测试,了解使用分布式性能测试的原理,最后,了解Gatling提供了哪些支持来实现它。
2.加特林的性能测试
性能测试是一种测试实践,用于评估系统在特定工作负载下的响应能力和稳定性。性能测试通常包含几种类型的测试。其中包括负载测试,压力测试,浸泡测试,峰值测试等。所有这些都有其自己的特定目标要实现。
但是,任何性能测试的一个共同方面是模拟工作负载,Gatling,JMeter和K6之类的工具可以帮助我们做到这一点。但是,在继续进行之前,我们需要一个可以测试性能的应用程序。
然后,我们将为该应用程序的性能测试开发一个简单的工作负载模型。
2.1。创建一个应用程序
在本教程中,我们将使用Spring CLI创建一个简单的Spring Boot Web应用程序:
spring init --dependencies=web my-application
接下来,我们将创建一个简单的REST API,该API可应要求提供一个随机数:
@RestController
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@GetMapping("/api/random")
public Integer getRandom() {
Random random = new Random();
return random.nextInt(1000);
}
}
此API没什么特别的-它每次调用仅返回0到999范围内的随机整数。
使用Maven命令启动此应用程序非常简单:
mvnw spring-boot:run
2.2。创建工作量模型
如果我们需要将此简单的API部署到生产中,则需要确保它可以处理预期的负载并仍提供所需的服务质量。这是我们需要执行各种性能测试的地方。工作负载模型通常标识一个或多个工作负载概要文件,以模拟实际使用情况。
对于具有用户界面的Web应用程序,定义适当的工作负载模型可能会非常具有挑战性。但是对于我们的简单API,我们可以对负载测试的负载分布进行假设。
Gatling提供了Scala DSL来创建要在仿真中测试的方案。首先,为我们之前创建的API创建一个基本方案:
package randomapi
import io.gatling.core.Predef._
import io.gatling.core.structure.ScenarioBuilder
import io.gatling.http.Predef._
import io.gatling.http.protocol.HttpProtocolBuilder
class RandomAPILoadTest extends Simulation {
val protocol: HttpProtocolBuilder = http.baseUrl("http://localhost:8080/")
val scn: ScenarioBuilder = scenario("Load testing of Random Number API")
.exec(
http("Get Random Number")
.get("api/random")
.check(status.is(200))
)
val duringSeconds: Integer = Integer.getInteger("duringSeconds", 10)
val constantUsers: Integer = Integer.getInteger("constantUsers", 10)
setUp(scn.inject(constantConcurrentUsers(constantUsers) during (duringSeconds))
.protocols(protocol))
.maxDuration(1800)
.assertions(global.responseTime.max.lt(20000), global.successfulRequests.percent.gt(95))
}
让我们讨论一下基本模拟中的要点:
- 我们首先添加一些必要的Gatling DSL导入
- 接下来,我们定义HTTP协议配置
- 然后,我们通过对API的单个请求定义一个方案
- 最后,我们为要注入的负载创建一个模拟定义;在这里,我们使用10个并发用户注入负载10秒钟
使用用户界面为更复杂的应用程序创建这种方案可能非常复杂。值得庆幸的是,Gatling附带了另一个实用程序,称为记录器。使用此记录器,我们可以通过允许它代理浏览器和服务器之间的交互来创建方案。它还可以使用HAR(HTTP存档)文件来创建方案。
2.3。执行模拟
现在,我们准备执行负载测试。为此,我们可以将仿真文件“ RandomAPILoadTest.scala”放在目录“%GATLING_HOME%/user-file/randomapi/”.
请注意,这不是执行模拟的唯一方法,但肯定是最简单的方法之一。
我们可以通过运行以下命令来启动加特林:
$GATLING_HOME/bin/gatling.sh
这将提示我们选择要运行的仿真:
Choose a simulation number:
[0] randomapi.RandomAPILoadTest
选择模拟后,它将运行模拟并生成带有摘要的输出:
此外,它在目录“%GATLING_HOME%/ results”中生成HTML格式的报告:
这只是生成的报告的一部分,但是我们可以清楚地看到结果摘要。这是非常详细且易于遵循的。
3.分布式性能测试
到目前为止,一切都很好。但是,回想一下,性能测试的目的是模拟实际工作负载。对于流行的应用程序来说,这可能比我们在这里琐碎的案例中看到的负载高出很多。如果我们在测试摘要中注意到,我们设法实现了大约500个请求/秒的吞吐量。对于处理实际工作负载的实际应用程序,这可能要高出许多倍!
我们如何使用任何性能工具来模拟这种工作量?是否真的可以仅通过单台机器注入负载来获得这些数字?也许不是。即使负载注入工具可以处理更高的负载,底层操作系统和网络也有其自身的局限性。
在这里,我们必须将负载注入分布在多台机器上。当然,像其他任何分布式计算模型一样,这也面临着自己的挑战:
- 我们如何在参与的机器之间分配工作量?
- 谁负责协调其完成和从可能发生的任何错误中恢复?
- 我们如何收集和汇总合并报表的结果?
分布式性能测试的典型体系结构使用主节点和从节点来解决以下问题:
但是,如果主机崩溃了,又会发生什么呢?解决分布式计算的所有问题不在本教程的范围内,但是在选择用于性能测试的分布式模型时,我们当然必须强调它们的含义。
4.带有加特林的分布式性能测试
既然我们已经了解了分布式性能测试的必要性,那么我们将了解如何使用Gatling实现这一目标。集群模式是Gatling Frontline的内置功能。但是,Frontline是Gatling的企业版,不能作为开源使用。 Frontline支持在本地或任何流行的云供应商上部署注入器。
尽管如此,仍然可以通过Gatling开源实现这一目标。但是,我们将不得不承担大部分繁重的工作。在本节中,我们将介绍实现它的基本步骤。在这里,我们将使用我们之前定义的相同仿真来生成多机负载。
4.1。设置
我们将首先在本地或任何云供应商上创建一个控制器计算机和多个远程工作器计算机。我们必须在所有这些计算机上执行某些先决条件。其中包括在所有工作机上安装Gatling开源程序以及设置一些控制器机器环境变量。
为了获得一致的结果,我们应该在所有辅助计算机上安装相同版本的Gatling,每台计算机上均配置相同。这包括我们在其中安装Gatling的目录以及我们创建要安装它的用户。
让我们看一下我们需要在控制器机器上设置的重要环境变量:
HOSTS=( 192.168.xx 192.168.xx 192.168.xx)
并且我们还定义了将用于从中注入负载的远程工作者计算机的列表:
GATLING_HOME=/gatling/gatling-charts-highcharts-1.5.6
GATLING_SIMULATIONS_DIR=$GATLING_HOME/user-files/simulations
SIMULATION_NAME='randomapi.RandomAPILoadTest'
GATLING_RUNNER=$GATLING_HOME/bin/gatling.sh
GATLING_REPORT_DIR=$GATLING_HOME/results/
GATHER_REPORTS_DIR=/gatling/reports/
一些变量指向Gatling安装目录以及我们开始模拟所需的其他脚本。它还提到了我们希望生成报告的目录。稍后我们将在哪里使用它们。
重要的是要注意,我们假设这些机器具有类似Linux的环境。但是,我们可以轻松地将该过程调整为适用于Windows等其他平台。
4.2。分配负载
在这里,我们将把相同的场景复制到我们先前创建的多台工作计算机上。有几种方法可以将模拟复制到远程主机。最简单的方法是对支持的主机使用scp
。我们还可以使用shell脚本自动执行此操作:
for HOST in "${HOSTS[@]}"
do
scp -r $GATLING_SIMULATIONS_DIR/* [email protected]$HOST:$GATLING_SIMULATIONS_DIR
done
上面的命令将本地主机上的目录内容复制到远程主机上的目录。对于Windows用户, Putty是PSCP(PuTTY安全复制协议)随附的更好的选择。我们可以使用PSCP在Windows客户端与Windows或Unix服务器之间传输文件。
4.3。执行模拟
将模拟复制到工作机后,就可以触发它们了。实现并发用户总数的关键是几乎在所有主机上同时执行模拟。
我们可以再次使用Shell脚本自动化此步骤:
for HOST in "${HOSTS[@]}"
do
ssh -n -f [email protected]$HOST \
"sh -c 'nohup $GATLING_RUNNER -nr -s $SIMULATION_NAME \
> /gatling/run.log 2>&1 &'"
done
我们正在使用ssh
触发远程工作者计算机上的模拟。这里要注意的关键是我们使用的是“无报告”选项(-nr)。这是因为我们仅在此阶段才有兴趣收集日志,并且稍后将通过合并所有辅助计算机的日志来创建报告。
4.4。收集结果
现在,我们需要在所有辅助计算机上收集由模拟生成的日志文件。同样,这是我们可以使用Shell脚本自动执行并可以在控制器计算机上执行的操作:
for HOST in "${HOSTS[@]}"
do
ssh -n -f [email protected]$HOST \
"sh -c 'ls -t $GATLING_REPORT_DIR | head -n 1 | xargs -I {} \
mv ${GATLING_REPORT_DIR}{} ${GATLING_REPORT_DIR}report'"
scp [email protected]$HOST:${GATLING_REPORT_DIR}report/simulation.log \
${GATHER_REPORTS_DIR}simulation-$HOST.log
done
对于那些不熟悉Shell脚本的人来说,这些命令似乎很复杂。但是,当我们将它们分成几部分时,并没有那么复杂。首先,我们将ssh
放入远程主机,以相反的时间顺序列出Gatling报告目录中的所有文件,并获取第一个文件。
然后,我们将选定的日志文件从远程主机复制到控制器机器,并重命名它以附加主机名。这很重要,因为我们将有来自不同主机的多个具有相同名称的日志文件。
4.5。生成报告
最后,我们必须从在不同工作机上执行的模拟收集的所有日志文件生成报告。幸运的是,加特林在这里完成了所有繁重的工作:
mv $GATHER_REPORTS_DIR $GATLING_REPORT_DIR
$GATLING_RUNNER -ro reports
我们将所有日志文件复制到标准的加特林报告目录中,并执行Gating命令生成报告。假设我们在控制器机器上也安装了Gatling。最终报告与我们之前看到的类似:
在这里,我们甚至都没有意识到负载实际上是从多台机器注入的!我们可以清楚地看到,当我们使用三台工作计算机时,请求的数量几乎增加了两倍。但是,在现实生活中,缩放比例并不是完全线性的!
5.扩展性能测试的注意事项
我们已经看到,分布式性能测试是一种扩展性能测试以模拟实际工作负载的方法。现在,尽管分布式性能测试很有用,但确实有其细微差别。因此,我们绝对应该尝试尽可能垂直地扩展负载注入能力。只有在单台机器上达到垂直限制时,才应考虑使用分布式测试。
通常,扩展机器上的负载注入的限制因素来自底层操作系统或网络。我们可以优化某些条件以使其变得更好。在类似Linux的环境中,负载注入程序可以产生的并发用户数通常受打开文件数限制。我们可以考虑使用ulimit
命令增加它。
另一个重要因素涉及机器上可用的资源。例如,负载注入通常会消耗大量网络带宽。如果机器的网络吞吐量是限制因素,我们可以考虑对其进行升级。同样,机器上可用的CPU或内存可能是其他限制因素。在基于云的环境中,切换到功能更强大的计算机相当容易。
最后,我们包含在仿真中的场景应该具有弹性,因为我们不应该始终在负载下假设积极的响应。因此,在写关于回应的断言时,我们应该谨慎和防御。另外,我们应将断言的数量保持在最低限度,以节省增加吞吐量的工作量。
六,结论
在本教程中,我们介绍了使用Gatling执行分布式性能测试的基础知识。我们创建了一个简单的应用程序进行测试,在Gatling中开发了一个简单的模拟,然后了解了如何在多台计算机上执行此操作。
在此过程中,我们还了解了分布式性能测试的需求以及与之相关的最佳实践。
0 评论