JMeter入門介紹


目錄

概述

作為一名后端開發人員,熟練掌握一款性能測試工具非常有必要,這樣有利於在技術選型時做一些參考。
常見的性能測試工具有:ab,JMeter,LoadRunner,他們都有各自的特點和應用場景:

  1. ab是Apache的一個工具組件,專門用於HTTP服務器測試。
  2. JMeter是一款遵循Apache開源協議的性能測試工具,除了可以用於HTTP服務器性能測試之外,還可以用於FTP,JDBC,LDAP測試等。
  3. LoadRunner是一款商業化性能測試工具,使用相對復雜一些,但是功能非常強大。

下載&安裝

http://jmeter.apache.org/download_jmeter.cgi

JMeter是基於Java開發的跨平台性能測試工具,官方提供了2種壓縮格式的二進制包(zip和tgz),根據實際情況下載對應文件即可。
安裝也非常簡單,直接將壓縮包解壓到指定目錄即可,如下示例:

$ tar xzvf apache-jmeter-5.2.1.tgz -C ~/opt

添加JMeter到環境變量PATH中,如下示例:

$ export JMETER_HOME=~/opt/apache-jmeter-5.2.1
$ export PATH=$PATH:$JMETER_HOME/bin

配置好JMeter環境變量之后,在命令行終端中執行命令jmeter即可啟動JMeter圖形化界面。

實戰JMetetr

使用JMeter分為3個步驟:

  1. 准備測試計划
  2. 執行性能測試
  3. 分析測試報告

測試計划簡述

所謂測試計划就是一系列測試配置信息的集合,在JMeter中可以將這些配置信息保存為一個腳本文件(后綴名為“.jmx”)。
測試計划中涉及許多配置對象,詳見:Elements of a Test Plan,理解這些配置對象是編寫JMeter測試計划的前提,各個配置對象的名稱及含義解釋如下:

  1. Test Plan:測試計划,組織所有配置信息,是其他配置對象的根
  2. Thread Group:線程組,用於並發參數設置
  3. Controller:控制器,驅動着整個測試計划的執行
  4. Sampler:采樣器,用於配置指定類型的請求
  5. Assertion:斷言,用於對請求結果進行驗證
  6. Timer:定時器,可用於對並發進行控制(例如:設置請求結束后是否延遲再次發送請求)
  7. Configuration Element:配置元素,如:HTTP請求默認值(HTTP Request Defaults),隨機變量(Random Variable)等等
  8. Pre-Processor Element:請求執行前置處理器
  9. Post-Processor Element:請求執行后置處理器
  10. Listener:監聽器,通常用於展示測試結果,也可以用於對響應數據進行處理(比如:將響應結果寫入到文件)
  11. Test Fragment:這個元素目前沒有實際用途
  12. Non-Test Element:非測試元素,用於設置一些其他參數,不常用

一般來講,上述對象之間具備嵌套關系,描述如下:
(1)一個測試腳本中只有一個Test Plan對象,並且作為其他對象的根。
(2)在Test Plan下可以有一個或者多個Thread Group(通常只需要有一個即可),可以有一個或者多個Listener,如:View Results Tree(以樹型結構展示),還可以配置Assertion,Timer,Configuration Element,Pre Processor,Post Processor,Test Fragment,Non-Test Element。
(3)在Thread Group下可以配置Controller,Sampler,Assertion,Timer,Configuration Element,Pre-Processor,Post-Processor,Test Fragment,Listener。
(4)Controller下可以配置Controller,Sampler,Assertion,Timer,Configuration Element,Pre-Processor,Post-Processor,Listener。
(5)在Sampler下可以配置Assertion,Timer,Configuration Element,Pre-Processor,Post-Processor,Listener。

用一個樹型結構來描述各對象之間的嵌套關系如下:

  • Test Plan
    • Thread Group
      • Controller
        • Controller
        • Sampler
          • Assertion
          • Timer
          • Configuration Element
          • Pre-Processor
          • Post-Processor
          • Listener
        • Assertion
        • Timer
        • Configuration Element
        • Pre-Processor
        • Post-Processor
        • Listener
      • Sampler
      • Assertion
      • Timer
      • Configuration Element
      • Pre-Processor
      • Post-Processor
      • Test Fragment
      • Listener
    • Assertion
    • Timer
    • Configuration Element
    • Pre Processor
    • Post Processor
    • Listener
    • Test Fragment
    • Non-Test Element

