使用Gatling + Gradle + Jenkins Pipeline为您的JAX-RS(和JavaEE)应用程序进行连续压力测试...

在这篇文章中,我将解释如何使用Gatling项目为您的JAX-RS Java EE端点编写压力测试,以及如何将它们与GradleJenkins Pipeline集成,因此,除了进行简单的压力测试外,您还可以使用以下方法: 连续的压力测试,其中每个提交都可能自动触发此类测试,并提供自动断言和每个执行的更重要的图形反馈,因此您可以监视应用程序中性能的变化。

首先要开发的是JAX-RS JavaEE服务:

@Path("/planet")
@Singleton
@Lock(LockType.READ)
public class PlanetResources {@InjectSwapiGateway swapiGateway;@InjectPlanetService planetService;@Inject@AverageFormatterDecimalFormat averageFormatter;@GET@Path("/orbital/average")@Produces(MediaType.TEXT_PLAIN)@Asynchronouspublic void calculateAverageOfOrbitalPeriod(@Suspended final AsyncResponse response) {// Timeout controlresponse.setTimeoutHandler(asyncResponse -> asyncResponse.resume(Response.status(Response.Status.SERVICE_UNAVAILABLE).entity("TIME OUT !").build()));response.setTimeout(30, TimeUnit.SECONDS);try {// SwapiGateway is an interface to swapi.co (Star Wars API)JsonObject planets = swapiGateway.getAllPlanets();final JsonArray results = planets.getJsonArray("results");// Make some calculations with the result retrieved from swapi.codouble average = planetService.calculateAverageOfOrbitalPeriod(results);final Response averageResponse = Response.ok(averageFormatter.format(average)).build();response.resume(averageResponse);} catch(Throwable e) {response.resume(e);}}
}

没什么特别的,这是一个异步的JAX-RS端点,它连接到swapi.co网站,检索“星球大战”行星的所有信息,计算出轨道周期的平均值,最后以文本形式返回。 为了简单起见,我不会向您展示所有其他类,但是它们非常简单,在文章结尾,我将为您提供github存储库。

该应用程序打包在war文件中,并部署到应用程序服务器中。 在这种情况下,将部署到官方Apache TomEE Docker映像内部署的Apache TomEE 7 。

下一步是使用Gatling依赖项配置Gradle构建脚本。 由于Gatling是用Scala编写的,因此您需要使用Scala插件。

apply plugin: 'java'
apply plugin: 'scala'def gatlingVersion = "2.1.7"dependencies {compile "org.scala-lang:scala-library:2.11.7"testCompile "io.gatling:gatling-app:${gatlingVersion}"testCompile "io.gatling.highcharts:gatling-charts-highcharts:${gatlingVersion}"
}

之后,是时候编写我们的第一个压力测试了。 重要的是要注意,为加特林编写压力测试正在使用提供的DSL编写Scala类。 即使对于从未看过Scala的人来说,如何使用它也非常直观。

因此,创建一个名为src / test / scala的目录,并创建一个具有下一个内容的名为AverageOrbitalPeriodSimulation.scala的新类:

package org.starwarsimport io.gatling.core.Predef._
import io.gatling.http.Predef._
import scala.concurrent.duration._
import scala.util.Properties// Extends from Simulation
class AverageOrbitalPeriodSimulation extends Simulation {// Gets the base URL where our service is running from environment/system propertyval LOCATION_PROPERTY = "starwars_planets_url";val location = Properties.envOrElse(LOCATION_PROPERTY, Properties.propOrElse(LOCATION_PROPERTY, "http://localhost:8080/"))// configures the base URLval conf = http.baseURL(location)// defines the scenario to run, which in this case is a GET to endpoint defined in JAX-RS serviceval scn = scenario("calculate average orbital period").exec(http("get average orbital period").get("rest/planet/orbital/average")).pause(1)// instead of simulating 10 users at once, it adds gradullay the 10 users during 3 seconds// asserts that there is no failing requests and that at max each request takes less than 3 secondssetUp(scn.inject(rampUsers(10).over(3 seconds))).protocols(conf).assertions(global.successfulRequests.percent.is(100), global.responseTime.max.lessThan(3000))
}

每个模拟都必须扩展模拟对象。 此模拟从starwars_planets_url环境或系统属性中获取服务的基本URL,创建指向JAX-RS中定义的端点的方案,最后在3秒钟内它将逐步添加用户,直到同时运行10个用户。 仅在所有请求在3秒内成功通过后,测试才能通过。

现在我们需要运行此测试。 您会注意到这不是JUnit测试,因此您无法执行Run As JUnit测试。 您需要做的是使用Gatling提供的可运行类,该类要求您将模拟类作为参数传递。 使用Gradle确实很容易做到。

task runLoadTest(type: JavaExec) {// before runnign the task we need to compile the testsdependsOn testClassesdescription = 'Stress Test Calculating Orbital Period'classpath = sourceSets.main.runtimeClasspath + sourceSets.test.runtimeClasspath// if starwars_planets_url is not provided we add the DOCKER_HOST one automaticallydef starwarsUrl;if (!System.env.containsKey('starwars_planets_url') && !System.properties.containsKey('starwars_planets_url')) {if (System.env.containsKey('DOCKER_HOST')) {starwarsUrl = System.env.DOCKER_HOST.replace("tcp", "http").replace("2376", "9090") + "/starwars/"} else {starwarsUrl = "http://localhost:8080/starwars/"}}jvmArgs = [ "-Dgatling.core.directory.binaries=${sourceSets.test.output.classesDir.toString()}" ]// Means that the url has been calculated here and we set itif (starwarsUrl != null) {environment["starwars_planets_url"] = starwarsUrl}// Gatling applicationmain = "io.gatling.app.Gatling"// Specify the simulation to run and outputargs = ["--simulation", "org.starwars.AverageOrbitalPeriodSimulation","--results-folder", "${buildDir}/reports/gatling-results","--binaries-folder", sourceSets.test.output.classesDir.toString(),"--output-name", "averageorbitalperiodsimulation","--bodies-folder", sourceSets.test.resources.srcDirs.toList().first().toString() + "/gatling/bodies",]
}// when running test task we want to execute the Gatling test
test.dependsOn runLoadTest

我们正在定义JavaExec类型的Gradle任务,因为我们想要的是运行一个可运行的类。 然后,通过自动检测到是否未设置starwars_planets_url,我们将该测试运行到已安装Docker的计算机上,因此可能使开发人员的工作变得更加轻松。

最后,如果需要,我们将覆盖环境变量,我们为可运行类设置必需的属性,并配置Gradle在每次执行测试任务(./gradlew test)时执行此任务。

如果运行它,您可能会看到来自Gatling的一些输出消息,以及所有类似以下的消息:请打开以下文件: /Users/…./stress-test/build/reports/gatlingresults / averageorbitalperiodsimulation-1459413095563 / index。 html ,这是您获取报告的地方。 请注意,在目录末尾附加了一个随机数,这很重要,因为稍后我们将要看到。 该报告可能如下所示:

屏幕截图2016年3月31日在15.36.15

目前,我们已将GatlingGradle集成在一起,但是这里缺少一个片段,它在方程式上添加了连续部分。 为了添加连续的压力测试,我们将使用JenkinsJenkins Pipeline作为CI服务器,因此对于每个提交都执行压力测试   其他任务,例如编译,运行单元,集成测试或代码质量门。

过去, Jenkins作业是使用Web UI配置的,要求用户手动创建作业,填写作业的详细信息并通过Web浏览器创建管道。 同样,这也使得将作业的配置与正在构建的实际代码分开。

随着Jenkins Pipeline插件的引入。 该插件是Groovy DSL,可让您在文件中实施整个构建过程,并将其与代码一起存储。 Jenkins 2.0默认带有此插件,但是如果您使用的是Jenkins 1.X,则可以将其安装为其他任何插件( https://wiki.jenkins-ci.org/display/JENKINS/Pipeline+Plugin )

因此,现在我们可以开始对发布插件进行编码了,但是出于本文的目的,仅涉及压力部分。 您需要在项目的根目录上创建一个名为Jenkinsfile的文件(名称不是强制性的,但实际上是名称),在本例中为下一个内容:

stage 'Compile And Unit Test'stage 'Code Quality'stage 'Integration Test'stage 'Acceptance Test'// defines an stage for info purposes
stage 'Stress Test'def dockerHost = '...'
//defines a node to run the stage
node {// get source code from location where Jenkinsfile (this) is located.// you could use stash/unstash to get sources from previous stages instead of getting from SCMcheckout scm// defines the environment variable for stress testwithEnv(["starwars_planets_url=http://${dockerHost}:9090/starwars/"]) {// executes shell scriptsh './gradlew test'}}

在这种情况下,我们定义了一个新阶段,称为压力测试。 阶段步骤仅用作参考,将用于记录目的。 接下来定义一个节点。 节点是执行代码的Jenkins执行程序。 在此节点内,从放置Jenkinsfile的相同位置检出源代码,设置一个新的环境变量,该变量指向应用程序的部署位置,最后是执行Gradle测试任务的shell步骤。

Jenkins的最后一步是创建类型为Pipeline的新作业并设置Jenkinsfile的位置。 因此,转到“ 詹金斯”>“新项目”>“管道”,并为作业命名。

屏幕截图2016年3月31日在11.55.28

然后,您只需要转到“ 管道”部分,并配置用于存储项目的SCM存储库。

屏幕截图2016年3月31日在11.56.30

然后,如果您已经正确配置了Jenkins和您的SCM服务器的挂钩,那么将在每次提交时执行此作业,因此您的压力测试将连续运行。

当然,您可能已经注意到压力测试已执行,但Jenkins没有发布任何报告,因此您无法查看或比较不同执行的结果。 因此,您可以使用publishHtml插件将生成的报告存储在Jenkins中 。 如果尚未安装该插件,则需要与其他任何Jenkins插件一样安装。

PublishHtml插件使我们可以将构建工具生成的一些html文件发布到Jenkins,以便用户可以使用,也可以按内部版本号进行分类。 您需要配置要发布的文件目录的位置,在这里我们找到第一个问题,您还记得盖特林生成带有随机数的目录吗? 因此,我们需要首先解决此问题。 您可以采用不同的策略,但是最简单的方法是在测试后将目录重命名为已知的静态名称。

打开Gradle构建文件并添加下一个内容。

task(renameGatlingDirectory) << {// find the directorydef report = {file -> file.isDirectory() && file.getName().startsWith('averageorbitalperiodsimulation')}def reportDirectory = new File("${buildDir}/reports/gatling-results").listFiles().toList().findAll(report).sort().last()// rename to a known directory// should always work because in CI it comes from a clean executionreportDirectory.renameTo("${buildDir}/reports/gatling-results/averageorbitalperiodsimulation")
}// it is run after test phase
test.finalizedBy renameGatlingDirectory

我们正在创建一个在测试任务结束时执行的新任务,该任务将最后创建的目录重命名为averageorbitalperiodsimulation

最后一步是在Jenkinsfile中的shell调用之后的下一个调用中添加:

publishHTML(target: [reportDir:'stress-test/build/reports/gatling-results/averageorbitalperiodsimulation', reportFiles: 'index.html', reportName: 'Gatling report', keepAll: true])

之后,您可能会在作业页面中看到一个指向报告的链接。

屏幕截图2016年3月31日在15.22.30

就是如此,多亏了GradleJenkins,您可以轻松地实施持续的压力测试策略,而只需使用所有开发人员都讲的语言代码即可。

我们不断学习,

亚历克斯

翻译自: https://www.javacodegeeks.com/2016/04/continuous-stress-testing-jax-rs-javaee-applications-gatling-gradle-jenkins-pipeline.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/354570.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用 VuePress 搭建一个自己的知识文档

最近准备对前端知识做一个梳理&#xff0c;将自己的平时遇到的问题和解决方案形成一个知识文档。本文记录了搭建 VuePress 的主要过程&#xff0c;同时也提供了部分自定义的配置&#xff0c;示例地址&#xff1a;http://doc.i-fanr.com 环境搭建 VuePress 有着比较完善的中文文…

代码重构学习

文章&#xff1a;浅谈重构中踩过的坑 文章中有一个很好的&#xff0c;优化if else多分支判断的例子&#xff0c;将方法抽象出来&#xff0c;根据不同场景实现抽象类&#xff0c;然后用写一个工厂类&#xff0c;一个工厂方法&#xff0c;通过传入类型&#xff0c;进行实例化。 很…

pta 朋友圈

某学校有N个学生&#xff0c;形成M个俱乐部。每个俱乐部里的学生有着一定相似的兴趣爱好&#xff0c;形成一个朋友圈。一个学生可以同时属于若干个不同的俱乐部。根据“我的朋友的朋友也是我的朋友”这个推论可以得出&#xff0c;如果A和B是朋友&#xff0c;且B和C是朋友&#…

金三银四跳槽面试季,我整理前端知识做了个网站

每年的金三银四&#xff0c;都将迎来求职面试的一个高峰期&#xff0c;为什么会有那么多的求职需求&#xff1f;多是因为以下几个来源&#xff1a;已拿 offer 等年终奖的&#xff1a;年前已经找到机会&#xff0c;领了年终奖辞职要到新公司报到的临时起意要辞及裸辞的&#xff…

web框架和后台开发_Web开发框架–第1部分:选项和标准

web框架和后台开发在我的公司&#xff0c;我们正在评估未来几年将使用哪种Web开发框架。 自上次评估以来&#xff0c;我们一直在使用由Struts 2驱动的Java应用服务器作为MVC&#xff0c;将Tiles作为模板引擎&#xff0c;将jQuery用于Javascript awesomennes&#xff0c;将DWR用…

hadoop的Map阶段的四大步骤

深入理解map的几个阶段是怎样执行的。转载于:https://www.cnblogs.com/xubiao/p/7846080.html

小程序 Typescript 最佳实践

小程序结合TypeScript开发&#xff0c;如果用第三方框架&#xff0c;首选Taro已完美支持。但是如果你选择原生开发&#xff0c;那么下面的这份实践可能会帮到你。小程序 Typescript 最佳实践使用 gulp 构建&#xff08;支持 typescript 和 less/sass/scss&#xff09;使用 type…

DIY注释

从Java 5开始&#xff0c;Java中出现了注释。 我想做一个自己的注释&#xff0c;只是为了看看需要什么。 但是&#xff0c;我发现它们只是接口。 有擦 接口后面没有牙。 必须执行一些代码。 我认为这是橡胶行之有效的方法&#xff0c;我真的找到了解决方法。 首先&#xff0c…

这款电脑升降桌美到我了

一直在寻觅一款集颜值与功能于一体的电脑升降桌&#xff0c;这款乐歌 E5 电动桌终于成功地满足了我的需求。有黑白两款颜色可选&#xff0c;但其中白色钢化玻璃版常适合用来作为白色系桌面的基础——四周圆角设计&#xff0c;再加上碳素钢的桌体框架&#xff0c;整体非常有质感…

spring boot集成mybatis+事务控制

一下代码为DEMO演示&#xff0c;采用注解的方式完成Spring boot和Mybatis的集成&#xff0c;并进行事物的控制 数据源的配置: 1 spring.datasource.urljdbc:mysql://localhost:3306/book 2 spring.datasource.usernameroot 3 spring.datasource.password 4 spring.datasource.d…

分享一个引起极度舒适的工作桌面

干净整洁的桌面或许不能带给你工作效率的提升&#xff0c;但一定会给你带来愉悦的心情。长期码字一定需要一个升降桌&#xff0c;可自由地调节高度&#xff0c;以保证舒适的坐姿和灵活的视角。另外坐久了&#xff0c;累了还能站立工作一会儿。有了外显之后&#xff0c;如果不需…

canvas绘制多边形

<!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>canvas绘制多边形</title> </head> <body> <canvas id"canvas" style"border: 1px solid darkcyan;" width…

ehcache rmi_EhCache复制:RMI与JGroups

ehcache rmi最近&#xff0c;我正在研究一种需要复制缓存的产品。 缓存提供程序已经确定-EhCache&#xff0c;剩下的就是有关传输的问题。 哪一个是最佳选择&#xff1f; 这里的最佳选择是指性能更好的选择。 仅在两个可用传输之间进行了性能评估-JGroups和RMI&#xff0c;对其…

Element Table 可以实现哪些常见的有用的功能

最近项目中频繁使用 table 功能&#xff0c;因为 UI 框架使用的又是 Element UI&#xff0c;于是总结下在 Element 下 el-table 组件使用技巧。1.行背景色table 组件提供了 row-style 属性&#xff0c;说明&#xff1a;行的 style 的回调方法&#xff0c;也可以使用一个固定的 …

从0开始 Java实习 黑白棋

黑白棋的设计 代码如下&#xff1a; import java.util.*; public class Chess{char[][] chess new char[16][16];public static void main(String args[]){ Scanner in new Scanner(System.in);Chess ch new Chess();ch.init(); ch.output();int tag 0;int nn 0;wh…

如果在这样的环境中写代码,会不会很高效

桌面环境分享系列又来了。我会把平时看到的好的桌面布置分享给大家&#xff0c;帮助大家在桌面整理和打造方面提供一些新的想法和创意。如何评价一个开发桌面的好坏&#xff0c;首先一定要清爽整洁&#xff0c;该有的家伙事儿一定要有。不是要看上去要有多高大上&#xff0c;重…

为什么选择SpringBoot?

使用Spring MSpring进行许可是一种非常流行的基于Java的框架&#xff0c;用于构建Web和企业应用程序。 与许多其他只关注一个领域的框架不同&#xff0c;Spring框架通过其投资组合项目提供了广泛的功能来满足现代业务需求。 Spring框架提供了以多种方式&#xff08;例如XML &a…

wamp2.5可用php5.6,局域网访问,多站点配置

1.用php5.6 直接下载个wamp3.0的&#xff0c;那里的php支持5.6&#xff0c;安装之后把php5.6的文件夹剪切到wamp2.5的放php的文件夹&#xff0c;然后wamp那里就有php5.6的选择了&#xff0c;选择后就可以用了 2.局域网访问 打开apache的配置文件&#xff0c;然后搜索Require lo…

Vue 页面如何监听用户预览时间

最近的业务中涉及到这样一个需求&#xff0c;在线培训的系统需要知道用户对某个在线预览的页面追踪用户的预览时长。初步我们首先想到借助 Vue 页面的生命周期函数 mounted 和 destroyed&#xff0c;分别在其中加入开始计时和清除计时的逻辑&#xff0c;通过后台的接口上报对应…

一个追求高效的学习者手机里装有哪些APP?(转)

转载&#xff1a;http://www.jianshu.com/p/f568c8d8b6bb 1、录音软件-Recordium 参加活动&#xff0c;如果不想错过活动现场的经常片段&#xff0c;速记又来不及&#xff0c;那就选择录音吧。小六之前都使用录音笔&#xff0c;但是自从有了这个APP之后&#xff0c;在开会&…