qileilove

          blog已經(jīng)轉(zhuǎn)移至github,大家請訪問 http://qaseven.github.io/

          新一代服務(wù)器性能測試工具Gatling

          21世紀(jì)是云的世紀(jì), 大規(guī)模云網(wǎng)已經(jīng)出現(xiàn)了,而且在未來幾年內(nèi)會得到高速發(fā)展,從而使得基于云的系統(tǒng)也會越來越多。如果要開發(fā)一款高性能的云系統(tǒng),服務(wù)器性能測試是一個必不可少的環(huán)節(jié)。今天,就來介紹一款新一代服務(wù)器性能測試工具Gatling。
            一,什么是Gatling
            Gatling是一款基于Scala 開發(fā)的高性能服務(wù)器性能測試工具,它主要用于對服務(wù)器進(jìn)行負(fù)載等測試,并分析和測量服務(wù)器的各種性能指標(biāo)。Gatling主要用于測量基于HTTP的服務(wù)器,比如Web應(yīng)用程序,RESTful服務(wù)等,除此之外它擁有以下特點:
            支持Akka Actors 和 Async IO,從而能達(dá)到很高的性能
            支持實時生成Html動態(tài)輕量報表,從而使報表更易閱讀和進(jìn)行數(shù)據(jù)分析
            支持DSL腳本,從而使測試腳本更易開發(fā)與維護(hù)
            支持錄制并生成測試腳本,從而可以方便的生成測試腳本
            支持導(dǎo)入HAR(Http Archive)并生成測試腳本
            支持Maven,Eclipse,IntelliJ等,以便于開發(fā)
            支持Jenkins,以便于進(jìn)行持續(xù)集成
            支持插件,從而可以擴展其功能,比如可以擴展對其他協(xié)議的支持
            開源免費
            Gatling適用的場景包括:測試需求經(jīng)常改變,測試腳本需要經(jīng)常維護(hù);測試環(huán)境的客戶機性能不強,但又希望發(fā)揮硬件的極限性能;能對測試腳本進(jìn)行很好的版本管理,并通過CI進(jìn)行持續(xù)的性能測試;希望測試結(jié)果輕量易讀等。
            相關(guān)廠商內(nèi)容
            QCon上海技術(shù)訓(xùn)練營:OSGi、GitHub、Scrum深度培訓(xùn),10月29-31日與您相約,了解詳情! 2013年10月26日QClub大連站:大連軟件開發(fā)者大會 QCon上海2013“團(tuán)隊文化”專題:構(gòu)建持續(xù)前進(jìn)的團(tuán)隊文化、價值觀,工具與體系 GitHub中國上海Drinkup活動,就在QCon上海2013前夜,貝尼酒吧 QCon上海2013“游戲服務(wù)器實踐”專題:游戲服務(wù)器運維經(jīng)驗、架構(gòu)分享、性能策略
            二,Gatling與JMeter
            JMeter是目前使用最為廣泛的服務(wù)器性能測試工具之一,它最大的特點就是擁有一套簡單易用的GUI,但它最大的缺點也是由于簡單易用導(dǎo)致它某些方面的不足,比如測試腳本(XML)不容易維護(hù)等。Gatling正是針對JMeter的劣勢做了大量改進(jìn),因此相較于 JMeter,Gatling擁有以下優(yōu)勢:
            在并發(fā)性能方面,Gatling使用了Akka Actors和Async IO, 而JMeter則采用了一個用戶使用一個線程的方式 ,一旦并發(fā)線程過多,性能就急速下降,很難充分發(fā)揮硬件的能力。雖然兩個工具都是基于JVM的,但是Actors模型的性能在高并發(fā)的情況下性能大大優(yōu)于Threads,從而使得Gatling在更少的內(nèi)存和CPU的情況下可以提供同樣的測試能力,降低了測試成本。圖1和圖2分別展現(xiàn)了二者在并發(fā)性能方面的表現(xiàn)。
            圖1,JMeter 2.8
            圖2,Gatling 1.3.2
            圖片,測試環(huán)境和測試腳本參見:https://github.com/excilys/gatling/wiki/Benchmarks
            其中圖1和圖2分別是JMeter和Gatling在300個用戶并發(fā)下的測試結(jié)果。可以很明顯的看出,JMeter的并發(fā)量在300上下波動,最高達(dá)到400,最低達(dá)到200,而Gatling幾乎穩(wěn)定在300。由此可見Gatling性能的穩(wěn)定性。
            在測試腳本方面,Gatling是Scala代碼,而JMeter主要是XML代碼。Gatling基于一套開源的Gatling DSL API,所以它的功能很容易擴展,也不需要使用者精通Scala語言。DSL的使用也更容易編寫出簡明,易讀性和維護(hù)性高的代碼,而且還可以使用版本工具進(jìn)行更有效的管理。因為性能測試應(yīng)該屬于系統(tǒng)發(fā)布流程中必不可少的一個步驟,所以測試腳本應(yīng)該和系統(tǒng)代碼一樣使用版本工具進(jìn)行統(tǒng)一管理。
            在報表系統(tǒng)上,Gatling提供了一套輕量并且十分友好的Html報表系統(tǒng),使得用戶可以更為快速而方便地查看和分析數(shù)據(jù),相反,JMeter的報表系統(tǒng)卻十分笨重,且使用也不方便。

            三,如何在項目中使用Gatling
            對于Gatling這樣一個全新的服務(wù)器性能測試工具,是否能將它很好的運用到項目中并發(fā)揮其優(yōu)勢,這個是一個困擾測試決策者的問題。下面我將結(jié)合在一個真實項目中使用和部署Gatling的經(jīng)驗來解答這個問題。
            搭建測試環(huán)境
            在一個大型的Web項目中,測試環(huán)境的搭建是項目測試工作開始的第一步,也是最為關(guān)鍵的一步,因為測試環(huán)境直接影響到測試成本和測試結(jié)果。由于這個項目對于性能的要求并不是很高,我們經(jīng)過討論和分析,決定選取虛擬機作為測試平臺。這就意味著被測系統(tǒng)以及測試客戶端可以使用的硬件資源比如CPU和內(nèi)存十分有限,因此需要測試工具能充分使用有限的資源發(fā)揮最大的性能。
            進(jìn)行負(fù)載測試
            為了快速實現(xiàn)測試腳本,我首先選擇了使用Gatling錄制功能進(jìn)行腳本錄制,成功錄制以后會在指定的“Output folder”目錄下面生成你指定“Class Name”為名字的腳本,見圖3。
            
          圖3,Gatling Recorder
            根據(jù)圖3的配置,錄制好的腳本存放在/Users/twer/work/gatling/user-files/simulations/Common/MyRecordedSimulation.scala。生成的部分腳本代碼如下:
          class MyRecordedSimulation extends Simulation {
          val httpProtocol = http
          .baseURL("http:// :10.17.7.3")
          .acceptHeader("image/png,image/*;q=0.8,*/*;q=0.5")
          .acceptEncodingHeader("gzip, deflate")
          .acceptLanguageHeader("en-US,en;q=0.5")
          .connection("keep-alive")
          .userAgentHeader("Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:22.0)
          Gecko/20100101 Firefox/22.0")
          val headers_1 = Map(
          """Accept""" -> """text/html,application/xhtml+xml,application/xml;q=0.9,
          */*;q=0.8""",
          """If-None-Match""" -> """"a3ef335152d5532e2297bd8ad288f3f9"""")
          錄制代碼段1
          .exec(http("request_21")
          .get("""/customer/images/new?app_dialog=true&dialog=true""")
          .headers(headers_18))
          .pause(6)
          .exec(http("request_22")
          .get("""/customer/images?_=1374400463122""")
          .headers(headers_19))
          .pause(165 milliseconds)
          .exec(http("request_23")
          .get("""/Users/twer/work/gatling/user-files/simulations/testdata/test1.
          png""")
          .headers(headers_20)
          .check(status.is(500)))
          .pause(2)
          .exec(http("request_24")
          .get("""/customer/images?view=list"""))
          .pause(86 milliseconds)
          ……
          setUp(scn.inject(atOnce(1 user))).protocols(httpProtocol)
           錄制代碼段2
            錄制出來的腳本擁有很多局限性:
            只支持1個用戶
            沒有檢測點
            沒有邏輯分層
            因此,它并不能用于真正的性能測試。對于這樣的原始代碼,我們需要進(jìn)行大量的重構(gòu),使代碼擁有很好的可讀性和可維護(hù)性。
            首先我們要進(jìn)行分層處理:
            對于錄制代碼段1,需要建立一個Header類來管理所有HTTP Header,這里使用“Headers.scala”,在錄制代碼段1中只給出了“headers_1”,實際的腳本包含了大量的Header。
            對于錄制代碼段2,需要將測試場景和測試控制分開,每一個測試場景使用一個文件來保存,代碼段2所示的場景使用“UploadImageScenario.scala”來保存。主控腳本也需要分離出來存入“MainSimulation.scala”,通過調(diào)用不同的測試場景的腳本,從而可以復(fù)用HTTP的配置選項,比如:
            val httpProtocol = http
            .baseURL("http:// :10.17.7.3")
            其次,我們還需要增加多用戶的支持:
            多用戶數(shù)據(jù)的讀入,其中“user_credentials.csv”存儲的就是用戶名和密碼
          .feed(csv("user_credentials.csv"))
          .exec(http("request_login")
          .post("""/customer/login""")
          .param("""username""", """${username}""")
          .param("""password", "${password}""")
            設(shè)置多用戶的值。由于我們使用的是虛擬機,所以經(jīng)過測試,確定為400用戶并發(fā)。
            setUp(LoginScenario.loginScn.inject(ramp(400 users) over(60 seconds))).
            protocols(httpProtocol)
            最后,我們還要增加檢測點,使用check,find,status等函數(shù)進(jìn)行檢測,下面的代碼檢測了用戶登出的時候HTTP Response Status是否為302:
          exec(http("request_logout")
          .get(("""/customer/logout""")
          .headers(headers_logout)
          .check(status.is(302)))
            當(dāng)然,如果測試人員熟悉Gatling DSL API,我們也可以不用錄制代碼再進(jìn)行重構(gòu),而是直接設(shè)計測試系統(tǒng)并進(jìn)行測試案例的開發(fā)。
            項目采取了敏捷方法進(jìn)行開發(fā),所以系統(tǒng)的一些功能在開發(fā)過程中會出現(xiàn)頻繁改動,導(dǎo)致測試場景和測試腳本也會隨之發(fā)生改變,因此,測試腳本的可讀性和可維護(hù)性對于我們來說就非常重要。當(dāng)某個功能改變之后,使用Gatling腳本就能十分方便的進(jìn)行閱讀和重構(gòu)。比如對于添加user的功能,第一版只需要能添加user即可(見添加user代碼1),而在下一版中,則要求在添加user時可以選擇該user具有那些權(quán)限(見添加user代碼2),代碼如下:
          .exec(http("request_add_user")
          .post("""/customer/users""")
          .headers(headers_user)
          .param("""utf8""", """?""")
          .param("""user[username]""", """user2""")
          .param("""user[email]""", """user@gmail.com""")
          .param("""user[password]""", """user2""")
          .param("""user[password_confirmation]""", """user2""")
            添加user代碼1
          .exec(http("request_add_user")
          .post("""/customer/users""")
          .headers(headers_user)
          .param("""utf8""", """?""")
          .param("""user[username]""", """user2""")
          .param("""user[email]""", """user@gmail.com""")
          .param("""user[password]""", """user2""")
          .param("""user[password_confirmation]""", """user2""")
          .param("""user[plugins][]""", """customer_dashboard""")
          .param("""user[plugins][]""", """customer_files""")
          .param("""user[plugins][]""", """customer_images""")
          .param("""user[plugins][]""", """customer_pages"""))
           添加user代碼2
            項目發(fā)布后,若項目功能發(fā)生改變,我們也可以使用Gatling進(jìn)行持續(xù)的性能回歸測試,保證系統(tǒng)性能不會因為某次修改導(dǎo)致非預(yù)期的降低。如果降低了,就要進(jìn)行及時的調(diào)查,修復(fù)或者是調(diào)整,保證性能一直在預(yù)期的可控范圍內(nèi)。
            測試報表
            Gatling測試報表基于HTML,并且在測試過程中業(yè)已生成,所以打開速度很快。而且,當(dāng)把鼠標(biāo)移動到不同數(shù)據(jù)軸上時,都會有彈出框顯示這個點上詳細(xì)的測試數(shù)據(jù)信息。這種動態(tài)顯示數(shù)據(jù)的方式非常方便查看和分析數(shù)據(jù)。考慮到項目真實數(shù)據(jù)的不便,我將通過Gatling官方網(wǎng)站給出的示例報表進(jìn)行說明。
            Gatling的報表分為兩類:GLOBAL和DETAILS,其中GLOBAL主要是請求相關(guān)的統(tǒng)計數(shù)據(jù),比如每秒請求數(shù),請求成功與失敗數(shù)等;其中DETAILS主要是請求時間相關(guān)的統(tǒng)計數(shù)據(jù),比如請求響應(yīng)時間,請求響應(yīng)延遲時間等。
            
          圖4 每秒請求數(shù)
            當(dāng)鼠標(biāo)放到圖中任何一個點的時候,對應(yīng)時間點上請求的詳細(xì)數(shù)據(jù)就會以圖中白色的彈出框的方式進(jìn)行顯示。在下面的請求響應(yīng)延遲時間圖里面也有同樣的功能。
            
          圖5 請求響應(yīng)延遲時間
            3,與CI的集成
            項目的CI系統(tǒng)選用的是Jenkins,因為Jenkins有Gatling的插件,所以通過這個插件可以在Jenkins上直接查看Gatling的測試結(jié)果,如圖6所示。
            
          圖6 Jenkins Gatling插件
            我們還把生成的報表存檔到每個Build里面,這樣就可以在每個Build中獲得那次測試的所有報表。
            更多類型的測試
            其他類型的HTTP服務(wù)器性能測試,比如瞬間壓力測試,耐久性測試等,都十分適合使用Gatling。
            四,未來的Gatling
            Gatling發(fā)布的時間雖然不長,但憑借其優(yōu)良的性能,DSL模式的腳本,輕量友好的報表系統(tǒng)在眾多服務(wù)器性能測試工具中脫穎而出。在2013年5月發(fā)布的ThoughtWorks技術(shù)雷達(dá)中,Gatling被列入了ADOPT,并在一些ThoughtWorks項目中得到了實際的運用。不過,Gatling還是存在一些問題,比如不支持分布式模型;默認(rèn)只支持HTTP,對于其他協(xié)議需要自己動手進(jìn)行擴展;報表種類也不是很豐富 。倘若Gatling 能在這幾方面有所突破,那么它必將成為新一代服務(wù)器性能測試工具中的殺手锏。

          posted on 2013-10-24 10:52 順其自然EVO 閱讀(342) 評論(0)  編輯  收藏 所屬分類: 性能測試

          <2013年10月>
          293012345
          6789101112
          13141516171819
          20212223242526
          272829303112
          3456789

          導(dǎo)航

          統(tǒng)計

          常用鏈接

          留言簿(55)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 墨竹工卡县| 东安县| 葵青区| 论坛| 高雄县| 永安市| 基隆市| 黄梅县| 肃宁县| 柳河县| 房产| 治县。| 翁牛特旗| 惠水县| 利津县| 五原县| 新丰县| 大港区| 宁晋县| 漠河县| 博白县| 彭州市| 宽甸| 镇宁| 道真| 江川县| 河西区| 通州区| 新民市| 尼勒克县| 阿拉善左旗| 天祝| 敖汉旗| 安福县| 宿迁市| 三原县| 铜山县| 神农架林区| 双鸭山市| 阿合奇县| 彭泽县|