使用JMeter進行壓力測試
說到壓力測試,一般第一反應都是LoadRunner.這個軟件也確實是自動化測試的一個事實標准.無奈這個軟件太過龐大,以及不能在MacOS上使用.我由於項目的需要,需要對一個模塊的WebServcie接口做壓力的測試,於是就找到了另外一個神器JMeter. JMeter是Apache組織開發的基於Java的壓力測試工具.它是由JAVA編寫的,可以跨平台.最初只能測試Web應用,現在可以進行各種的壓力測試,包括但不限於JAVA小程序,CGI腳本,JAVA RMI調用,數據庫,FTP服務等等. 並且它的操作非常簡單,通過幾部的配置就可以創建一個完整的壓力測試用例.
JMeter安裝
JMeter是由JAVA編寫的,所以需要依賴JDK的運行環境,最新版的JMeter需要JDK1.6以上的支持.
JMeter的軟件可以通過官網下載.直接下載編譯后的壓縮包,然后在終端中輸入:unzip apache-jmeter-2.13.zip
進行解壓
而后在終端中執行./jmeter
即可啟動主界面.
進行Web的壓力測試
JMeter中最小的單位就是元件.你可以給你的測試計划中增加若干的元件,每一個元件其實就是一個步驟. JMeter中設置了各種不同的元件:有設置用戶的,有設置定時器的,有設置前后置處理的,有設置斷言的還有設置監聽器的.通過這些不同的元件的組合,我們就能很很容易的組合出更多不同的壓力測試用例.
我們以最簡單的Web服務器的壓力測試為例,來演示下如何使用JMeter設置測試用例.
設置線程組(模擬用戶)
壓力測試不同於功能測試,軟件的正確性並不是它的測試重點。它所看重的是軟件的執行效率,尤其是短時間內訪問用戶數爆炸性增長時軟件的響應速度.因此就需要同時模擬多個用戶對系統進行請求. 因此,一般設置測試計划的第一步都是創建一個線程組,用來模擬多個用戶的操作.

而后就需要設置線程組的一些屬性.
- 線程數:相當於是模擬用戶的數量.
- 准備時長:表示線程之間間隔多少時間,單位是秒.0就表示了所有的線程並發發送請求,否則就是每個線程間隔幾秒發送請求
- 循環次數:表示每個線程執行幾次
- 調度器:就是創建線程的schedule.
- 在取樣器錯誤后執行的操作:表示線程出現錯誤后執行的操作.比如繼續,或者停止線程,或者測試

設置HTTP請求
這里我們使用最簡單的用例進行測試——訪問我的博客的首頁,測試QPS(Query Per Second 每秒查詢率)的情況.
因此,接下來我們需要增加的就是在線程組上面右鍵—-添加—-Sampler—-HTTP請求.

在JMetaer中取樣器(Sampler)就是與服務器進行交互的元件.一個取樣器通常會進行三個部分的工作:
- 向服務器發送請求
- 記錄服務器的響應數據
- 記錄響應的時間信息

這里我設置了:
- 服務器名稱: sunxiang0918.cn
- 端口號: 80
- HTTP請求實現: JAVA
- 協議: http
- 方法: GET
- ContentEncoding: UTF-8
- 路徑: /
其實這樣就算是完成了一個HTTP請求的設置了.這個時候我們就可以保存這個測試用例到一個JMX文件
中.然后執行這個測試用例了. 不過,由於我們還沒有配置監聽器元件,因此,現在運行的話.我們是看不到任何的結果的.
請求參數模板化
在實際的使用中,我們的請求中可能有不同的參數,並且這些參數可能是不相同的.這就需要把參數模板化.
在JMeter中,參數的語法是: ${xxxx}
其中的xxxx
即為參數名. 通過這個語法,就可以在整個請求中調用參數的值. 只要我們對這些參數進行賦值即可.

比如在這里我們增加一個Random Variable
.這個表示的是隨機的給一個變量進行賦值.
我們在這里設置了一個keyword
的變量,其值為0
到100
間的隨機數.隨機方式采用默認的.

