如何利用gatling創建一個性能測試例


【原創博文,轉載請聲明出處】

基於上一篇博文介紹如何源碼編譯創建自己的gatling可執行工具,今天介紹一下如何基於gatling做性能測試!

 

由於gatling的測試例腳本是基於scala寫的,所以,測試的case腳本當然是一個scala文件了。gatling的測試腳本是用scala寫的遵循DSL模型的可讀性和維護性極強的腳本。由於DSL重在聲明做什么,而不像一般的命令式的編程語言寫一堆指令表述怎么做,所以DSL的聲明式編程更加側重在做什么上下功夫,給人一種類似自然語言的程序,但是它比自然語言嚴格,且准確。當然了,這中DSL聲明式編程風格,是基於解釋器來完成這些聲明背后所承載的具體的程序指令代碼,也就是從做什么到怎么做的轉換。最終要生成java的字節碼程序,交給JVM進行執行,完成要做的事情。

 

好了,下面,我就進入主題,簡單的用一個例子介紹gatling的測試腳本的書寫以及測試過程。

直接上測試腳本的代碼:(是測試鏈接baidu主頁以及在通過baidu查詢cnblogs字符的行為,各重復5,每次執行完畢后暫停10秒)

 1 package cnblogsCase
 2 
 3 import io.gatling.core.Predef._
 4 import io.gatling.http.Predef._
 5 import scala.concurrent.duration._
 6 
 7 class RepeatBaiduSimulation extends Simulation{
 8   val httpConf = http.baseURL("https://www.baidu.com")
 9   
10   val homepage = repeat(5){
11     exec(http("Home page").get("/").check(status.is(200)))
12     .pause(10 seconds)
13   }
14   
15   val searchcb = repeat(5){
16     exec(http("Search cnblogs").get("/s").queryParam("wd", "cnblogs").check(status.is(200)))
17     .pause(10 seconds)
18   }
19   
20   val scn = scenario("Search baidu home page").exec(homepage, searchcb)
21   
22   //setUp(scn.inject(rampUsers(10) over (60 seconds)).protocols(httpConf))
23   setUp(scn.inject(atOnceUsers(5)).protocols(httpConf))
24 }

基於gatling的測試腳本,其實就是一個scala的類,在里面描述做什么事情,並且指定具體的流程,也就是gatling定義的scenario。這個腳本,可以在Scala-eclipse IDE里面寫,也可以直接vim文本編寫,我這里是在scala-eclipse里面寫的。在project里面創建了一個cnblogsCase的package。

 

這個腳本要放在gatling工具的指定目錄下(user-files/simulations),便於執行。因為我的case文件有所屬的package,所以,在simulations下面要創建一個目錄cnblogsCase。

[root@CloudGame simulations]# pwd
/root/.ivy2/local/io.gatling.highcharts/gatling-charts-highcharts-bundle/2.2.0-SNAPSHOT/zips/gatling-charts-highcharts-bundle-2.2.0-SNAPSHOT/user-files/simulations
[root@CloudGame simulations]# ll
total 8
drwxr-xr-x 2 root root 4096 Jan 10 10:50 cnblogsCase
drwxr-xr-x 3 root root 4096 Jan 8 16:02 computerdatabase

 

接下來,執行gatling.sh腳本,進行測試:

1 [root@CloudGame gatling-charts-highcharts-bundle-2.2.0-SNAPSHOT]# cd bin/
2 [root@CloudGame bin]# ll
3 total 132
4 -rwxr--r-- 1 root root   2898 Jan  8 16:02 gatling.bat
5 -rwxr--r-- 1 root root   1946 Jan  8 16:02 gatling.sh
6 -rwxr--r-- 1 root root   1992 Jan  8 16:02 recorder.bat
7 -rwxr--r-- 1 root root   1134 Jan  8 16:02 recorder.sh
8 -rw-r--r-- 1 root root 118708 Jan 10 11:24 res.txt
9 [root@CloudGame bin]# ./gatling.sh 

截取部分執行過程中的信息:

 1 。。。。。。。
 2 11:22:21.552 [main] DEBUG io.gatling.compiler.ZincCompiler$ - }
 3 11:22:21.982 [main] DEBUG io.gatling.compiler.ZincCompiler$ -
 4 Initial source changes:
 5         removed:Set()
 6         added: Set()
 7         modified: Set()
 8 Invalidated products: Set()
 9 External API changes: API Changes: Set()
