一篇入門 — Gatling 性能測試手冊


介紹

本篇博客,旨在記錄學習的要點,所以格式隨意, 方便本人日后自考和回憶,有興趣的朋友可以評論討論。
原文地址:https://www.cnblogs.com/clockq/p/10539974.html

一. 性能測試基礎

1.1 性能測試時什么?

性能測試時通過自動化的測試工具模擬多種正常峰值、以及異常負載條件,以此來對系統的各項性能指標進行評測。

性能測試 = 負載測試 + 壓力測試

  1. 通過負載測試,確定在各種工作負載下系統的性能,目的是測試系統的負載逐漸增加的情況下,系統的各項性能指標的變化情況。
  2. 通過壓力測試,確定一個系統的瓶頸或者不能接受的性能點,來獲得系統所能提供的最大服務級別。

1.2 性能測試的目的

  1. 評估系統的能力
  2. 識別體系中的弱點
  3. 系統調優
  4. 檢查軟件中的問題
  5. 驗證系統穩定性
  6. 驗證系統可靠性

1.3 性能測試的常見觀察指標

  • Avg Rps: 平均每秒響應次數 = 總請求時間 / 秒數
  • Avg time to last byte per terstion(mstes): 平均每秒業務腳本迭代次數
  • Successful Rounds: 成功的請求
  • Failed Hits: 失敗的單擊次數
  • Hits Per Second: 每秒單擊次數
  • Successful Hits Per Second: 每秒成功的單擊次數
  • Failed Hist Per Second: 每秒失敗的單擊次數
  • Attempted Connections: 嘗試連接數
  • Throughput: 吞吐率

同時,對於服務端的CPU占有率,內存占有率,數據庫連接池等也是需要觀察的重點。

1.4 性能測試的基本流程

  1. 明確性能測試需求
  2. 制定性能測試方案
  3. 編寫性能測試案例
  4. 執行性能測試案例
  5. 分析性能測試結果
  6. 生成性能測試報告

二. Gatling基礎 -> 基礎使用法

2.1 安裝Gatling

獲取安裝包 http://gatling.io.download/
下載成功后解壓即可 使用Gatling需要安裝JDK

2.2 使用Gatling

  1. 編寫測試腳本(這塊重點學習和講解)或者使用自帶的錄制器(bin/recorder.sh)
  2. 執行測試腳本(bin/gatling.sh),在開啟的窗口中選擇要執行的腳本
  3. 查看測試報告(報告默認在“result/”目錄下)
  4. 分析測試結果

三. Gatling 和 Mvn 整合使用 (推薦)

3.1 導入依賴

    <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>

3.2 導入插件

<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>

3.3 編寫腳本

忽略
注意: 腳本要寫在 src/test/scala 下

3.4 執行腳本

mvn gatling:execute

3.5 分析報告

四. 現實測試舉例

我們先以測試“博客園系統登錄頁”性能為例,講解一次測試過程的幾個步驟,和測試報告怎么分析。

4.1 明確性能測試需求

好的開始是成功的一半

明確性能測試的需求是至關重要的,所以我們要先有一份測試需求實例

測試需求名稱: 博客園登錄接口性能測試

信息描述 描述內容
參與者 張三
概述 測試博客園登錄接口的最大並發量
前置條件 博客園前端頁面已經成功部署,並可以正常訪問
后置條件
業務數據 測試登錄賬號
不可測試原因 網絡不可達
流程規則 用戶訪問博客園登錄頁,滯留5s,之后調用登錄接口
業務規則
頁面規則
特殊規則
接口規則
檢查內容 檢查當用戶量達到多大時,會導致服務端阻塞,用戶響應時間超過5s

4.2 編寫性能測試案例

測試需求名稱: 博客園登錄接口性能測試

測試步驟 步驟描述 預期結果
步驟 1 是否測試博客園登錄接口最大並發量 確定性能測試登錄接口的並發用戶數量
步驟 2 啟動博客園的前端工程 前端工程啟動成功
步驟 3 准備性能測試腳本 性能測試腳本准備完成
步驟 4 准備測試數據
步驟 5 執行腳本,驗證系統是否滿足相關性能測試指標 平均響應時長<2s 95%響應時長<= 5s 系統滿足相關性能測試指標
步驟 5 執行1小時壓力測試 1. 系統滿足相關性能測試指標 2. 1小時壓力測試中腳本未報錯

4.3 執行性能測試案例

按照性能測試案例編寫測試腳本

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)

}

並執行上述腳本

4.4 分析性能測試結果

看下圖,可以看到67% + 8%的請求可以在1.2s內完全,同時在1000用戶的並發測試下,會有用戶請求不到資源,也就是加載失敗。

其實,這個地方,可以通過修改gatling.conf來改變表格的渲染區間,使結果更符合我們的測試要求

image

這里,75th的總響應時間=1s,還是很快的,但95th的總響應時間>9s, 所以不符合我們的測試要求。
image

我們使用遞增的方式,在3s內逐漸增加用戶並發量,並且用戶會滯留5s + 60s,在下圖中就得到了體現
image

下圖是本次測試,在每個時間點的請求情況,包含請求狀態(成功,失敗)和請求數量
image

還有更多圖表,就不一一展示了,我們主要就是查看前兩個圖表,以此判斷服務器所能承受的壓力。

當然,如果需要考查更多標准,就需要查看其它圖表,比如延遲分布圖,負載分布圖等等。。。。

4.5 生成性能測試報告

一份合格的性能測試報告,至少應該包含如下內容:

  1. 測試基本信息: 包含: 測試目的,報告目標讀者,術語定義,參考資料
  2. 測試環境描述: 包含: 服務器軟硬件環境,網絡環境,測試工具,測試人員
  3. 性能測試案例執行分析: 需要詳細描述每個測試案例的執行情況,以及對對應測試結果進行分析
  4. 測試結果綜合分析及建議:對本次性能測試做綜合分析,並給出測試結論和改進建議
  5. 測試經驗總結

博客園登錄接口性能測試報告

測試信息

信息描述 描述內容
測試人員 齊鍾昱
測試目的 檢查當用戶量達到多大時,會導致服務端阻塞,用戶響應時間超過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

五. 常用腳本api

5.1 並發量控制

  1. atOnceUsers(100) 使用100並發量測試目標服務器
  2. rampUsers(100) over (10 seconds) 循序漸進的增大壓力,在10s中內線性增加用戶數達到最大壓力100並發量
  3. nothingFor(10 seconds) 等待10s
  4. constantUsersPerSec(rate) during(duration) 在指定duration內,以固定頻率注入用戶,每秒注入rate個用戶,默認固定間隔
  5. constantUsersPerSec(rate) during(duration) randomized 與上面不同的是用戶以隨機間隔注入
  6. rampUsersPerSec(rate1) to (rate2) during(duration) 在指定duration內,以遞增頻率注入用戶,每秒注入 rate1 ~ rate2 個用戶

5.2 用戶行為控制

  1. .exec() 實際的用戶行為
  2. .pause(20) 用戶滯留20s,模擬用戶思考或者瀏覽內容
  3. .pause(min: Duration, max: Duration) 用戶隨機滯留,滯留時間在min ~ max 之間

5.3 流程控制

  1. repeat(time, counterName) 內置循環器
  2. foreach(seq, elem, counterName) foreach循環器
  3. csv("file").random 創建填充器
  4. doIf("", "") 判斷語句


免責聲明!

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



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