官方文檔:javascript
http://jmeter.apache.org/usermanual/best-practices.htmlphp
翻譯:html
16.最佳實踐java
16.1 始終使用最新版本的JMetershell
JMeter的性能正在不斷提升,所以強烈建議用戶使用最新版本。
確保始終閱讀更改列表以瞭解新的改進和組件。必定要避免使用與最新版本相差3個版本以上的版本。apache
16.2 使用正確的線程數瀏覽器
您的硬件功能以及測試計劃設計都會影響您可使用JMeter有效運行的線程數。這個數字還取決於服務器的速度(更快的服務器使JMeter運行更好,由於它能夠更快地返回響應)。與任何負載測試工具同樣,若是您沒有正確調整線程數,您將面臨「Coordinated Omission(協調省略?)」問題,這可能會給您錯誤或不許確的結果。若是須要進行大規模負載測試,請考慮使用分佈式模式(或不使用)在多臺計算機上運行多個非GUI JMeter實例。使用分佈式模式時,結果文件將組合在Controller節點上,若是使用多個自發實例,則能夠組合樣本結果文件以進行後續分析。可使用JavaTest採樣器來測試JMeter在給定平臺上的執行方式。它能夠在沒有任何網絡訪問的狀況下測試獲得最大吞吐量。緩存
JMeter能夠選擇延遲線程建立,直到線程開始採樣。即在任何線程組延遲和線程自己的加速時間以後。這容許很是大的線程總數,前提是不會有太多併發的線程。安全
16.3 Cookie管理器的放置位置服務器
有關信息,請參閱構建Web測試。
16.4 受權管理器的放置位置
有關信息,請參閱構建高級Web測試。
16.5 使用HTTP代理服務器(HTTP(S) Test Script Recorder)
有關HTTP代理服務器的詳細信息,請參閱HTTP代理服務器。最重要的是過濾掉您不感興趣的全部請求。例如,錄製圖像請求沒有意義(可讓JMeter下載頁面上的全部圖像 - 請參閱HTTP請求)。這些只會使您的測試計劃變得混亂。最有可能的是,全部文件都有一個擴展名,例如.jsp,.asp,.php,.html等。這些你應該經過輸入「.*\.jsp」做爲「包含模式」來「包含」。
或者,您能夠輸入「.*\.gif」做爲「排除模式」來排除圖像。根據您的應用程序,這多是(也可能不是)更好的方法。您還可能要排除樣式表,javascript文件或其餘包含的文件。經過每次去除一些非必須的請求並從新開始測試您的設置,以最終確認您正在錄製您想要的內容。
HTTP代理服務器指望在其下面找到一個帶有錄製控制器的ThreadGroup元素,它將錄製HTTP請求。這樣能夠方便地將全部取樣器打包在一個控制器下,並給該控制器取一個名字來描述測試用例。
如今,您能夠根據步驟來完成測試用例了。若是您沒有預約義的測試用例,請使用JMeter來錄製您的操做以定義測試用例。完成一系列明確的步驟後,將整個測試用例保存在適當命名的文件中。而後,擦拭乾淨並開始一個新的測試用例。經過這樣作,您能夠快速記錄大量的測試用例「粗略草稿」。
HTTP代理服務器最有用的功能之一是您能夠從錄製的samples中抽象出某些常見元素。經過在「測試計劃」或「用戶自定義變量」元素中定義一些用戶定義的變量,您可讓JMeter自動替換錄製的sample中的值。例如,若是您正在服務器「xxx.example.com」上測試應用程序,那麼您能夠定義一個名爲「server」的變量,其值爲「xxx.example.com」,而且能夠在您錄製的任何sample中找到該值將替換爲「${server}」。
請注意,匹配區分大小寫。
若是JMeter沒有錄製任何samples,請檢查瀏覽器是否確實在使用代理。若是瀏覽器在JMeter未運行的狀況下也能正常運行,說明瀏覽器沒有在使用代理。某些瀏覽器會忽略localhost或127.0.0.1的代理設置,嘗試使用本地主機名或IP。
錯誤「unknown_ca」可能意味着您正在嘗試錄製HTTPS請求,而且瀏覽器還沒有接受JMeter代理服務器證書。
16.6 用戶變量
某些測試計劃須要爲不一樣的用戶/線程使用不一樣的值。例如,您可能但願測試須要爲每一個用戶進行惟一登陸的序列。使用JMeter提供的工具很容易實現。
例如:
建立一個包含用逗號分隔的用戶名和密碼的文本文件。將它放在與測試計劃相同的目錄中。
將CSV DataSet configuration添加到測試計劃中。將變量命名爲USER和PASS。
在適當的取樣器上用${USER}替換登陸名,用${PASS}替換密碼。
CSV Data Set element將爲每一個線程讀取一個新行。
16.7 減小資源需求
關於減小資源使用的一些建議。
使用非GUI模式:jmeter -n -t test.jmx -l test.jtl
使用盡量少的監聽器:若是使用上面的-l標誌,則能夠刪除或禁用它們。
在負載測試期間,請勿使用「查看結果樹」或「View Results in Table」監聽器,僅在腳本編寫階段使用它們來調試腳本。
在循環中對於類似的請求最好使用同一個採樣器並使用變量(CSV Data Set)來區分,而不是使用多個類似的取樣器。 [使用控制器在這裏沒有幫助,由於它會將文件中的全部測試元素添加到測試計劃中。]
不要使用功能模式。
使用CSV輸出而不是XML。
僅保存您須要的數據。
使用盡量少的斷言。
使用性能最佳的腳本語言(參見JSR223部分)。
若是您的測試須要大量數據 - 特別是若是須要隨機化 - 請在能夠用 CSV Dataset 讀取的文件中建立測試數據。這能夠避免在運行時浪費資源。
16.8 BeanShell服務器
BeanShell interpreter有一個很是有用的功能 - 它能夠充當服務器,能夠經過telnet或http訪問。
沒有安全性。任何能夠鏈接到端口的人均可以發出任何BeanShell命令。這些能夠提供對JMeter應用程序和主機的無限制訪問。除非端口受到訪問保護(例如經過防火牆),不然不要啓用服務器。
若是您確實但願使用服務器,請在jmeter.properties中定義如下內容:
beanshell.server.port=9000 beanshell.server.file=../extras/startup.bsh
在上面的示例中,服務器將啓動,並將偵聽端口9000和9001。端口9000將用於http訪問,端口9001將用於telnet訪問。 startup.bsh文件將由服務器處理,可用於定義各類函數和設置變量。啓動文件定義了設置和打印JMeter和系統屬性的方法。這是您應該在JMeter控制檯中看到的內容:
Startup script running Startup script completed Httpd started on port: 9000 Session started on port: 9001
您可使用示例腳本(extras / remote.bsh)來測試服務器(看看它是如何工做的)。
在JMeter bin目錄中啓動它(若是從其餘地方運行,根據須要調整路徑),輸出應以下所示:
$ java -jar ../lib/bshclient.jar localhost 9000 ../extras/remote.bsh Connecting to BSH server on localhost:9000 Reading responses from server … BeanShell 2.0b5 - by Pat Niemeyer (pat@pat.net) bsh % remote.bsh starting user.home = C:\Documents and Settings\User user.dir = D:\eclipseworkspaces\main\JMeter_trunk\bin Setting property 'EXAMPLE' to '0'. Setting property 'EXAMPLE' to '1'. Setting property 'EXAMPLE' to '2'. Setting property 'EXAMPLE' to '3'. Setting property 'EXAMPLE' to '4'. Setting property 'EXAMPLE' to '5'. Setting property 'EXAMPLE' to '6'. Setting property 'EXAMPLE' to '7'. Setting property 'EXAMPLE' to '8'. Setting property 'EXAMPLE' to '9'. EXAMPLE = 9 remote.bsh ended bsh % … disconnected from server.
做爲一個實際示例,假設您在非GUI模式下運行了長時間的JMeter測試,而且您但願在測試期間的不一樣時間更改吞吐量。測試計劃應包括一個根據屬性(例如${__P(throughput)})來定義的Constant Throughput Timer。如下BeanShell命令可用於更改測試:
printprop("throughput"); curr = Integer.decode(args[0]); // Start value inc = Integer.decode(args[1]); // Increment end = Integer.decode(args[2]); // Final value secs = Integer.decode(args[3]); // Wait between changes while(curr <= end) { setprop("throughput",curr.toString()); // Needs to be a string here Thread.sleep(secs*1000); curr += inc; } printprop("throughput");
該腳本能夠存儲在一個文件中(例如throughput.bsh),並使用bshclient.jar發送到服務器。例如:
java -jar ../lib/bshclient.jar localhost 9000 throughput.bsh 70 5 100 60
16.9 BeanShell腳本
從JMeter 3.1開始,咱們建議從BeanShell切換到JSR223測試元素(有關更多詳細信息,請參閱下面的JSR223部分),並從__Beanshell函數切換到__groovy函數。
16.9.1 概述
每一個BeanShell測試元素都有本身的解釋器副本(對於每一個線程)。若是重複調用測試元素,例如在循環內,除非選擇「在每次調用以前重置bsh.Interpreter(Reset bsh.Interpreter before each call)」選項,不然解釋器將保留在調用之間。
一些長時間運行的測試可能會致使解釋器使用大量內存;若是是這種狀況,請嘗試使用重置選項。
您可使用命令行在JMeter外部測試BeanShell腳本:
$ java -cp bsh-xxx.jar[;other jars as needed] bsh.Interpreter file.bsh [parameters]
或者
$ java -cp bsh-xxx.jar bsh.Interpreter bsh% source("file.bsh"); bsh% exit(); // or use EOF key (e.g. ^Z or ^D)
16.9.2 共享變量
能夠在啓動(初始化)腳本中定義變量。除非使用重置選項,不然這些將在測試元素的調用中保留。
腳本還可使用「vars」變量的get()和put()方法訪問JMeter變量,例如:
vars.get("HOST"); vars.put("MSG","Successful");
get()和put()方法僅支持具備String值的變量,但也有getObject()和putObject()方法可取任意對象。 JMeter變量是線程的本地變量,但能夠被全部測試元素(不只僅是Beanshell)使用。
若是須要在線程之間共享變量,則可使用JMeter屬性:
import org.apache.jmeter.util.JMeterUtils; String value = JMeterUtils.getPropDefault("name",""); JMeterUtils.setProperty("name", "value");
示例.bshrc文件包含getprop()和setprop()方法的示例定義。
共享變量的另外一種可能方法是使用「bsh.shared」共享命名空間。例如:
if (bsh.shared.myObj == void){ // not yet defined, so create it: myObj = new AnyObject(); } bsh.shared.myObj.process();
它能夠在JMeter啓動文件中經過定義屬性「beanshell.init.file」來建立,而不是在test元素中建立對象。這隻處理一次。
16.10 在Groovy或Jexl3等中開發腳本函數
做爲函數編寫和測試腳本很是困難。可是JMeter有JSR223採樣器,可使用任何支持它的語言。咱們建議使用Apache Groovy或任何支持JSR223的Compilable接口的語言。
建立一個包含JSR223 Sampler和Tree View Listener的簡單測試計劃。對sampler腳本窗格中的腳本進行編碼,並經過運行測試對其進行測試。若是有任何錯誤,這些錯誤將顯示在Tree View和jmeter.log文件中。此外,運行腳本的結果將顯示爲響應。
一旦腳本正常工做,它就能夠做爲變量存儲在測試計劃中。而後可使用腳本變量來建立函數調用。例如,假設Groovy腳本存儲在變量RANDOM_NAME中。而後,函數調用能夠編碼爲${__groovy(${RANDOM_NAME})}。不須要在腳本中轉義任何逗號,由於在插入變量值以前函數調用已被解析。
16.11 參數化測試
一般,若是可以使用不一樣的設置重複運行同一個測試是有用的。例如,更改線程或循環的數量,或更改主機名。
一種方法是在測試計劃中定義一組變量,而後在測試元素中使用這些變量。例如,能夠定義變量LOOPS = 10,並將線程組中的變量稱爲$ {LOOPS}。要使用20個循環運行測試,只需更改測試計劃上的LOOPS變量的值。
若是您想在非GUI模式下運行大量測試,這很快就會變得乏味。對此的一個解決方案是根據屬性定義測試計劃變量,例如LOOPS=${__P(loops,10))}。這使用屬性「loops」的值,若是找不到屬性,則默認爲10。而後能夠在JMeter命令行上定義「loops」屬性:
jmeter … -Jloops=12 …
若是有許多屬性須要一塊兒更改,那麼實現此目的的一種方法是使用一組屬性文件。可使用-q命令行選項將相應的屬性文件傳遞給JMeter。
16.12 JSR223元素
對於密集負載測試,推薦的腳本語言是ScriptingEngine實現可編譯接口的語言。 Groovy腳本引擎實現了可編譯。可是,在JMeter 3.1發佈時,Beanshell和Javascript都沒有這樣作,所以建議不要使用它們進行密集負載測試。
注意:Beanshell實現了可編譯接口,但它還沒有編碼 - 該方法只會拋出異常。 JMeter爲這個bug作了明確的工做。
使用JSR 223元素時,建議檢查Cache編譯腳本(若是可用)屬性,以確保在基礎語言支持時緩存腳本編譯。在這種狀況下,請確保腳本不使用$ {varName}表示的任何變量,由於Jmeter只會獲取要$ {varName}變量的第一個值。而是使用:
vars.get("varName")
您也能夠將它們做爲參數傳遞給腳本並以這種方式使用它們。
16.13 在線程和線程組之間共享變量
變量是線程的本地變量,在一個線程中設置的變量不能在另外一個線程中讀取。這是設計的。對於可在測試開始前肯定的變量,請參閱參數化測試(上文)。若是在測試開始以前未知該值,則有多種選擇:
將變量存儲爲屬性 - 屬性對JMeter實例是全局的
將變量寫入文件並從新讀取
使用bsh.shared命名空間 - 見上文
編寫本身的Java類
16.14 管理屬性
當您須要修改jmeter屬性時,請確保不要修改jmeter.properties文件,而是從jmeter.properties複製該屬性並在user.properties文件中修改其值。
這樣作能夠簡化您遷移到下一版JMeter的過程。
請注意,在文檔中常常提到jmeter.properties,但這應理解爲「從jmeter.properties複製到user.properties要修改的屬性,並在後一個文件中執行此操做」。
user.properties文件取代jmeter.properties中定義的屬性。
16.15 不推薦使用的元素
建議不要使用已棄用的元素(在更改列表和組件引用中標記爲已刪除的元素)並遷移到新的建議元素(若是可用)或執行相同操做的新方法。從版本N的菜單中刪除不推薦使用的元素,但能夠經過修改user.properties文件中的not_in_menu屬性並從中刪除元素的完整類名來啓用遷移。請注意,版本N中的棄用元素將在版本N + 1中被刪除,所以請確保儘快中止使用它們。