10 Modified binary dependencies: Set()
11 Initial directly invalidated sources: Set()
12 
13 Sources indirectly invalidated by:
14         product: Set()
15         binary dep: Set()
16         external source: Set()
17 11:22:21.983 [main] DEBUG io.gatling.compiler.ZincCompiler$ - All initially invalidated sources: Set()
18 
19 11:22:21.993 [main] DEBUG io.gatling.compiler.ZincCompiler$ - Compilation successful
20 Choose a simulation number:
21      [0] cnblogsCase.RepeatBaiduSimulation 22      [1] computerdatabase.BasicSimulation
23      [2] computerdatabase.advanced.AdvancedSimulationStep01
24      [3] computerdatabase.advanced.AdvancedSimulationStep02
25      [4] computerdatabase.advanced.AdvancedSimulationStep03
26      [5] computerdatabase.advanced.AdvancedSimulationStep04
27      [6] computerdatabase.advanced.AdvancedSimulationStep05
28 Select simulation id (default is 'repeatbaidusimulation'). Accepted characters are a-z, A-Z, 0-9, - and _
29 Select run description (optional)
30 11:23:00.883 [GatlingSystem-akka.actor.default-dispatcher-4] INFO  i.g.c.stats.writer.ConsoleDataWriter - Initializing
31 11:23:00.887 [GatlingSystem-akka.actor.default-dispatcher-3] INFO  i.g.c.stats.writer.LogFileDataWriter - Initializing
32 11:23:00.897 [GatlingSystem-akka.actor.default-dispatcher-4] INFO  i.g.c.stats.writer.ConsoleDataWriter - Initialized
33 11:23:00.905 [GatlingSystem-akka.actor.default-dispatcher-3] INFO  i.g.c.stats.writer.LogFileDataWriter - Initialized
34 11:23:00.937 [main] DEBUG i.n.u.i.l.InternalLoggerFactory - Using SLF4J as the default logging framework
35 。。。。。。

最終執行完畢后,你會看到如下的結果日志:

 1 Parsing log file(s) done
 2 Generating reports...
 3 
 4 ================================================================================
 5 ---- Global Information --------------------------------------------------------
 6 > request count                                         20 (OK=20 KO=0 )  7 > min response time                                      8 (OK=8      KO=-     )
 8 > max response time                                    454 (OK=454    KO=-     )
 9 > mean response time                                   123 (OK=123    KO=-     )
10 > std deviation                                        146 (OK=146    KO=-     )
11 > response time 50th percentile                         85 (OK=85     KO=-     )
12 > response time 75th percentile                        147 (OK=147    KO=-     )
13 > mean requests/sec                                  0.198 (OK=0.198  KO=-     )
14 ---- Response Time Distribution ------------------------------------------------
15 > t < 800 ms                                            20 (100%)
16 > 800 ms < t < 1200 ms                                   0 (  0%)
17 > t > 1200 ms                                            0 (  0%)
18 > failed                                                 0 (  0%)
19 ================================================================================
20 
21 Reports generated in 0s.
22 Please open the following file: /root/.ivy2/local/io.gatling.highcharts/gatling-charts-highcharts-bundle/2.2.0-SNAPSHOT/zips/gatling-charts-highcharts-bundle-2.2.0-SNAPSHOT/results/repeatbaidusimulation-1452396180846/index.html