如上所述,只有Test PlanThread GroupControllerSampler可以嵌套其他對象,而Assertion,Timer,Configuration Element,Pre-Processor,Post-Processor,Listener,Test Fragment和Non-Test Element不能再嵌套子對象。
實際上,在JMeter圖形化界面中編輯測試計划時,指定對象下是否可以再嵌套子對象在操作菜單中就做了限制。

如下圖所示是一個在實際應用中可能會涉及到的對象嵌套關系配置示例:
JMeter Object

並且對象在運行時的執行順序如下:

  1. Configuration elements
  2. Pre-Processors
  3. Timers
  4. Sampler
  5. Post-Processors (unless SampleResult is null)
  6. Assertions (unless SampleResult is null)
  7. Listeners (unless SampleResult is null)

首先,定時器(Timers),斷言(Assertions),前置和后置處理器(Pre,Post-Processors)只有在應用它們的采樣器存在時才會運行;
其次,控制器(Controllers)和采樣器(Samplers)按照它們在測試計划配置樹中出現的順序執行;
最后,其他對象按照它們出現的范圍和類型順序執行,在一個特定類型的對象范圍內,按照它們在測試計划配置樹中出現的順序執行;

上述這一堆闡述重點在於理解各個測試對象的作用,以及在什么位置使用它們,至於對象的執行順序理解即可,不用死記硬背。
關於JMeter中的組件列表,詳見:Introduction

准備測試計划

JMeter的測試計划有2種方式生成:

  1. 手動編寫
  2. 錄制腳本

最佳實踐是針對不同的場景選擇對應的測試計划生成方式,比如:對於接口測試使用手動編寫可能更加合適,而對於網頁的測試,使用錄制腳本的方式會更加方便。

編寫測試計划

在GUI模式下編輯測試計划時,關鍵在於理解清楚JMeter中涉及的配置對象的作用,在此基礎上就可以借助圖形化界面設計測試計划並將其保存為一個腳本文件。
具體的測試計划編寫可以參考官方的一個Web測試計划示例:Building a Web Test Plan

設置“Ramp-up period”參數

在手動編寫測試計划時,值得注意點的是:線程池參數“Ramp-up period”值一定要設置合理,該參數的設置關系到測試啟動時是否會給服務器帶來非常大的沖擊甚至過載,或者是達不到性能測試的要求。
“Ramp-up period”參數的含義是設置一個時長(單位:秒),使得在Thread Group中設置的線程根據該時長逐步啟動。
舉例說明:
(1)在Thread Group中設置線程數為10,Ramp-up period參數設置為100s,JMeter將會在100s內逐步啟動10個線程,也就是說,每個線程的啟動間隔為10s(100s/10),可能最后一個線程啟動的時候第一個線程已經結束。
(2)在Thread Group中設置線程數為100,Ramp-up period參數設置為10s,每個線程的啟動間隔為0.1s(10s/100),可能在測試剛啟動時給服務器產生很大的負載。

綜上所述,Ramp-up period參數值不能設置太大,也不能設置太小,JMeter官方文檔的解釋是:可以將該參數值與線程數設置為相同,或者比線程數略大或稍小即可。
根據經驗來講,一般需要將Ramp-up period參數值設置比線程數略小更加合適。

其他一些關於Ramp-up period參數的設置技巧可以參考:

  1. 關於JMeter線程組中線程數,Ramp-Up Period,循環次數之間的設置概念
  2. JMeter技巧集錦

除了常見的Web測試,JMeter官方也給出了許多其他類型的測試計划示例,詳見:User's Manual

錄制測試腳本

錄制測試腳本就是通過工具自動生成測試測試的方式,在JMeter中這種方式更適合於Web頁面測試,但是實踐中發現,自動生成的測試用例也很難直接就能用於性能測試,還需要對測試用例做一些調整。
無論怎樣,有勝於無,通過腳本錄制方式還是能在一定程度上減少手動編輯測試計划的工作量。
在JMeter中錄制測試腳本有2種方式:

  1. 使用JMeter自帶的Http服務代理功能錄制,不同版本的JMter操作界面不同
  2. 借助於插件和第三方工具錄制,如:badboy工具,blazemeter插件等等

更多關於錄制JMeter測試腳本的實現可以參考如下博客:
1.Jmeter學習筆記五錄制腳本
2.JMeter中級篇-1-JMeter自帶的錄制功能舉例
3.利用Jmeter錄制腳本的兩種方法
4.錄制Jmeter腳本的N種方法
5.JMeter中級篇-2-Firefox錄制JMeter腳本的方案

執行性能測試

單機測試

