性能測試是任何分佈式或Web應用程序測試計劃的重要組成部分。在計劃和開發週期中進行性能評價,能夠保證交付給客戶的應用程序知足客戶對於高負載、可用性和可伸縮性的要求。提早肯定軟件的負載限制能夠爲適當地進行系統配置提供幫助,從而避免出現意料以外的故障。系統性能分析中要處理的幾個問題是:系統或服務器可否處理數百個或數千個客戶端的同時請求,以及系統能夠處理請求的頻率。這種類型的測試不但提供了系統響應時間的絕對度量值,並且針對服務器的迴歸測試和應用程序代碼,檢查服務器的響應是否和預期結果相匹配,併爲不一樣供應商的中間件解決方案的評價和比較提供幫助。
Apache JMeter——Apache的性能測試框架,已經普遍地做爲Web應用程序的性能測試工具。它能夠用於在模擬重負載的條件下分析整個服務器性能。該軟件提供了FTP和HTTP請求功能和可擴展自定義腳本功能。本文闡述了Jmeter可用於對Web services進行負載測試的緣由。咱們特別經過在BEA WebLogic Server 9.0中配置一個簡單的Web Services來進行說明。示例測試計劃闡述了測試計劃的建立、線程組、循環和Web Services請求。咱們還討論瞭如何測量數據,並經過隨附的JMeter圖表對圖形工具中所顯示的結果進行了說明。
JMeter
Apache JMeter是能夠對利用HTTP或FTP服務器的應用程序進行測試的工具。它是基於Java的,經過所提供的API它還具備高度可擴展性。典型的JMeter測試包括建立循環和線程組。循環使用預設的延遲來模擬對服務器的連續請求。線程組是爲模擬併發負載而設計的。JMeter提供了用戶界面。它還公開了API,用戶能夠從Java應用程序來運行基於JMeter的測試。爲了在JMeter中建立負載測試,須要構建測試計劃。在實際操做中,Jmeter須要執行一系列的操做。最簡單的測試計劃一般包括下列元件:
線程組——這些元件用於指定運行的線程數和等候週期。每一個線程模擬一個用戶,而等候週期用於指定建立所有線程的時間。例如,線程數爲5,等候時間爲10秒,則建立每一個線程之間的時間間隔爲2秒。循環數定義了線程的運行時間。使用調度器,還能夠設置運行的起始時間。
取樣器——對於服務器HTTP、FTP或LDAP請求,這些元件是可配置請求。該教程僅側重於Web Services請求。
監聽器——這些元件用於請求數據的後期處理。例如,能夠將數據保存到文件或用圖表來講明結果。此時JMeter圖表並無提供許多配置選項;然而它是可擴展的,它始終能夠添加額外的可視化效果或數據處理模塊。
Apache JMeter網站給出了關於可用元件的詳細說明。在某些狀況下,若是可用元件不適合特定的測試,開發人員可經過在安裝Jmeter的\lib\ext\目錄中放置jar文件來編寫他/她本身的腳本或Java類,並將其嵌入測試計劃。
本文中咱們使用的是版本是JMeter 2.1。從 Web 站點 下載可執行二進制文件,將其解壓縮,而後應用程序便可在Windows或Unix平臺中使用。若是是在Windows操做系統中工做,要轉到bin文件夾用jmeter.bat 或jmeterw.bat啓動應用程序。
建立負載測試
使用Jmeter的負載測試功能,能夠在服務器上產生高負載並肯定其容量和限制。注意:若要使用Web services樣本,須要有可用的mail.jar和activation.jar,它們可從Sun Microsystems中獲取。因爲受權限制,Apache沒有分發這些庫。下載這兩個jar文件以後,將它們放入Java classpath或安裝Jmeter的lib目錄中。
如今,右鍵單擊Test Plan並添加Thread Group和Loop Controller。咱們使用這兩個元件來設置模擬的併發用戶數和測試持續時間。在樹狀結構的Loop Controller下面,添加「WebService (SOAP) Request」和Graph,如圖2所示。若是不能向測試計劃添加WebService請求,則多是路徑中沒有mail.jar或activation.jar。
鍵入線程數、等候週期和循環數。在本教程中咱們分別使用五、10和100。將循環控制器計數設置爲1。若是配置了Web Services的WebLogic Server仍然沒有運行,請手動啓動它或從WebLogic Workshop中啓動。
配置負載測試
咱們須要對發送到服務器的SOAP請求參數進行設置。若是指向WSDL文件的連接(URL)可用,將該連接粘貼到WSDL URL字段並單擊Load WSDL。可用的方法將顯示在Web Methods組合框中。接下來,須要單擊Configure以便填充Server Name或IP、Port Number、Path和SOAPAction。
若是沒有可用的WSDL連接,也能夠手動鍵入服務器名稱、端口號、路徑和SOAP操做的值。最後一步,在SOAP/XML-RPC Data區域填寫SOAP請求。用戶也能夠經過SOAP XML Data選項用File從文件中加載。
輸入Web Services請求對話框中的全部字段以後,單擊Ctrl+S保存JMeter項目。爲了使數據可視化,咱們添加了圖表元件「Graph results」和「Spline Visualizer」。此外,咱們也能夠經過添加「Save responses to a file」元件將響應發送到文件;這在檢查SOAP響應錯誤時頗有用。爲了模擬更真實的客戶端請求順序,咱們在樹中插入了定時器元件——「Gaussian Random timer」。執行該操做以後,客戶端的請求的分佈更加混亂,將會以隨機方式而不是以相等的時間間隔來點擊服務器。咱們將Gaussian隨機時間設置爲偏離100ms,恆定延遲偏移量爲300ms.
運行負載測試
用戶能夠經過單擊Ctrl+R運行負載測試,或者從菜單中選擇Run並單擊Start運行負載測試。單擊圖形元件,將會看到圖表被填充,數據表明對服務器的請求
說明測試結果的圖表。線程數=5,等候時間=10,循環數=100。循環控制器設置爲1。
咱們選擇在圖表中顯示三個參數——吞吐量(綠線)、中間值(紫線)和平均值(藍線)。咱們對測試參數進行修改。爲了模擬服務器上的較高負載,咱們將線程數提升到10和50並比較服務器的響應時間。再次單擊Start並觀查圖表中顯示的結果;參見圖5和圖6。
說明測試結果的圖表。線程數=10,等候時間=5,循環數=100,循環控制器設置爲1。
說明測試結果的圖表。線程數=50,等候時間=5,循環數=20,循環控制器設置爲1
圖表底部參數的含義以下:
• 吞吐量是服務器每分鐘處理的請求數。
• 平均值是總運行時間除以發送到服務器的請求數。
• 中間值是表明時間的數字,有一半的服務器響應時間低於該值而另外一半高於該值。
• 偏離表示服務器響應時間變化、離散程度測量值的大小,或者,換句話說,就是數據的分佈。
• 最後的樣本就是最後完成的請求。
只要觀察這三次運行及它們的相應圖表,咱們就能夠獲得下列有價值的結果:
響應時間很明顯地隨着線程的增長而增長。若要繼續進行測試,咱們能夠更改線程數、等候週期和循環數。注意:咱們沒有更改或調整服務器的配置。WebLogic Server 9.0中有一個可自動配置的線程池,其配置範圍受到限制(請參閱Naresh Revanuru撰寫的 Workload Management in WebLogic Server 9.0 ,Dev2Dev),上表說明客戶端數量的增加對服務器響應時間的影響是非線性的。實際上,將這個數字提升兩倍或十倍不會產生明顯的影響!然而,使用接近或超過默認服務器限制的線程數來運行同一個試驗時應引發注意。爲了檢驗從服務器收到的響應是真實的SOAP響應而不是HTTP錯誤,咱們觀察下列輸出文件的內容。這是符合上面要求的SOAP響應:
<soapenv:Envelope
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/>
<soapenv:Body>
<m:calculateAreaResponse xmlns:m="http://myservice">
<m:return>12</m:return>
</m:calculateAreaResponse>
</soapenv:Body>
</soapenv:Envelope>
爲了使測試結果更加可視化,向計劃中添加Spline Visualizer,它緊靠着Graph Results。Spline Visualizer提供了關於全部樣本次數的視圖。它用分段插入功能繪製出一條連續的線,在繪製時跨越10個點,每一個點表明10﹪的樣本。在樣條圖表中用直線取代鏈接點,提供了基於多項式近似算法的平滑分佈視圖。
Multiple JMeters
JMeter還具備一項十分有用的Remote Start功能,它容許用戶從多臺機器啓動JMeter測試。客戶端主機地址能夠輸入到位於bin文件夾下的「jmeter.properties」文件中。找到remote_hosts屬性並在那裏添加遠程主機名稱,使用逗號進行分隔。從新啓動Jmeter,在Run菜單中單擊Remote Start或Remote Start All。某些Web和應用程序服務器可連續處理同一個IP地址的多個請求以及並行處理不一樣IP地址的請求,所以,對於請求來自不一樣的機器或將測試負載分佈到幾個客戶端顯得十分關鍵的狀況,可使用該選項來執行操做。
其餘功能
前面已經提到,Jmeter包含HTTP、FTP和 LDAP取樣器。建立這些請求是一項簡單的任務,Jmeter用戶手冊中做了詳細說明;它一般包括建立Thread Group、添加取樣器、定時器和監聽器。下面咱們介紹一些有關這些標準取樣器以外的、可能須要一些非標準配置步驟的功能。
腳本
特別支持Java請求和BeanShell腳本的自定義測試和腳本是JMeter的另外一個功能,它爲負載測試開發人員提供了更大的靈活性。咱們能夠建立腳本化測試並將其做爲一個Java類進行編譯,而後將其傳遞給JMeter運行。爲了使用BeanShell腳本功能,須要下載BeanShell jar並將其放置在/lib目錄下面,以便JMeter在運行時能夠選取它。用戶可使用Java取樣器中的beanshell API,或者建立BeanShell取樣器,由它讀取文件中的腳本或處理文本框中所鍵入的命令。下面的代碼樣本說明了添加到HTTP取樣器中的BeanShell斷言。用戶能夠對基於HTTP請求的響應的測試執行過程進行分析和控制。一個好的方案應該建立具備線程組的測試計劃,並在計劃的時間循環啓動負載測試。請求將點擊Web服務器並得到其響應。
print("HTTP return code is:" + ResponseCode);
print("HTTP return message is:" + ResponseMessage);
if (SampleResult.isSuccessful())
{
print("Success");
SampleResult.setStopTest(true);
SampleResult.setStopThread(true);
}
響應可用添加到測試計劃的BeanShell斷言進行記錄,它緊靠着HTTP取樣器,若是Web服務器響應與某個條件相匹配,也就是說,若是成功或包含了預期的字符串,則腳本會中止測試或線程,不然將繼續執行。
JMS應用程序
爲了使用JMeter對JMS應用程序進行負載測試,要下載ActiveMQ jar並將其複製到/lib目錄。根據前面的測試,咱們首先建立線程組,並添加JMS Point-to-Point樣本。JMS Point-to-Point對話框須要填寫下列參數:QueueConnection Factory、JNDI Name Request隊列和JNDI Name Receive隊列。例如,咱們可使用WebLogic示例服務器上安裝的JMS模塊中的參數;在這種狀況下,它們爲weblogic.examples.jms.QueueConnectionFactory和weblogic.examples.jms.exampleQueue。咱們也能夠建立自定義的JMS鏈接工廠和隊列。對於WebLogic服務器,咱們還須要添加 weblogic.jndi.WLInitialContextFactory做爲初始Context Factory值和Provider URL,一般狀況下,其形式爲:t3://hostname:7001,例如:t3://localhost:7001。
自定義取樣器
許多測試人員早晚會面臨下面這個問題:假如必需要建立測試計劃,而JMeter沒有提供必需的取樣器或監聽器。例如,用戶須要測試Enterprise JavaBeans應用程序。用戶仍然可使用JMeter的Java Request,它實質上是Java類,能夠向其添加須要的任何邏輯。咱們建立一個樣本Java取樣器,它將嚮應用程序服務器發送請求並調用會話bean。首先,咱們建立package mytest和稱爲JBTest.javaJava的Java類:
package mytest;
import mybeans.LoginBeanRemoteHome;
import mybeans.LoginBeanRemote;
import java.io.Serializable;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.rmi.PortableRemoteObject;
import java.util.Hashtable;
import javax.naming.*;
import javax.rmi.*;
import java.rmi.RemoteException;
import javax.ejb.CreateException;
import org.apache.jmeter.protocol.java.sampler.*;
import org.apache.jmeter.config.Arguments;
import org.apache.jmeter.protocol.java.sampler.AbstractJavaSamplerClient;
import org.apache.jmeter.protocol.java.sampler.JavaSamplerContext;
import org.apache.jmeter.samplers.SampleResult;
import org.apache.jmeter.testelement.TestElement;
public class EJBTest implements JavaSamplerClient ,
Serializable {
public EJBTest() {
}
public void setupTest(JavaSamplerContext context) {
}
public Arguments getDefaultParameters() {
Arguments params = new Arguments();
return params;
}
public SampleResult runTest(JavaSamplerContext context) {
SampleResult results = new SampleResult();
try{
Context env = getInitialContext("t3://localhost:7001");
LoginBeanRemoteHome home = (LoginBeanRemoteHome)
PortableRemoteObject.narrow(
env.lookup("ejb.LoginBeanRemoteHome"),
LoginBeanRemoteHome.class);
LoginBeanRemote bean = (LoginBeanRemote) home.create();
bean.login("TestUser","TestPassword");
results.setSuccessful(true);
}
catch (NamingException ne){
ne.printStackTrace();
results.setSuccessful(false);
}
catch (RemoteException re){
re.printStackTrace();
results.setSuccessful(false);
}
catch (CreateException ce){
ce.printStackTrace();
results.setSuccessful(false);
}
return results;
}
static Context getInitialContext(String url) throws NamingException {
Hashtable env = new Hashtable<String,String>();
env.put(Context.INITIAL_CONTEXT_FACTORY,
"weblogic.jndi.WLInitialContextFactory");
env.put(Context.PROVIDER_URL, url);
return new InitialContext(env);
}
public void teardownTest(JavaSamplerContext context) {
}
}
爲了使用該代碼,要對它進行編譯以建立jar文件myEJBTest.jar,將jar複製到JMeter classpath(如lib目錄),或者將classpath位置添加到jmeter.properties 文件——其形式爲:
user.classpath=d:\jakarta-jmeter-2.1.1\lib\ext\myEJBTest.jar
從新啓動JMeter,向測試計劃添加Java Request元件,並從下拉菜單中選擇mytest.EJBTest。缺省狀況下,JMeter提供的是「SleepTest」和「JavaTest」。如今,咱們能夠向測試計劃添加線程組、循環和監聽器並運行測試計劃。
測試數據庫
Jmeter所支持的另外一個功能是評價數據庫服務器的性能。用戶可使用軟件提供的JDBC Request元件,也可使用腳本或Java類來建立本身的測試。例如,使用一些與前面相似的示例能夠測試存儲過程的調用。許多數據庫優化技術均可以使用,包括使用特定供應商優化(如查詢的並行處理),使用聯結或索引。此外,當用多個boolean評價建立查詢時,數據組織知識頗有用。在處理大量數據時,應用程序中的數據庫和查詢優化是特別關鍵的,JMeter是一個能夠在這類評價中提供某些評測的工具。例如,能夠在數據或查詢優化先後執行性能或負載測試並對結果進行比較。
咱們經過建立MySQL實例的測試計劃來演示樣本數據庫性能測量計劃是如何工做的。首先,從MySQL網站下載JDBC驅動程序,並複製到/lib目錄以便JMeter能夠訪問數據庫。如今啓動JMeter,建立線程組,並設置循環數和相應的線程數。添加JDBC Connection Configuration、JDBC Query Defaults和JDBC Request元件。在這些對話框中,咱們須要配置數據庫鏈接和查詢。輸入數據庫URL值,它們的形式相似於:jdbc:mysql://hostname/databaseName,而後爲JDBC Driver Class輸入com.mysql.jdbc.Driver。針對這個試驗,咱們建立了數據庫customers,它帶有包含下列三個字段的customer表格:名稱、地址和賬戶。在Query框中鍵入查詢,例如,從客戶中選擇名稱。
爲了使結果可視化,能夠添加帶有響應時間的圖表,或者,若是要檢驗響應是否匹配特定模式,能夠添加響應斷言。例如,在Response Assertion中添加文本模式「Smith」。在Assertion Result窗口將顯示如「Test failed, text expected to contain /Smith/」之類的錯誤,或者,若是因爲設置錯誤而沒有鏈接,則顯示「Response was null」。若是測試成功,將不返回任何內容。除了圖表和斷言監聽器,咱們還可使用Aggregate Report,它以表格的形式顯示樣本數、平均值、中間值和吞吐量的摘要。
結束語
使用JMeter現有的功能和它所提供的用戶界面,能夠模擬5個併發線程,以10和5 ms延遲點擊服務器。本教程說明了該工具可以用於對Web services的響應時間進行測量的原理。例如,利用JMeter腳本,能夠查找客戶端的身份認證和受權。所測試的應用程序服務器和JMeter客戶端都本地安裝在同一個工做站,然而一樣的設置也能夠用於測試遠程服務器。
所獲得的結果和圖表還不能提供有價值的性能報告;它們只能說明WebLogic Server對Web Services請求響應時間的簡單分佈。要了解是否實現了優化,應當在優化先後針對兩個不一樣的服務器,或針對客戶端線程變量數的不一樣負載來運行相同的負載測試。換句話說,只有比較的結果才具備實用價值,它可以幫助瞭解服務器性能,進而基於這些評測作出判斷。