在這個測試過程中,你會看到HTTPrequest和HTTP response的message,例如在做search cnblogs的時候,就有下面的這種信息可以看到:

 1 Request DefaultFullHttpRequest(decodeResult: success, version: HTTP/1.1, content: UnpooledHeapByteBuf(freed))
 2 GET /s?wd=cnblogs HTTP/1.1
 3 Referer: https://www.baidu.com/
 4 Cookie: BIDUPSID=FDE533EC959AF63BFE9EFBDFF9822C3E; BAIDUID=FDE533EC959AF63BFE9EFBDFF9822C3E:FG=1; PSTM=1452396098; __bsi=14078739286212139513_00_0_I_R_82_0303_C02F_N_I_I_0; BD_NOT_HTTPS=1; BDSVRTM=0
 5 Connection: keep-alive
 6 Host: www.baidu.com
 7 Accept: */*
 8 
 9 Response DefaultHttpResponse(decodeResult: success, version: HTTP/1.1)
10 HTTP/1.1 200 OK 11 Server: bfe/1.0.8.13
12 Date: Sun, 10 Jan 2016 03:22:29 GMT
13 Content-Type: text/html
14 Content-Length: 227
15 Connection: keep-alive
16 Last-Modified: Thu, 09 Oct 2014 10:47:57 GMT
17 X-UA-Compatible: IE=Edge,chrome=1
18 Set-Cookie: BD_NOT_HTTPS=1; path=/; Max-Age=300
19 Set-Cookie: BDSVRTM=3; path=/
20 Pragma: no-cache
21 Cache-control: no-cache
22 BDPAGETYPE: 3
23 BDQID: 0xae1b13fb000760db
24 Accept-Ranges: bytes
25 Set-Cookie: __bsi=14180245014310892240_00_0_I_R_90_0303_C02F_N_I_I_0; expires=Sun, 10-Jan-16 03:22:34 GMT; domain=www.baidu.com; path=/

上面的請求和應答中,可以清楚的看到測試的內容和結果。在Http Request的請求行中,可以看到URI的內容,在Http Response的響應行中,可以看到狀態信息,都是符合預期的。

這里,羅嗦一下,如何知道腳本中執行search的時候,search的key填寫什么?也就是如何構建Http Request的請求行中的URI?其實,這個是要依據自己要測試的目標的網頁具體內容的,比如這里要在baidu的主頁搜索欄里面查找cnblogs,就要知道URI中的key,再將其的value填寫為cnblogs就可以了。這個可以debug模式查看baidu主頁的html,還可以很清楚的知道執行指令是用get還是post。

上圖中,紅色框中,form中沒有指定method,則用GET指令(通常如此),在對應的input標簽里面的name屬性,其值為wd,這個就是要用來構建腳本中的queryParam的key的。是不是比較簡單呢?我覺得不是難事!

 

配置和寫腳本都不是什么難事情,現在就要分析一下,腳本測試執行的過程是不是我沒預期想要的。主要看看,分析一下執行的次數。我腳本中,設置了5個用戶,scenario包含2部分,一個打開主頁,一個查詢cnblogs字符串,都是執行5次,這么算下來,request一共應該是多少此呢?算算就知道了: 5*(5 + 5) = 50,而結果是不是這樣子呢????

請回去查看結果日志,其中的紅色部分,就是最終的執行次數,只有20次,說明不服和預期!對於這個結果,我分析了下,沒有弄明白,開始以為自己的腳本寫的有問題,后來下載了官網版本2.1.7,執行上面的腳本,得到如下的結果:

 1 Simulation finished
 2 Parsing log file(s)...
 3 Parsing log file(s) done
 4 Generating reports...
 5 
 6 ================================================================================
 7 ---- Global Information --------------------------------------------------------
 8 > request count                                         50 (OK=50     KO=0     )
 9 > min response time                                      7 (OK=7      KO=-     )
10 > max response time                                    177 (OK=177    KO=-     )
11 > mean response time                                    63 (OK=63     KO=-     )
12 > std deviation                                         45 (OK=45     KO=-     )
13 > response time 50th percentile                         74 (OK=74     KO=-     )
14 > response time 75th percentile                         91 (OK=91     KO=-     )
15 > mean requests/sec                                  0.494 (OK=0.494  KO=-     )
16 ---- Response Time Distribution ------------------------------------------------
17 > t < 800 ms                                            50 (100%)
18 > 800 ms < t < 1200 ms                                   0 (  0%)
19 > t > 1200 ms                                            0 (  0%)
20 > failed                                                 0 (  0%)
21 ================================================================================
22 
23 Reports generated in 0s.
24 Please open the following file: /mnt/workwps/gatling-charts-highcharts-bundle-2.1.7/results/repeatbaidusimulation-1452401293142/index.html

這個是符合預期的.

為了驗證自己的2.2.0-SNAPSHOT從源碼編譯的結果是不是有問題,自己特意從官網的snapshot中下載了官方的可執行bundle文件.最終執行的結果和我自己編譯出來的gatling運行得到的結果一樣,這個應該不是我的編譯出了問題!

至於2.2.0-SNAPSHOT版本的結果為何不對,目前還沒有找到原因,是什么地方出問題了,不會是2.2.0-SNAPSHOT目前還在開發中,存在某些問題吧???有待繼續調查!!!還是先不要用最新版本了,繼續用2.1.7吧!

 

最后上傳幾張截圖(基於2.1.7得到的)展示結果:

 

 

 

這個gatling工具,其實還是非常不錯的,使用相對比較簡單,結果展示也非常友好!相比nGrinder的純的web UI下的操作,對於初學者可能有比較大的難度,但是,熟悉scala和DSL后,會發現gatling具有很多優勢,比如腳本書寫非常的靈活,聲明式的scenaro的會讓其他用戶讀你寫的case毫不費勁!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM