歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux基礎 >> 關於Linux

性能測試工具Gatling介紹

1 介紹

Gatling是一款基於Scala 開發的高性能服務器性能測試工具,它主要用於對服務器進行負載等測試,並分析和測量服務器的各種性能指標。Gatling主要用於測量基於HTTP的服務器,比如Web應用程序,RESTful服務等,除此之外它擁有以下特點:

  • 支持Akka Actors 和 Async IO,從而能達到很高的性能
  • 支持實時生成Html動態輕量報表,從而使報表更易閱讀和進行數據分析
  • 支持DSL腳本,從而使測試腳本更易開發與維護
  • 支持錄制並生成測試腳本,從而可以方便的生成測試腳本
  • 支持導入HAR(Http Archive)並生成測試腳本
  • 支持Maven,Eclipse,IntelliJ等,以便於開發
  • 支持Jenkins,以便於進行持續集成
  • 支持插件,從而可以擴展其功能,比如可以擴展對其他協議的支持
  • 開源免費

    Gatling適用的場景包括:測試需求經常改變,測試腳本需要經常維護;測試環境的客戶機性能不強,但又希望發揮硬件的極限性能;能對測試腳本進行很好的版本管理,並通過CI進行持續的性能測試;希望測試結果輕量易讀等。

    2 與Jmeter對比:

    圖1和圖2分別展現了二者在並發性能方面的表現。

    \

    圖1,JMeter 2.8

    \

    圖2,Gatling 1.3.2

    3 使用、

    3.1 下載:http://gatling.io/#/download,解壓即可使用

    3.2 文件目錄介紹

    \

    • bin目錄下有2個腳本,gatling和recorder, gatling用來運行測試, recorder用來啟動錄制腳本的UI的(不推薦使用),
    • conf目錄是關於Gatling自身的一些配置。
    • lib目錄是Gatling自身依賴的庫文件。
    • results目錄用來存放測試報告的。
    • user-files目錄是用來存放測試腳本的。

      當運行gating腳本的時候,其會掃描user-files目錄下的所有文件,列出其中所有的Simulation(一個測試類,裡面可以包含任意多個測試場景)。選擇其中一個Simulation,然後填寫Simulation ID和運行描述,這個都是為報告描述服務的。

      3.3 錄制-

      3.3.1 啟動錄制:

      • On Linux/Unix:
        $GATLING_HOME/bin/recorder.sh
         
      • On Windows:
        %GATLING_HOME%\bin\recorder.

        3.3.2 界面:

        \

         

        3.3.3 錄制配置

        需要配置Internet的代理才能錄制成功。錄制完成之後代碼保存在user-files/simulations/ 目錄下

        4 運行:

        4.1 運行腳本

        • On Linux/Unix:
          $GATLING_HOME/bin/gatling.sh
           
        • On Windows:
          %GATLING_HOME%\bin\gatling.bat

          4.2 運行的時候會把所有的能運行的場景(simulation)都列出來,選擇想要運行的即可。

           

          5 測試結果

           

          Gatling測試報表基於HTML,並且在測試過程中業已生成,所以打開速度很快。而且,當把鼠標移動到不同數據軸上時,都會有彈出框顯示這個點上詳細的測試數據信息。這種動態顯示數據的方式非常方便查看和分析數據。考慮到項目真實數據的不便,我將通過Gatling官方網站給出的示例報表進行說明。

          Gatling的報表分為兩類:GLOBAL和DETAILS,其中GLOBAL主要是請求相關的統計數據,比如每秒請求數,請求成功與失敗數等;其中DETAILS主要是請求時間相關的統計數據,比如請求響應時間,請求響應延遲時間等。

          \

          圖4 每秒請求數,

          當鼠標放到圖中任何一個點的時候,對應時間點上請求的詳細數據就會以圖中白色的彈出框的方式進行顯示。在下面的請求響應延遲時間圖裡面也有同樣的功能。

          \

          圖5 請求響應延遲時間,

          6 進階

          腳本解析

          package computerdatabase // 1 包名

          import io.gatling.core.Predef._ // 2必須導入的

          import io.gatling.http.Predef._

          import scala.concurrent.duration._

          class BasicSimulation extends Simulation { // 3 類聲明,必須繼承Simulation

          val httpConf = http // 4 所有Http請求普遍配置

          .baseURL("http://computer-database.gatling.io") // 5 base URL

          .acceptHeader("text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8") // 6 請求頭

          .doNotTrackHeader("1")

          .acceptLanguageHeader("en-US,en;q=0.5")

          .acceptEncodingHeader("gzip, deflate")

          .userAgentHeader("Mozilla/5.0 (Windows NT 5.1; rv:31.0) Gecko/20100101 Firefox/31.0")

           

          val scn = scenario("BasicSimulation") // 7 定義場景

          .exec(http("request_1") // 8 http請求名稱 request_1,這個名稱最後會顯示在報告中

          .get("/")) // 9 get請求方法

          .pause(5) // 10 暫停/思考時間 5s

          setUp( // 11 建立場景

          scn.inject(atOnceUsers(1)) // 12 聲明注入一個用戶

          ).protocols(httpConf) // 13 之前聲明的Http請求配置

          }

          6.1 分離場景:分離操作:如浏覽、搜索、編輯操作

          object Search{valsearch=exec(http("Home")// let's give proper names, as they are displayed in the reports

          .get("/")).pause(7).exec(http("Search").get("/computers?f=macbook")).pause(2).exec(http("Select").get("/computers/6")).pause(3)}objectBrowse{valbrowse=???}objectEdit{valedit=???}

          We can now rewrite our scenario using these reusable business processes:

          valscn=scenario("Scenario Name").exec(Search.search,Browse.browse,Edit.edit)

          6.2 設置常規用戶和管理員賬戶

          val users=scenario("Users").exec(Search.search,Browse.browse)

          val admins=scenario("Admins").exec(Search.search,Browse.browse,Edit.edit)

          6.3 設置虛擬用戶

          setUp(users.inject(atOnceUsers(10)).protocols(httpConf))

          6.4 設置上升壓力,即每隔一段時間啟動多少用戶

          setUp(users.inject(rampUsers(10)over(10seconds)),admins.inject(rampUsers(2)over(10seconds))).protocols(httpConf)

          10s 內啟動10個users和2個admin

          6.5 參數化 or 動態數據

          6.5.1 創建文件:在user-files/data文件夾下創建cvs文件,如:search.csv ,內容如下:

          searchCriterion,searchComputerName

          Macbook,MacBook Pro

          eee,ASUS Eee PC 1005PE

          6.5.2 使用文件:

          objectSearch{

          valfeeder=csv("search.csv").random// 1, 2

          valsearch=exec(http("Home").get("/")).pause(1).feed(feeder)// 3

          .exec(http("Search").get("/computers?f=${searchCriterion}")// 4

          .check(css("a:contains('${searchComputerName}')","href").saveAs("computerURL")))// 5

          .pause(1).exec(http("Select").get("${computerURL}"))// 6

          .pause(1)}

          6.5.3 解釋:

          Explanations:

        • First we create a feeder from a csv file with the following columns: searchCriterion, searchComputerName.
        • As the default feeder strategy is queue, we will use the random strategy for this test to avoid feeder starvation.
        • Every time a user reaches the feed step, it picks a random record from the feeder. This user has two new session attributes named searchCriterion, searchComputerName.
        • We use session data through Gatling’s EL to parametrize the search.
        • We use a CSS selector with an EL to capture a part of the HTML response, here a hyperlink, and save it in the user session with the name computerURL. Note how Scala triple quotes are handy: you don’t have to escape double quotes inside the regex with backslashes.
        • We use the previously saved hyperlink to get a specific page.

          6.6 循環調用

          In the browse process we have a lot of repetition when iterating through the pages. We have four times the same request with a different query param value. Can we change this to not violate the DRY principle?

          First we will extract the repeated exec block to a function. Indeed, Simulation‘s are plain Scala classes so we can use all the power of the language if needed:

          objectBrowse{defgotoPage(page:Int)=exec(http("Page "+page).get("/computers?p="+page)).pause(1)valbrowse=exec(gotoPage(0),gotoPage(1),gotoPage(2),gotoPage(3),gotoPage(4))}

          We can now call this function and pass the desired page number. But we still have repetition, it’s time to introduce another builtin structure:

          objectBrowse{valbrowse=repeat(5,"n"){// 1exec(http("Page ${n}").get("/computers?p=${n}"))// 2.pause(1)}}

          Explanations:

        • The repeat builtin is a loop resolved at runtime. It takes the number of repetitions and, optionally, the name of the counter that’s stored in the user’s Session.
        • As we force the counter name we can use it in Gatling EL and access the nth page

          6.7 結果校驗:()

          importjava.util.concurrent.ThreadLocalRandom// 1

          valedit=exec(http("Form").get("/computers/new")).pause(1).exec(http("Post").post("/computers").check(status.is(session=>200+ThreadLocalRandom.current.nextInt(2))))// 2

          Explanations:

          1.
        • We do a check on a condition that’s been customized with a lambda. It will be evaluated every time a user executes the request and randomly return 200 or 201. As response status is 200, the check will fail randomly.

          To handle this random failure we use the tryMax and exitHereIfFailed constructs as follow:

          valtryMaxEdit=tryMax(2){// 1exec(edit)}.exitHereIfFailed// 2

          Explanations:

        • tryMax tries a given block up to n times. Here we try a maximum of two times.
        • If all tries failed, the user exits the whole scenario due to exitHereIfFailed.

          7 其他

          7.1 可以與CI集成

          \

          7.2 實時監控: 支持用戶數和請求數的實時監控

          7.3 服務器監控功能(System under test metrics)。

          參考鏈接:

        • First we import ThreadLocalRandom, to generate random values.
Copyright © Linux教程網 All Rights Reserved