?🔥個人主頁:?中草藥
?🔥專欄:【Java】登神長階 史詩般的Java成神之路
概念
????????性能測試是軟件測試的重要分支,核心目標是通過模擬真實業務場景和負載壓力,評估系統在不同條件下的性能表現,發現系統性能問題,驗證其是否滿足預期的性能指標(如響應速度、穩定性、并發能力等),并定位性能瓶頸以支撐優化。
關鍵指標
響應時間(Response Time):用戶發起請求到系統返回結果的總時間(如接口響應時間、頁面加載時間),直接影響用戶體驗。
對于Web應用而言,系統響應時間包括前端展現時間和系統響應時間
前端展現時間:頁面渲染時間
系統響應時間:包括服務器,數據庫,通訊網絡等響應時間
吞吐量(Throughput):單位時間內系統處理的請求數 / 數據量(如 TPS 每秒事務數、QPS 每秒查詢數),直接反映系統負載承受能力。
并發用戶數(Concurrent Users):指的是Web服務器在一段時間內處理瀏覽器請求而建立http連接數或生成的處理線程數(注意:非 “在線用戶數”,而是實際操作的活躍用戶)。
資源利用率:CPU、內存、磁盤 I/O、網絡帶寬等服務器資源的占用率,過高會導致性能下降。
穩定性:系統在長時間高負載下是否持續正常運行(無崩潰、無內存泄漏、響應時間穩定)。
TPS:每秒處理事務數,用于衡量系統在一定時間內能夠處理的事務數
計算公式:總的事務數/總的運行時間
舉例 1:某一系統 1 分鐘處理 1000 個業務,那么 TPS = 1000 / 60 = 16.7
舉例 2:2022 年最高的一天有 10 萬筆交易,預測 2023 年 TPS 需要多少合格?認為每筆交易就是一個事務,理論 TPS = 100000 / 24*60*60 = 1.2(理想狀態),然而實際上訂單量會在某段時間內突然增加,并不是平均到每個時間段內,因此
1)沒有更詳細的數據:根據二八定律(80% 的事務在 20% 的時間內完成)
TPS = 100000 * 0.8 / 24*60*60*0.2 = 4.6
2)如果有詳細的數據:5 萬筆交易在晚上的 8~9 點完成的
TPS = 50000 / 60*60 = 13.9(實際還要參考往年業務的增長,假設每年業務增長 30%,則 TPS = 50000 + 50000*0.3 / 60*60 = 18)
QPS:每秒查詢率,若一個事務中只有一個接口且是查詢接口,則QPS=TPS
測試分類
測試類型 | 核心目的 | 典型場景舉例 |
---|---|---|
基準測試 | 又稱單用戶測試,在標準環境下執行特定場景,獲取性能基準值(如響應時間、吞吐量),作為后續優化或版本對比的參考。 | 新功能上線前,測試核心支付接口在 50 并發下的平均響應時間,建立性能基線。 |
并發測試 | 模擬多個用戶同時發起相同 / 不同操作,驗證系統在并發場景下的資源競爭、數據一致性表現。 | 100 個用戶同時搶購同一件限量商品,測試訂單數據是否準確無重復。 |
負載測試 | 逐步增加負載(如用戶數、請求量),觀察性能指標變化,找到 “正常負載下的性能閾值”。 | 電商日常促銷時,驗證系統在 1000 并發用戶下是否穩定。 |
壓力測試 | 超過預期負載持續加壓,找到系統 “極限瓶頸”(如崩潰、響應超時的臨界點)。 | 模擬 2000 并發用戶訪問,測試系統最大承載能力。 |
耐久性測試 | 在預期負載下長時間運行(幾小時到幾天),驗證系統穩定性(是否內存泄漏、資源耗盡)。 | 核心交易系統連續 72 小時運行,監控資源是否持續增長。 |
尖峰測試 | 突發高負載沖擊(如瞬間用戶數暴漲),驗證系統抗突發能力。 | 秒殺活動開始瞬間,10 秒內用戶從 100 突增至 5000。 |
配置測試 | 調整系統配置(如服務器數量、JVM 參數、數據庫連接池),找到最優配置方案。 | 測試 “2 核 4G” vs “4 核 8G” 服務器的性能差異。 |
容量測試 | 驗證系統在數據量增長下的性能(如數據庫數據量從 10 萬到 1000 萬時的響應變化)。 | 社交平臺用戶數據達 1 億時,好友列表查詢是否延遲。 |
Jmeter
????????JMeter 是 Apache 基金會開發的一款開源性能測試工具,主要用于模擬多用戶并發場景,測試軟件(如 Web 應用、API、數據庫等)的性能指標(如響應時間、吞吐量、并發能力等),廣泛應用于負載測試、壓力測試、接口測試等場景。它支持多種協議,操作靈活且擴展性強,是性能測試領域的主流工具之一。
核心組件
jmeter有著很多非常核心的組件,其中JMeter元件的作用域主要由測試計劃的樹形結構中的元件父子關系來確定
線程組(Thread Group)
性能測試的 “負載發生器”,定義并發用戶數、測試持續時間、用戶啟動速度等。
取樣器(Sampler)
模擬用戶具體操作,向目標系統發送請求(如 HTTP 請求、數據庫查詢)。比如HTTP請求取樣器
監聽器(Listener)
收集并展示測試結果,支持實時查看或事后分析。比如結果樹
配置元件(Config Element)
為取樣器提供默認配置(如請求頭、數據庫連接信息),減少重復設置。比如
HTTP請求默認值
用戶定義的變量
HTTP Cookie管理器
自動存儲 Cookie:當服務器通過Set-Cookie
響應頭返回 Cookie 時,Cookie 管理器會自動捕獲并保存這些 Cookie(包括名稱、值、域名、路徑、過期時間等屬性)。
自動發送 Cookie:后續向同一服務器發送請求時,Cookie 管理器會根據 Cookie 的域名、路徑規則,自動將匹配的 Cookie 通過Cookie
請求頭攜帶到請求中,模擬瀏覽器 “記住會話狀態” 的行為。
前置 / 后置處理器(Pre/Post Processor)
處理請求前的參數(如動態獲取 token)或響應后的結果(如提取返回值供后續請求使用)。比如后置處理器 Json提取器
操作符 | 作用說明 | 語法示例 | 說明(結合 JSON 示例) |
---|---|---|---|
$ | 表示 JSON 數據的?根節點,所有路徑均從根節點開始。 | $.name | 從根節點開始,提取?name ?字段的值。 |
. | 訪問當前節點的?子節點(直接子節點)。 | $.user.name | 訪問根節點下?user ?子節點的?name ?字段(適用于嵌套結構)。 |
.. | 遞歸匹配所有?子孫節點(跨層級查找,不局限于直接子節點)。 | $..email | 遞歸查找所有層級中名為?email ?的字段,無論其在嵌套結構的第幾層。 |
* | 通配符,匹配?所有子節點?或?數組元素。 | $.users[*].age | 匹配?users ?數組中所有元素的?age ?字段,提取所有用戶的年齡。 |
[] | 訪問數組元素,支持索引、范圍或過濾。 | $.users[0] $.users[1:3] | -?[0] ?提取數組第 1 個元素(索引從 0 開始);-? [1:3] ?提取數組索引 1 到 2 的元素(左閉右開)。 |
?() | 過濾數組元素,通過條件表達式篩選符合條件的節點。 | $.users[?(@.age > 18)].name | 從?users ?數組中篩選出?age > 18 ?的元素,提取其?name ?字段。 |
@ | 在過濾表達式??() ?中,代表?當前節點(用于引用當前元素的屬性)。 | $.users[?(@.name == 'Alice')].id | @ ?指代?users ?數組中的每個元素,篩選?name ?為?Alice ?的元素,提取其?id 。 |
['字段名'] | 通過屬性名訪問子節點(與?. ?作用類似,支持特殊字符字段名,如含空格的字段)。 | $.user['full name'] | 訪問?user ?節點下名為?full name ?的字段(字段名含空格時必須用此語法)。 |
length() | 數組長度函數,返回數組的元素數量(需配合過濾或數組操作)。 | $.users.length() | 返回?users ?數組的長度(即用戶總數)。 |
舉例,我們有以下Json數據
{"name": "JMeter","user": {"id": 1001,"full name": "Test User","email": "test@example.com"},"users": [{"name": "Alice", "age": 20, "id": 1},{"name": "Bob", "age": 17, "id": 2},{"name": "Charlie", "age": 25, "id": 3}]
}
$.name
?→ 提取結果:"JMeter"
$.user.email
?→ 提取結果:"test@example.com"
$..age
?→ 提取結果:[20, 17, 25]
(遞歸找到所有?age
?字段)$.users[*].name
?→ 提取結果:["Alice", "Bob", "Charlie"]
$.users[?(@.age > 18)].name
?→ 提取結果:["Alice", "Charlie"]
$.users.length()
?→ 提取結果:3
(數組長度為 3)
Json斷言
接口發送請求成功,并不完全意味著接口請求成功,我們更多的需要關注接口響應數據是否符合預期,JSON 斷言的核心是JSON Path 表達式(類似 XML 的 XPath,用于定位 JSON 中的元素)。通過 JSON Path 定位到目標字段后,斷言會對比該字段的實際值與預設的 “預期值”,判斷是否匹配。
若不選Additionally assert value,表示添加斷言值,則可用來判斷字段是否存在
若選擇Match as regularexpression正則匹配,則Expected Value可以僅寫上部分關鍵詞即可斷
言成功
CSV數據文件設置
CSV數據文件設置輔助我們去模擬更真實的用戶環境
CSV 數據文件(Comma-Separated Values,逗號分隔值文件)是一種純文本格式的表格數據存儲文件,主要用于存儲結構化數據(如電子表格、數據庫表等),并實現不同系統、工具之間的數據交換。
- 文件名:填寫csv文件的路徑。建議使用絕對路徑。
- 文件編碼:UTF-8
- 變量名稱:從csv數據文件中讀起的數據需要保存到的變量名。有多個變量時用逗號分隔
- 是否忽略首行:是否從csv數據文件第一行開始讀取。
- 分隔符:要求與csv數據文件中多列的分隔符一致
- 遇到文件結束符再次循環:若選擇為True當數據不夠的時候會從頭取。若選擇False,則需要勾選下面的配置,遇到文件結束符停止線程,這里如果不勾選,請求將會報錯。
定時器(Timer)
控制請求發送的間隔(如模擬用戶思考時間),避免請求無間隔發送(非真實場景)。
為了達到并發的效果,我們需要添加同步定時器(集合點)
模擬用戶組的數量(Number of simulated users to group by):
設定 “同時釋放的用戶數”(即并發閾值)。例如設為 100,表示當有 100 個用戶被阻塞時,同時釋放這 100 個用戶執行后續操作。
超時時間(Timeout in milliseconds):
若超過該時間仍未達到 “用戶組數量”,則無論當前阻塞多少用戶,都會強制釋放(避免無限等待)。例如設為 5000(5 秒),若 5 秒內只有 80 個用戶到達,則釋放這 80 個用戶。
配置后的日志如下:
事務控制器
將一系列連續的操作(如請求、邏輯控制器等)“打包” 為一個 “事務”,用于統計該事務的整體響應時間、成功率等指標,更貼合真實業務場景中 “用戶完成一個完整操作” 的概念。
壓力測試
環境準備
1、先下載插件管理
Install :: JMeter-Plugins.org
并將插件添加至jmeter下的lib/ext文件夾下
安裝成功右上角會出現一個蝴蝶的logo
2、下載所需插件,分別下載
監聽器插件 Page Data Extractor
線程組插件
Custom Thread Groups?
3 Basic Graphs?
梯度壓測線程組 Stepping Thread Group
添加監聽器-匯總報告,聚合報告,Response Times Over Time,Transaction pet second
我們可以系統日志去更加詳盡的分析此次測試過程
jmeter -n -t 腳本文件 -l 日志文件 -e -0 目錄
-n 無圖形化運行
-t 被運行的腳本
-l 將運行信息寫入日志文件,后綴為jtl的日志文件
-e 生成測試報告
-o 指定報告輸出目錄
性能分析
可以通過三大性能指標去分析性能問題
響應時間
如果響應時間超過了要求,代表系統遇到了瓶頸,注意分析多少線程的情況下發生了超標,響應時間變化會受到系統穩定性影響,隨著系統并發壓力變大,響應時間會變高
吞吐量
吞吐量越大,性能越好;吞吐量相對穩定或者變低,可能系統達到了性能瓶頸
變化規律:
波動很大:代表系統性能不穩定
慢慢變高,再趨于穩定:和并發量強相關。如果并發量小于吞吐量,慢慢增大并發量,吞吐量也會隨之增加
慢慢變低,并發量也減少了:要么說明性能測試要結束了,并發減少;也可能是系統變的卡頓,從而導致響應時間變慢,導致單個線程發起的并發量變少
錯誤率(Error Rate):異常請求數占總請求數的比例(單位:%),反映系統 “穩定性和容錯能力”。錯誤類型包括 5xx(服務器錯誤,如超時、OOM)、4xx(客戶端錯誤,如參數錯誤、權限不足)等。
一般要求可靠的成功率在99.9999%
錯誤率高的原因:
接口請求錯誤
服務器無法繼續處理,達到了性能瓶頸(業務邏輯有問題,內存泄漏,硬件資源等等)
后端系統限流(系統配置了最大并發數的限制)實現了熔斷,降級
熔斷:防止系統因某個服務的故障而整體崩潰。當電商平臺上用戶支付時,收銀臺發現某個支付渠如微信支付失敗率突增,超時嚴重,那么就可以臨時把這個支付方式熔斷掉道
降級:主動關閉一些非核心功能,以確保核心功能的正常運行。某次騰訊視頻掛了的時候,用戶名稱默認顯示騰訊用戶,:這也是一種降級方式,用兜底名稱做展示
在自己身上,克服這個時代。? ? ? ? ? ? ? ——尼采
🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀
以上,就是本期的全部內容啦,若有錯誤疏忽希望各位大佬及時指出💐
? 制作不易,希望能對各位提供微小的幫助,可否留下你免費的贊呢🌸?