本篇博客,旨在記錄學習的要點,因此格式隨意, 方便本人往後自考和回憶,有興趣的朋友能夠評論討論。
原文地址:https://www.cnblogs.com/clockq/p/10539974.htmljavascript
==性能測試時經過自動化的測試工具模擬多種正常、峯值、以及異常負載條件,以此來對系統的各項性能指標進行評測。==css
性能測試 = 負載測試 + 壓力測試html
同時,對於服務端的CPU佔有率,內存佔有率,數據庫鏈接池等也是須要觀察的重點。前端
獲取安裝包 http://gatling.io.download/
下載成功後解壓便可 使用Gatling須要安裝JDKjava
<properties> <gatling.version>2.1.7</gatling.version> <gatling-plugin.version>2.1.7</gatling-plugin.version> </properties> <!-- Gatling Module --> <dependency> <groupId>io.gatling.highcharts</groupId> <artifactId>gatling-charts-highcharts</artifactId> <version>${gatling.version}</version> </dependency>
<build> <sourceDirectory>src/test/scala</sourceDirectory> <testSourceDirectory>src/test/scala</testSourceDirectory> <plugins> <!-- Gatling Maven plugin that runs the load-simulation. --> <plugin> <groupId>io.gatling</groupId> <artifactId>gatling-maven-plugin</artifactId> <version>${gatling-plugin.version}</version> <configuration> <configFolder>src/test/resources</configFolder> <dataFolder>src/test/resources/data</dataFolder> <resultsFolder>target/gatling/results</resultsFolder> <runMultipleSimulations>true</runMultipleSimulations> <simulationsFolder>src/test/scala/com/pharbers/gatling</simulationsFolder> <simulationClass>com.pharbers.gatling.scenario.getHome</simulationClass> <!-- <noReports>false</noReports> --> <!-- <reportsOnly>directoryName</reportsOnly> --> <!-- <simulationClass>foo.Bar</simulationClass> --> <!-- <jvmArgs> --> <!-- <jvmArg>-DmyExtraParam=foo</jvmArg> --> <!-- </jvmArgs> --> <!-- <fork>true</fork> --> <!-- <propagateSystemProperties>true</propagateSystemProperties> --> <!-- <failOnError>true</failOnError> --> </configuration> </plugin> </plugins> </build>
忽略
注意: 腳本要寫在 src/test/scala 下web
mvn gatling:execute數據庫
咱們先以測試「博客園系統登陸頁」性能爲例,講解一次測試過程的幾個步驟,和測試報告怎麼分析。json
好的開始是成功的一半api
明確性能測試的需求是相當重要的,因此咱們要先有一份測試需求實例服務器
測試需求名稱: 博客園登陸接口性能測試 | 信息描述 | 描述內容 | | :--: | :--: | | 參與者 | 張三 | | 概述 | 測試博客園登陸接口的最大併發量 | | 前置條件 | 博客園前端頁面已經成功部署,並能夠正常訪問 | | 後置條件 | 無 | | 業務數據 | 測試登陸帳號 | | 不可測試緣由 | 網絡不可達 | | 流程規則 | 用戶訪問博客園登陸頁,滯留5s,以後調用登陸接口 | | 業務規則 | 無 | | 頁面規則 | 無 | | 特殊規則 | 無 | | 接口規則 | 無 | | 檢查內容 | 檢查當用戶量達到多大時,會致使服務端阻塞,用戶響應時間超過5s |
測試需求名稱: 博客園登陸接口性能測試 | 測試步驟 | 步驟描述 | 預期結果 | | :--: | :--: | :--: | | 步驟 1 | 是否測試博客園登陸接口最大併發量 | 肯定性能測試登陸接口的併發用戶數量 | | 步驟 2 | 啓動博客園的前端工程 | 前端工程啓動成功 | | 步驟 3 | 準備性能測試腳本 | 性能測試腳本準備完成 | | 步驟 4 | 準備測試數據 | 無 | | 步驟 5 | 執行腳本,驗證系統是否知足相關性能測試指標 平均響應時長<2s 95%響應時長<= 5s | 系統知足相關性能測試指標 | | 步驟 5 | 執行1小時壓力測試 | 1. 系統知足相關性能測試指標 2. 1小時壓力測試中腳本未報錯 |
按照性能測試案例編寫測試腳本
package com.pharbers.gatling.base import io.gatling.core.Predef._ import io.gatling.http.Predef._ import io.gatling.http.config.HttpProtocolBuilder object phHttpProtocol { implicit val noneWhiteList: io.gatling.core.filter.WhiteList = WhiteList() implicit val noneBlackList: io.gatling.core.filter.BlackList = BlackList() implicit val staticBlackList: io.gatling.core.filter.BlackList = BlackList(""".*\.js""", """.*\.css""", """.*\.gif""", """.*\.jpeg""", """.*\.jpg""", """.*\.ico""", """.*\.woff""", """.*\.(t|o)tf""", """.*\.png""") implicit val staticWhiteList: io.gatling.core.filter.WhiteList = WhiteList(""".*\.js""", """.*\.css""", """.*\.gif""", """.*\.jpeg""", """.*\.jpg""", """.*\.ico""", """.*\.woff""", """.*\.(t|o)tf""", """.*\.png""") def apply(host: String) (implicit blackLst: io.gatling.core.filter.BlackList, whiteLst: io.gatling.core.filter.WhiteList): HttpProtocolBuilder = { http .baseURL(host) .inferHtmlResources(blackLst, whiteLst) .acceptHeader("application/json, text/javascript, */*; q=0.01") .acceptEncodingHeader("gzip, deflate") .acceptLanguageHeader("zh-CN,zh;q=0.9,zh-TW;q=0.8") .doNotTrackHeader("1") .userAgentHeader("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36") } }
package com.pharbers.gatling.base object phHeaders { val headers_base = Map( "Accept" -> "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8", "Upgrade-Insecure-Requests" -> "1") }
package com.pharbers.gatling.scenario import io.gatling.core.Predef._ import io.gatling.http.Predef._ import io.gatling.core.structure.ChainBuilder import com.pharbers.gatling.base.phHeaders.headers_base object getHome { val getHome: ChainBuilder = exec(http("home") .get("/") .headers(headers_base)) }
package com.pharbers.gatling.scenario import io.gatling.core.Predef._ import io.gatling.http.Predef._ import io.gatling.core.structure.ChainBuilder import com.pharbers.gatling.base.phHeaders.headers_json object userLogin { val feeder = csv("loginUser.csv").random println(feeder) val login: ChainBuilder = exec(http("login") .get("/api/user/login") .headers(headers_json) .body(StringBody("""{ "condition" : { "email" : "nhwa", "password" : "nhwa" } }""")).asJSON) }
package com.pharbers.gatling.simulation import io.gatling.core.Predef._ import scala.concurrent.duration._ import com.pharbers.gatling.scenario._ import com.pharbers.gatling.base.phHttpProtocol class userLogin extends Simulation { import com.pharbers.gatling.base.phHttpProtocol.{noneBlackList, noneWhiteList} val httpProtocol = phHttpProtocol("http://192.168.100.141:9000") val scn = scenario("user_login") .exec( getHome.getHome .pause(5 seconds), userLogin.login .pause(60 seconds) ) setUp(scn.inject(rampUsers(1000) over (3 seconds))).protocols(httpProtocol) }
並執行上述腳本
看下圖,能夠看到67% + 8%的請求能夠在1.2s內徹底,同時在1000用戶的併發測試下,會有用戶請求不到資源,也就是加載失敗。
其實,這個地方,能夠經過修改gatling.conf來改變表格的渲染區間,使結果更符合咱們的測試要求
這裏,75th的總響應時間=1s,仍是很快的,但95th的總響應時間>9s, 因此不符合咱們的測試要求。
咱們使用遞增的方式,在3s內逐漸增長用戶併發量,而且用戶會滯留5s + 60s,在下圖中就獲得了體現
下圖是本次測試,在每一個時間點的請求狀況,包含請求狀態(成功,失敗)和請求數量
還有更多圖表,就不一一展現了,咱們主要就是查看前兩個圖表,以此判斷服務器所能承受的壓力。
固然,若是須要考查更多標準,就須要查看其它圖表,好比延遲分佈圖,負載分佈圖等等。。。。
一份合格的性能測試報告,至少應該包含以下內容:
博客園登陸接口性能測試報告
測試信息
信息描述 描述內容 測試人員 齊鍾昱 測試目的 檢查當用戶量達到多大時,會致使服務端阻塞,用戶響應時間超過5s 術語定義 50th,安裝遞增排序後,排在50%的請求的信息 術語定義 95th,安裝遞增排序後,排在95%的請求的信息 參考資料 零成本實現Web性能測試[電子工業出版社] 測試環境
信息描述 描述內容 服務器系統 CentOS Linux release 7.4.1708 (Core) 服務器集羣數量 4 服務器內存(臺) 16G 服務器CPU核心數(臺) 12 服務器硬盤空間(臺) 256G SSD JAVA版本 1.8.121 Scala版本 2.11.8 Play版本 2.5.0-M2 Redis版本 4.0.1 MongoDB版本 3.4.4 Node.js 8.11.2 Ember.js 2.18.2 網絡環境 公司局域網 測試工具 Gatling 2.1.7 結果分析
測試內容 預期結果 測試結果 備註 博客園系統登陸頁的最大訪問量 在當前環境下能夠1000用戶併發,不會形成用戶請求失敗 在3s內逐漸提升併發量,當併發量在643時有三個資源請求失敗,在併發量達到689時,有64個資源請求失敗 未經過,當前博客園系統登陸頁的最大訪問量應小於643 博客園系統登陸接口的最大併發量 在當前環境下能夠1000用戶併發,不會形成用戶請求失敗 在3s內逐漸提升併發量,當併發量達到1000時,請求資源仍所有成功 經過 博客園登陸頁的響應時間 在當前環境下用戶平均響應時長<2s 95%響應時長<= 5s 50th響應時間爲1.6s,95th爲22s 未經過 博客園登陸接口的響應時間 在當前環境下用戶平均響應時長<2s 95%響應時長<= 5s 50th響應時間 < 1s,95th < 1s 經過 測試總結
根據上述分析報告,本次性能測試爲經過制定要求,博客園系統登陸功能的最大併發量應小於643,爲保持性能,建議併發數小於500
atOnceUsers(100)
使用100併發量測試目標服務器rampUsers(100) over (10 seconds)
按部就班的增大壓力,在10s中內線性增長用戶數達到最大壓力100併發量nothingFor(10 seconds)
等待10sconstantUsersPerSec(rate) during(duration)
在指定duration內,以固定頻率注入用戶,每秒注入rate個用戶,默認固定間隔constantUsersPerSec(rate) during(duration) randomized
與上面不一樣的是用戶以隨機間隔注入rampUsersPerSec(rate1) to (rate2) during(duration)
在指定duration內,以遞增頻率注入用戶,每秒注入 rate1 ~ rate2 個用戶.exec()
實際的用戶行爲.pause(20)
用戶滯留20s,模擬用戶思考或者瀏覽內容.pause(min: Duration, max: Duration)
用戶隨機滯留,滯留時間在min ~ max 之間repeat(time, counterName)
內置循環器foreach(seq, elem, counterName)
foreach循環器csv("file").random
建立填充器doIf("", "")
判斷語句