gatling 使用_使用Gatling + Gradle + Jenkins Pipeline为您的JAX-RS(和JavaEE)应用程序进行连续压力测试...
gatling 使用
在這篇文章中,我將解釋如何使用Gatling項目為您的JAX-RS Java EE端點編寫壓力測試,以及如何將它們與Gradle和Jenkins 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 ,這是您獲取報告的地方。 請注意,在目錄末尾附加了一個隨機數,這很重要,因為稍后我們會看到。 該報告可能如下所示:
目前,我們已將Gatling與Gradle集成在一起,但是這里缺少一個片段,它在方程式上添加了連續部分。 為了添加連續的壓力測試,我們將使用Jenkins和Jenkins 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的位置。 因此,轉到“ 詹金斯”>“新項目”>“管道”,并為作業命名。
然后,您只需要轉到“ 管道”部分,并配置用于存儲項目的SCM存儲庫。
然后,如果您已經正確配置了來自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 。
最后一步是在shell調用之后在Jenkinsfile下一個調用中添加:
publishHTML(target: [reportDir:'stress-test/build/reports/gatling-results/averageorbitalperiodsimulation', reportFiles: 'index.html', reportName: 'Gatling report', keepAll: true])之后,您可能會在作業頁面中看到一個指向報告的鏈接。
就是如此,多虧了Gradle和Jenkins,您可以輕松地實施持續的壓力測試策略,而只需使用所有開發人員都講的語言代碼即可。
我們不斷學習,
亞歷克斯
翻譯自: https://www.javacodegeeks.com/2016/04/continuous-stress-testing-jax-rs-javaee-applications-gatling-gradle-jenkins-pipeline.html
gatling 使用
總結
以上是生活随笔為你收集整理的gatling 使用_使用Gatling + Gradle + Jenkins Pipeline为您的JAX-RS(和JavaEE)应用程序进行连续压力测试...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 停止新游戏备案什么意思(停止新游戏备案)
- 下一篇: 时间服务器设置(时间服务 linux)