通常來講,使用JMeter進行性能測試不會在GUI模式下進行,GUI圖形化界面通常只用來編寫測試計划。在GUI模式下調試好測試腳本之后,通過命令行的方式執行測試腳本。
關於JMeter的運行時參數詳見Running JMeter

在命令行執行性能測試的常用參數:
-n:非GUI模式
-t:指定測試計划文件路徑,可以是相對路徑或者絕對路徑
-l:輸出測試結果文件路徑,可以是相對路徑或者絕對路徑
-e:輸出測試報告
-o:測試報告保存目錄,可以是相對路徑或者絕對路徑

示例如下:

$ jmeter -n -t xxx.jmx -l ./yyy.jtl -e -o ./zzz

關於JMeter命令行參數詳見:CLI Mode

分布式測試

當在單機環境下使用JMeter無法模擬足夠的並發量時,可以使用分布式模式進行壓測。
在分布式模式下,存在一個控制節點Master,多個真正執行測試的從節點Slave,在Master上控制多個Slave進行壓力測試。
具體實現:

  1. 啟動Slave:在Slave節點啟動JMeter服務器模式,進入到JMETER_HOME/bin目錄下,執行:jmeter-server或jmeter-server.bat
  2. 啟動Master:
    (1)在Master節點上,進入到JMETER_HOME/bin目錄下,編輯jmeter.properties文件,將參數“remote_hosts”設置為以逗號分隔的Slave節點IP列表
    (2)在Master啟動Slave節點:jmeter -n -t xxx.jmx -r

關於分布式模式運行JMeter詳情參考:

  1. Apache JMeter Distributed Testing Step-by-step
  2. Server Mode

分析測試報告

JMeter從3.0之后就支持自動生成測試報告,只需要在執行測試時指定參數“-e”和“-o”即可,“-e”參數設置需要自動生成測試報告,“-o”參數指定測試報告目錄(該目錄不能已經存在)。
舉個例子:jmeter -n -t xxx.jmx -l ./yyy.jtl -e -o ./zzz
當然,還可以使用“-l”參數產生的測試結果文件生成測試報告:jmeter -g ./yyy.jtl -o ./zzz(這種報告生成方式非常有用,例如:運行JMeter壓測的機器性能不夠好時,在並發量很高的情況下自動生成測試報告會非常慢,此時可以在執行測試的時候只保存測試結果文件,然后將測試結果文件下載到性能更好的機器上再通過命令行的方式手動生成測試報告)。
關於JMeter生成測試報告還可以參考如下文章:
1.JMeter-自動生成測試報告
2.Generating Report Dashboard

性能測試中,我們最關心的指標是吞吐量和響應時間,在JMeter生成的測試報告中,已經非常人性化地展示了這些指標。

APDEX

這是由APDEX公司推出的表示應用程序性能滿意度的指標,值范圍為:0-1,因此,滿意度越接近1說明應用程序的性能越好。
在實際應用中,這個指標僅僅只能作為應用程序性能的一個非常粗略的判斷依據,因為在性能測試過程中還要考察響應時間的大小。比如:在一次壓測過程中所有請求都得到了響應,此時滿意度可能為0.99,但是99%的請求響應時間為1分鍾,這顯然是不可接受的。

響應時間和吞吐量統計

在JMeter生成的測試報告中有一個關於響應時間和吞吐量的統計報告,如下圖所示:
JMeter Statistics

首先,需要關注的是99%的請求響應時間(99th pct)統計,會把所有請求的響應時間做統計對比,通過該指標值可以非常明確地知道接口性能是否達標,如果響應時間不滿足要求,則需要考慮是否進行優化。
其次,當響應時間符合預期時還可以看到接口的吞吐量(Throughput),即:每秒請求數。

測試結果詳細報表

在JMeter性能測試報告中,關於響應時間和吞吐量的統計概要也只是一個非常粗略的參考指標,這個統計數據會受到測試用例在啟動和結束時的干擾,更加詳細和准確的統計結果應該查看圖形化的報表,非常直觀。

  1. Response Times Over Time:響應時間
  2. Active Threads Over Time:並發線程數
  3. Transactions Per Second:每秒事務數,可以理解為每秒請求數
  4. Response Time Vs Request:響應時間與請求數的對比
  5. Response Time Percentiles:響應時間百分比
  6. Response Time Distribution:響應時間分布

關於測試結果統計報表的解讀可以參考:JMeter-自動生成測試報告

常用插件及擴展

