JMeter 的安裝非常簡單,從官方網(wǎng)站上下載,解壓之后即可使用。運行命令在%JMETER_HOME%/bin 下,對于 Windows 用戶來說,命令是 jmeter.bat。運行前請檢查JMeter 的文檔,查看是否具備相關(guān)的運行條件。對于最新版,需要JDK的版本要求是JDK 1.4以上。
JMeter作用領(lǐng)域 JMeter可以用于測試靜態(tài)或者動態(tài)資源的性能(文件、Servlets、Perl腳本、java對象、數(shù)據(jù)庫和查詢、ftp服務(wù)器或者其他的資源)。JMeter用于模擬在服務(wù)器、網(wǎng)絡(luò)或者其他對象上附加高負載以測試他們提供服務(wù)的受壓能力,或者分析他們提供的服務(wù)在不同負載條件下的總性能情況。你可以用JMeter提供的圖形化界面分析性能指標或者在高負載情況下測試服務(wù)器/腳本/對象的行為。
接下來的章節(jié)里,作者將詳細的演示如何使用JMeter來測試Web應(yīng)用的完整過程。 2.1 測試環(huán)境 作者使用了Tomcat作為Web服務(wù)器進行測試,被測試的內(nèi)容是一個jsp文件和一個servlet,jsp文件調(diào)用JavaBean、打印相關(guān)信息,servlet接受用戶參數(shù)、調(diào)用javabean、輸出相關(guān)信息。詳細的內(nèi)容請參考作者提供的JMeter.war的內(nèi)容。
2.2 安裝啟動JMeter 下載JMeter的release版本,然后將下載的.zip文件解壓縮到C:/JMeter(后面的文章中將使用%JMeter%來引用這個目錄)目錄下。 現(xiàn)在,請使用%JMeter%/bin下面的jmeter.bat批處理文件來啟動JMeter的可視化界面,下面的工作都將在這個可視化界面界面上進行操作。下面的圖片是JMeter的可視化界面的屏幕截圖。
2.3 建立測試計劃(Test Plan) 測試計劃描述了執(zhí)行測試過程中JMeter的執(zhí)行過程和步驟,一個完整的測試計劃包括一個或者多個線程組(Thread Groups)、邏輯控制(Logic Controller)、實例產(chǎn)生控制器(Sample Generating Controllers)、偵聽器(Listener)、定時器(Timer)、比較(Assertions)、配置元素(Config Elements)。打開JMeter時,它已經(jīng)建立一個默認的測試計劃,一個JMeter應(yīng)用的實例只能建立或者打開一個測試計劃。 現(xiàn)在我們開始填充一個測試計劃的內(nèi)容,這個測試計劃向一個jsp文件和一個servlet發(fā)出請求,我們需要JMeter模擬五個請求者(也就是五個線程),每個請求者連續(xù)請求兩次,下面的章節(jié)介紹了詳細的操作步驟。 2.4 增加負載信息設(shè)置 這一步,我們將向測試計劃中增加相關(guān)負載設(shè)置,是Jmeter知道我們需要模擬五個請求者,每個請求者在測試過程中連續(xù)請求兩次。詳細步驟如下: 1. 選中可視化界面中左邊樹的Test Plan節(jié)點,單擊右鍵,選擇Add'Thread Group,界面右邊將會出現(xiàn)他的設(shè)置信息框。 2. Thread Group有三個和負載信息相關(guān)的參數(shù): 根據(jù)我們演示例子的設(shè)計,我們應(yīng)該將Number of Threads設(shè)置為5,Ramp-up period設(shè)置為0(也就是同時并發(fā)請求),不選中forever,在Loop Count后面的輸入框中輸入2,設(shè)置后的屏幕截圖如下: 圖二:設(shè)置好參數(shù)的Thread Group。 2.5 增加默認Http屬性(可選) 實際的測試工作往往是針對同一個服務(wù)器上Web應(yīng)用展開的,所以Jmeter提供了這樣一種設(shè)置, 在默認Http屬性設(shè)置需要被測試服務(wù)器的相關(guān)屬性,以后的http請求設(shè)置中就可以忽略這些相同參數(shù)的設(shè)置,減少設(shè)置參數(shù)錄入的時間。 我們這里將采用這種屬性。你可以通過下面的步驟來設(shè)置默認http屬性: 1. 選中可視化界面中左邊樹的Test Plan節(jié)點,單擊右鍵,選擇Add'config element'http request defaults,界面右邊將會出現(xiàn)他的設(shè)置信息框。 2. 默認http屬性的主要參數(shù)說明如下: 我們的測試計劃將針對本機的Web服務(wù)器上的Web應(yīng)用進行測試,所以protocal應(yīng)該是http,ip使用localhost,因為這個web應(yīng)用發(fā)布的context路徑是/jmeter,所以這里的path設(shè)置為/jmeter,因為使用Tomcat服務(wù)器,所以port number是8080。設(shè)置后的屏幕截圖如下: 2.6 增加Http請求 現(xiàn)在我們需要增加http請求了,他也是我們測試的內(nèi)容主體部分。你可以通過下面的步驟來增加性的http請求: 1. 選中可視化界面中左邊樹的Thread Group節(jié)點,單擊右鍵,選擇Add'sampler'http request,界面右邊將會出現(xiàn)他的設(shè)置信息框。 2. 他的參數(shù)和2.5中介紹的http屬性差不多,增加的屬性中有發(fā)送http時方法的選擇,你可以選擇為get或者post。 我們現(xiàn)在增加兩個http 請求,因為我們設(shè)置了默認的http屬性,所以和默認http屬性中相同的屬性不再重復(fù)設(shè)置。設(shè)置后的屏幕截圖如下: 圖四:設(shè)置好的jsp測試請求 2.7 增加Listener 增加listener是為了記錄測試信息并且可以使用Jmeter提供的可視化界面查看測試結(jié)果,里面有好幾種結(jié)果分析方式可供選擇,你可以根據(jù)自己習(xí)慣的分析方式選擇不同的結(jié)果顯示方式,我們這里使用表格的形式來查看和分析測試結(jié)果。你可以通過下面的步驟來增加listener: 1. 選中可視化界面中左邊樹的Test Plan節(jié)點,單擊右鍵,選擇Add'listener'view result in table,界面右邊將會出現(xiàn)他的設(shè)置信息和結(jié)果顯示框。 2. 你可以設(shè)置界面上面的filename屬性設(shè)置將測試結(jié)果保存到某個文件中界面下面將使用表格顯示測試結(jié)果,表格的第一列sampleno顯示請求執(zhí)行的順序和編號,url顯示請求發(fā)送的目標,sample-ms列顯示這個請求完成耗費的時間,最后的success列顯示改請求是否成功執(zhí)行。 界面的最下面你還可以看到一些統(tǒng)計信息,最關(guān)心的應(yīng)該是Average吧,也就是相應(yīng)的平均時間。 2.8 開始執(zhí)行測試計劃 現(xiàn)在你可以通過單擊菜單欄run -> Start開始執(zhí)行測試計劃了。下面這兩個圖是作者第一次、第二次執(zhí)行該測試計劃的結(jié)果圖: 圖六:第一次執(zhí)行后的結(jié)果顯示 大家可以看到第一次執(zhí)行時的幾個大時間值均來自于jsp request,這可以通過下面的理由進行解釋:jsp執(zhí)行前都需要被編譯成.class文件。所以第二次的結(jié)果才是正常的結(jié)果。 JMeter用于進行供能或者性能測試,通過使用JMeter提供的供能,我們可以可視化的制定測試計劃:包括規(guī)定使用什么樣的負載、測試什么內(nèi)容、傳入的參數(shù),同時,他提供了好多種圖形化的測試結(jié)果顯示方式,使我們能夠簡單的開始測試工作和分析測試結(jié)果。 本文中,作者根據(jù)自己的使用經(jīng)驗,詳細演示了如何使用JMeter來進行Web測試的全部過程,簡單的介紹了JMeter提供測試結(jié)果的圖形化顯示界面中相關(guān)參數(shù)的含義。希望能夠幫助大家學(xué)會使用JMeter的基本知識,同時,大家可以參考這個過程和JMeter的幫助文檔來實現(xiàn)對java對象、數(shù)據(jù)庫等的測試過程。 JMeter測試講解本文介紹了 JMeter 相關(guān)的基本概念。并以 JMeter 為例,介紹了使用它來完成最常用的三種類型服務(wù)器,即 Web 服務(wù)器、數(shù)據(jù)庫服務(wù)器和消息中間件,壓力測試的方法、步驟以及注意事項。 講到測試,人們腦海中首先浮現(xiàn)的就是針對軟件正確性的測試,即常說的功能測試。但是軟件僅僅只是功能正確是不夠的。在實際開發(fā)中,還有其它的非功能因素也起著決定性的因素,例如軟件的響應(yīng)速度。影響軟件響應(yīng)速度的因素有很多,有些是因為算法不夠高效;還有些可能受用戶并發(fā)數(shù)的影響。 在眾多類型的軟件測試中,壓力測試正是以軟件響應(yīng)速度為測試目標,尤其是針對在較短時間內(nèi)大量并發(fā)用戶的訪問時,軟件的抗壓能力。本文以 JMeter 為例,介紹了如何使用它來完成常用的壓力測試:Web 測試、數(shù)據(jù)庫測試和 JMS 測試。 JMeter 的主要測試組件總結(jié)如下: 1. 測試計劃是使用 JMeter 進行測試的起點,它是其它 JMeter 測試元件的容器。 2. 線程組代表一定數(shù)量的并發(fā)用戶,它可以用來模擬并發(fā)用戶發(fā)送請求。實際的請求內(nèi)容在Sampler中定義,它被線程組包含。 3. 監(jiān)聽器負責(zé)收集測試結(jié)果,同時也被告知了結(jié)果顯示的方式。 4. 邏輯控制器可以自定義JMeter發(fā)送請求的行為邏輯,它與Sampler結(jié)合使用可以模擬復(fù)雜的請求序列。 5. 斷言可以用來判斷請求響應(yīng)的結(jié)果是否如用戶所期望的。它可以用來隔離問題域,即在確保功能正確的前提下執(zhí)行壓力測試。這個限制對于有效的測試是非常有用的。 6. 配置元件維護Sampler需要的配置信息,并根據(jù)實際的需要會修改請求的內(nèi)容。 7. 前置處理器和后置處理器負責(zé)在生成請求之前和之后完成工作。前置處理器常常用來修改請求的設(shè)置,后置處理器則常常用來處理響應(yīng)的數(shù)據(jù)。 8. 定時器負責(zé)定義請求之間的延遲間隔。 JMeter的使用非常的容易,在 ONJava.com 上的文章 Using JMeter 提供了一個非常好的入門。 常用測試 壓力測試不同于功能測試,軟件的正確性并不是它的測試重點。它所看重的是軟件的執(zhí)行效率,尤其是短時間內(nèi)訪問用戶數(shù)爆炸性增長時軟件的響應(yīng)速度,壓力測試往往是在功能測試之后進行的。在實際的開發(fā)過程中,軟件潛在的效率瓶頸一般都是那些可能有多個用戶同時訪問的節(jié)點。 就目前 Java EE 的平臺下開發(fā)的軟件來說,這種節(jié)點通??赡苁牵篧eb 服務(wù)器、數(shù)據(jù)庫服務(wù)器和 JMS 服務(wù)器。它們都是請求主要發(fā)生的地點,請求頻率較其它的節(jié)點要高,而且處于請求序列的關(guān)鍵路徑之上。如果它們效率無法提高的話,對于整個軟件的效率有致命的影響。而且在這些節(jié)點上一般都會發(fā)生較大規(guī)模的數(shù)據(jù)交換,有時其中還包含有業(yè)務(wù)邏輯處理,它們正是在進行壓力測試時首先需要考慮的。 本文以這三種節(jié)點為例,介紹如何使用 JMeter 來完成針對于它們的壓力測試。 Web 服務(wù)器 對于大多數(shù)的項目來說,并不會自行開發(fā)一個Web服務(wù)器,因此Web服務(wù)器壓力測試的對象實際就是--發(fā)布到Web服務(wù)器中的軟件。最簡單的Web測試計劃只需要三個 JMeter 的測試元件,如下圖: 其中:
這種設(shè)置對于包含了安全機制的 web 應(yīng)用是不夠的,典型的 web 應(yīng)用一般都會: 1. 有一個登錄頁,它是整個應(yīng)用的入口。當(dāng)用戶登錄之后,應(yīng)用會將用戶相關(guān)的安全信息放到 session 中。 2. 有一個 filter,它攔截請求,檢查每個請求相關(guān)的 session 中是否包含有用戶安全信息。如果沒有,那么請求被重定向到登錄頁,要求用戶提供安全信息。 在這種配置下應(yīng)用上面的測試計劃,那么除了登錄頁之外的其它請求都將因為缺少用戶安全信息,而使請求實際定位到登錄頁。如果不加斷言,那么在監(jiān)聽器看來所有的請求都是成功。而實際上,這些請求最終都沒有到達它們應(yīng)該去的地方。顯然,這種測試結(jié)果不是我們所期望的。 為了成功的測試,至少有2種方法:
對于第一種方法,有其局限性:
雖然,第二種方法配置難度增加了,但是它不用修改程序。而且還可將測試計劃保存成文件,以便重復(fù)使用。因此,選用第二種方法是較為理想的做法。下面以一個簡化的例子說明使用方法二的配置步驟。 1. 例子由以下幾個文件組成:
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest req = (HttpServletRequest)request; HttpServletResponse res = (HttpServletResponse)response; HttpSession session= req.getSession(); User user = (User)session.getAttribute("user"); if(null == user){ String uri= req.getRequestURI(); //如果請求頁是登錄頁,不轉(zhuǎn)向 if( uri.equalsIgnoreCase("/gWeb/login.jsp")){ chain.doFilter(request, response); } else{ res.sendRedirect("/gWeb/login.jsp"); } }else{ chain.doFilter(request, response); } }
public class User { private String user; private String pwd; public User(String user, String pwd) { this.user = user; this.pwd = pwd; } public boolean login(){ return user.equals("foxgem") && pwd.equals("12345678"); } public String getUser() { return user; } public void setUser(String user) { this.user = user; } }
authorizen org.foxgem.jmeter.AuthorizenFilter authorizen *.jsp 2. 創(chuàng)建如下結(jié)構(gòu)的Web測試計劃: 其中主要測試元件說明如下:
啟動測試計劃之后,執(zhí)行的順序是:首先,第一個請求登錄頁進行登錄;成功登錄之后,使用循環(huán)控制器執(zhí)行第二個請求。請求welcome.jsp時,響應(yīng)斷言用來驗證是否確實是welocme.jsp來處理請求,而不是因為其它頁。在這個測試計劃中需要注意的是http cookie管理器。正是由于它的作用,使得第二個請求能順利的發(fā)送到welcome.jsp進行處理,而不是因為缺少用戶安全信息轉(zhuǎn)發(fā)到login.jsp。 在這個例子中,我們并沒有在程序中使用cookie(使用的是session),那么http cookie管理器怎么會起作用呢?這是因為在servlet/jsp規(guī)范中對于session的狀態(tài)跟蹤有2種方式:
對于第二種情形,可以使用JMeter前置管理器中的http url重寫修飾符來完成。對于Tomcat,Session參數(shù)是jsessionid,路徑擴展使用";"。使用url編碼時需要注意,必須將瀏覽器的cookie功能關(guān)閉。因為url編碼函數(shù),如encodeURL,會判斷是否需要將sessionid編碼到url中。當(dāng)瀏覽器允許cookie時,就不會進行編碼。 如果cookie而不是session來保存用戶安全信息,那么直接使用http cookie管理器就行了。此時,需要將使用的cookie參數(shù)和值直接寫到管理器中,由它負責(zé)管理。對于其它的cookie使用,也是如此操作。 登錄問題解決之后,對于 Web 服務(wù)器的測試就沒什么難點了。剩下的就是根據(jù)實際需要,靈活運用相關(guān)的測試組件搭建編寫的測試計劃。(當(dāng)然,對于安全問題還有其它的使用情景。在使用時需要明確:JMeter 是否支持,如果支持使用哪種測試組件解決。) 數(shù)據(jù)庫服務(wù)器在大多數(shù)企業(yè)項目中是不可缺少的,對于它進行壓力測試是為了找出:數(shù)據(jù)庫對象是否可以有效地承受來自多個用戶的訪問。這些對象主要是:索引、觸發(fā)器、存儲過程和鎖。通過對于SQL語句和存儲過程的測試,JMeter 可以間接的反應(yīng)數(shù)據(jù)庫對象是否需要優(yōu)化。 JMeter 使用 JDBC 發(fā)送請求,完成對于數(shù)據(jù)庫的測試。一個數(shù)據(jù)庫測試計劃,建立如下結(jié)構(gòu)即可: 其中:
在實際的項目中,至少有2種類型的JDBC請求需要關(guān)注:select語句和存儲過程。前者反應(yīng)了select語句是否高效,以及表的索引等是否需要優(yōu)化;后者則是反應(yīng)存儲過程的算法是否高效。它們?nèi)绻实拖?,必然會帶來響?yīng)上的不盡如人意。對于這兩種請求,JDBC請求的配置略有區(qū)別:
如果對于Oracle,如果測試的是函數(shù),那么也可以使用select語句來進行配置,此時可以使用:select 函數(shù)(入?yún)? from dual形式的語句來測試,其中dual是oracle的關(guān)鍵字,表示啞表。對于其它廠商的數(shù)據(jù)庫產(chǎn)品,請查找手冊。 JMS服務(wù)器 MOM 作為消息數(shù)據(jù)交換的平臺,也是影響應(yīng)用執(zhí)行效率的潛在環(huán)節(jié)。在 Java 程序中,是通過 JMS 與 MOM 進行交互的。作為 Java 實現(xiàn)的壓力測試工具,JMeter 也能使用 JMS 對應(yīng)用的消息交換和相關(guān)的數(shù)據(jù)處理能力進行測試。這一點應(yīng)該不難理解,因為在整個測試過程中,JMeter 測試的重點應(yīng)該是消息的產(chǎn)生者和消費者的本身能力,而不是 MOM本身。 根據(jù) JMS 規(guī)范,消息交換有2種方式:發(fā)布/訂閱和點對點。JMeter針對這兩種情形,分別提供了不同的Sampler進行支持。以下MOM我們使用ActiveMQ 3.2.1,分別描述這兩種消息交換方式是如何使用 JMeter 進行測試。 1. 測試前的準備(兩種情況都適用) JMeter 雖然能使用 JMS 對 MOM 進行測試,但是它本身并沒有提供JMS需要使用的包。因此,在測試之前需要將這些包復(fù)制到 %JMETER_HOME%/lib 下。對于 ActiveMQ 來說,就是復(fù)制 %ACTIVEMQ_HOME%/lib。%ACTIVEMQ_HOME%/optional 是可選包,可根據(jù)實際情況來考慮是否復(fù)制。 JMeter 在測試時使用了 JNDI,為了提供 JNDI 提供者的信息,需要提供 jndi.properties。同時需要將 jndi.properties 放到 JMeter 的 classpath 中,建議將它與 bin下的 ApacheJMeter.jar 打包在一起。對于 ActiveMQ,jndi.properties 的示例內(nèi)容如下: java.naming.factory.initial = org.activemq.jndi.ActiveMQInitialContextFactory java.naming.provider.url = tcp://localhost:61616 #指定connectionFactory的jndi名字,多個名字之間可以逗號分隔。 #以下為例: #對于topic,使用(TopicConnectionFactory)context.lookup("connectionFactry") #對于queue,(QueueConnectionFactory)context.lookup("connectionFactory") connectionFactoryNames = connectionFactory #注冊queue,格式: #queue.[jndiName] = [physicalName] #使用時:(Queue)context.lookup("jndiName"),此處是MyQueue queue.MyQueue = example.MyQueue #注冊topic,格式: # topic.[jndiName] = [physicalName] #使用時:(Topic)context.lookup("jndiName"),此處是MyTopic topic.MyTopic = example.MyTopic 2. 發(fā)布/訂閱 在實際測試時,發(fā)布者和訂閱者并不是需要同時出現(xiàn)的。例如,有時我們可能想測試單位時間內(nèi)消息發(fā)布者的消息產(chǎn)生量,此時就不需要消息發(fā)布者,只需要訂閱者就可以了。本例為了說明這兩種Sampler的使用,因此建立如下的測試計劃: 其中JMS Publisher和JMS Subscriber的屬性:選擇"使用jndi.properties",連接工廠是connectionFactory,主題是MyTopic,其它使用默認配置。對于JMS Publisher,還需提供測試用的文本消息。 啟動ActiveMQ,運行測試計劃。如果配置正確,那么與ActiveMQ成功連接之后,在JMeter的后臺會打印出相關(guān)信息。在測試過程中,JMeter 后臺打印可能會出現(xiàn)java.lang.InterruptedException 信息,這個是正?,F(xiàn)象,不會影響測試過程和結(jié)果。這一點可以從 bin 下的 jmeter.log 看出。 3. 點對點 對于點對點,JMeter只提供了一種Sampler:JMS Point-to-Point。在例子中,建立如下圖的測試計劃: 其中:Communication style是Request Only。對于另一種風(fēng)格:Request Response,會驗證收到消息的JMS Header中的JMSCorrelationID,以判斷是否是對請求消息的響應(yīng)。 |
|