然后在請求中增加一個請求的參數:
執行測試計划,會發現請求的URL就會變成:GET http://sunxiang0918.cn/?aaaaa=xxxx49
,后面的數字就是隨機.
除了隨機變量或用戶定義的變量外.還可以讀取CSV文件,通過CSV Data Set Config
,可以讀取CSV文件,並且制定每一列的變量名是什么.這樣就可以在請求的時候預設多個變量值.
增加響應斷言
為了判斷結果的正確性,我們有時需要增加響應的斷言.比如響應代碼必須是200才作數. JMeter中有一個元件就叫做響應斷言
.這個就可以加在HTTP請求的后面,用來判斷結果是否正確.

在這里我只增加了一個最簡單的通過響應代碼來判斷請求是否正確.

除此之外,它還能通過響應的內容,響應的頭信息等來進行判斷.功能非常的強大.
設置結果監聽器
為了我們能查看到請求的結果,我們需要再添加監聽器. 在這里我們增加三個結果監聽器:察看結果樹
圖形結果
以及聚合報告
查看結果樹
可以查看到每一次請求的具體情況,包括了請求參數,結果反饋,請求時間等等. 圖形結果
可以以圖形的方式展現請求的中和結果. 聚合報告
會展示本次測試計划所有的請求的一個聚合的結果.

這幾個結果監聽器都不需要什么設置.增加后,即可再執行一次測試計划.里面就會有結果了.

我們先來看查看結果樹
. 它顯示了這次請求的所有信息.比如開始時間,線程名字,完成用時,請求大小,反饋大小,反饋代碼,采樣次數,錯誤信息,反饋頭信息,反饋體等等. 通過這個列表,我們就能很清楚的知道所有請求的大概情況.

然后就是圖形結果
從這個圖上就能很清楚的看出整個請求和響應的趨勢.
最后就是聚合報告
. 它用表格的形式展示了本次測試的總體情況.
LabelSamplesAverageMedian90%Line95%Line99%LineMinMaxErrorThroughputKB/sec名稱采樣請求數平均響應時間中位數90%用戶響應時間95%用戶響應時間99%用戶響應時間最小響應時間最大響應時間錯誤請求百分比吞吐量,每秒完成請求數每秒接收數據量HTTP請求20081166015371886242227534240.00%15.8/sec542.3
限制QPS
為了了解博客的首頁在負載達到30QPS時的響應時間,我們就需要控制向博客首頁發送請求的負載為固定的30QPS. JMeter提供了一個非常有用的定時器:Constant Throughput Timer
(常數吞吐量定時器),通過該定時器可以方便的控制給一個采樣器發送請求的吞吐量.

首先是Target throughput
目標吞吐量,需要注意的是這個的單位是分鍾. 比如我們要測試的是30QPS,那么一分鍾的吞吐量就是 1800. 而Calculate Throughput based on
有五個選項:
- This thread only:控制每一個線程的吞吐量.這個時候,總吞吐量就是
Target throughput
乘以線程數 - All active threads:設置總體的吞吐量,它會把
Target throughput
分配到每一個活躍的想成上. - All active threads in current thread group.設置總體的吞吐量,它會把
Target throughput
分配到每一個活躍的想成上.當一個測試計划中只有一個測試組的時候,效果和All active threads
是一樣的. - All active threads(shared):與
All active threads
的區別在於,每個活躍線程都會在所有活躍線程上一次運行結束后等待一定的時間后再次運行. - All active threads in current thread group(shared):與
All active threads in current thread group
的區別在於,每個活躍線程都會在所有活躍線程上一次運行結束后等待一定的時間后再次運行.
因此,我們這里選擇了All active threads
.
需要注意的是:這個常量吞吐量定時器只有在線程組中產生了足夠多的請求的時候才有意義.否則,就算設置了這個Target throughput
,也有可能由於線程數和請求數不夠,而打不到預期的目標.
在這個基礎上再跑一次的結果為:
LabelSamplesAverageMedian90%Line95%Line99%LineMinMaxErrorThroughputKB/sec名稱采樣請求數平均響應時間中位數90%用戶響應時間95%用戶響應時間99%用戶響應時間最小響應時間最大響應時間錯誤請求百分比吞吐量,每秒完成請求數每秒接收數據量HTTP請求30091072315251812326830592550.00%11.2/sec387.0
由此可見,在這里訪問github.io,確實相當的慢啊….
總結
這里只是簡單的展示了一下JMeter的用法,其實對其他的壓力測試,比如WebService
,Restful
,RMI
等的測試都可以參照這個步驟,增加不同的元件即可.