JMeter自帶的功能基本可以完成一些常見的性能測試任務,如果需要實現一些功能更加強大的測試,可以通過插件的方式進行擴展。
JMeter安裝插件有2種方式:
(1)通過插件管理器下載,實際上JMeter的插件管理器本身也是一個插件,詳見:https://jmeter-plugins.org/install/Install/
(2)手動下載,將插件包下載到$JMETER_HOME/lib/ext目錄,重啟JMeter即可。

1.Concurrency Thread Group

相比起JMeter自帶的Thread Group,該插件可以模擬更加真實的用戶並發,也可以很方便地對壓測時間進行設置。

2.HTTP Raw Request

功能比JMeter自帶的Http Request有增強和優化。

3.Raw Data Source

支持從文件中讀取數據,這樣可以方便造一些壓測需要的數據。

4.Transaction Throughput vs Threads

查看線程數與吞吐量的對比關系,可以非常直觀地看到系統性能隨着並發數的提高而產生的變化。

更多JMeter插件可以從JMeter Plugins下載。
除了豐富的插件,更多關於JMeter的最佳實踐可以參考:Best Practices
關於對JMeter的擴展,詳見:How to write a plugin for JMeter

Q&A

Q1: java.net.NoRouteToHostException: Cannot assign requested address

原因: 由於linux分配的客戶端連接端口用盡,無法建立socket連接所致,雖然socket正常關閉,但是端口不是立即釋放,而是處於 TIME_WAIT 狀態,默認等待60s后釋放。
查看linux支持的客戶端連接端口范圍,也就是28232個端口。cat /proc/sys/net/ipv4/ip_local_port_range,端口范圍:32768 - 61000

解決:
1.調低端口釋放后的等待時間,默認為60s,修改為15~30s。echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout
2.修改tcp/ip協議配置,通過配置/proc/sys/net/ipv4/tcp_tw_reuse,默認為0,修改為1,釋放TIME_WAIT端口給新連接使用:echo 1 > /proc/sys/net/ipv4/tcp_tw_reuse
3.修改tcp/ip協議配置,快速回收socket資源,默認為0,修改為1。echo 1 > /proc/sys/net/ipv4/tcp_tw_recycle

即總共需要執行如下命令:

$ echo 1 > /proc/sys/net/ipv4/tcp_tw_reuse
$ echo 1 > /proc/sys/net/ipv4/tcp_tw_recycle
$ echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout

另外,如果非root用戶執行上述命令時可能會遇到權限錯誤:

$ echo 1 > /proc/sys/net/ipv4/tcp_tw_reuse
bash: /proc/sys/net/ipv4/tcp_tw_reuse: Permission denied

甚至在命令之前加上sudo再執行也依然報錯:

$ sudo echo 1 > /proc/sys/net/ipv4/tcp_tw_reuse
bash: /proc/sys/net/ipv4/tcp_tw_reuse: Permission denied

此時應該通過另外的方式執行:

$ sudo bash -c 'echo 1 > /proc/sys/net/ipv4/tcp_tw_reuse'
$ sudo bash -c 'echo 1 > /proc/sys/net/ipv4/tcp_tw_recycle'
$ sudo bash -c 'echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout'

Q2: 使用JMeter發送POST請求時中文參數在服務器端接收到時為亂碼

解決: 在Jmeter中設置“Content-encoding”為:utf-8 。

【參考】
http://www.cnblogs.com/fnng/archive/2012/12/22/2829479.html JMeter基礎之一 一個簡單的性能測試
https://www.testwo.com/article/357 使用JMeter進行負載測試——終極指南
http://www.cnblogs.com/qmfsun/p/6381767.html JMeter執行壓測輸出HTML圖形化報表(二)
https://my.oschina.net/ydsakyclguozi/blog/536416 Jmeter中的幾個重要測試指標釋義
https://moonbingbing.gitbooks.io/openresty-best-practices/flame_graph.html 火焰圖
https://my.oschina.net/shichangcheng/blog/1560864 JMeter 進行壓力測試
https://blog.csdn.net/wwq_1111/article/details/59512546 JMeter壓力測試遇到的問題匯總
https://www.infoq.cn/article/k9kx0RxEbhht*iluT9iV 推薦幾款常用的性能測試工具
https://www.edureka.co/blog/what-is-software-testing/ 涉及軟件測試的文章博客
http://blog.csdn.net/lzqinfen/article/details/46326281 JMeter報錯the target server failed to respond--JMeter的坑
https://www.jianshu.com/p/130c7fddeddf Jmeter-使用Stepping Thread Group插件來設置負載場景
http://www.cnblogs.com/YatHo/p/6092599.html jmeter壓力測試報告 - DEMO


免責聲明!

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



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