使用JMeter對數(shù)據(jù)庫做壓力測試
【IT168 技術(shù)文檔】作為一名開發(fā)人員,大多情況下都會認真的做好功能測試,但是卻常常忽略了軟件開發(fā)之后的壓力測試,尤其是在面向大量用戶同時使用的Web應(yīng)用系統(tǒng)的開發(fā)過程,壓力測試往往是不夠充分的。近期我在一個求職招聘型的網(wǎng)站項目中就對壓力測試的重要性體會頗深。
在項目中,我負責開發(fā)職位信息的搜索部分,但是由于缺乏壓力測試,倉促將搜素部分的功能提交到生產(chǎn)環(huán)境,結(jié)果當并發(fā)量稍稍到達一定程度時,數(shù)據(jù)庫系統(tǒng)便已經(jīng)不堪重負。無奈之下向網(wǎng)上資源查詢解決方法,其中一個就是對現(xiàn)有的應(yīng)用做足夠到位的壓力測試。
壓力測試有著很豐富的內(nèi)容,而這里,我只針對應(yīng)用中所遇到的問題以及解決方法做一個簡單的描述,希望對以后遇到同樣問題的朋友能夠起到些許幫助作用。
我自己做的例子使用的環(huán)境是:
測試工具:JMeter 2.3.1
數(shù)據(jù)庫:Oracle 10G
其他環(huán)境:JDK 1.6.0_05(也可以使用JDK1.4及以上版本)
1.創(chuàng)建好的JMeter測試計劃樹形結(jié)構(gòu)圖如下:

2.在剛打開JMeter的時候,默認會存在兩個節(jié)點,一個是“Test Plan”,點擊這個節(jié)點,在右邊的屬性頁面中,命名為“我們的數(shù)據(jù)庫測試計劃”

在屬性頁的最下面,我們看到設(shè)置jar包所在路徑的選項,默認存在一個選項"E:\software\develop\testunit\jMeter \jakarta-jmeter-2.3.1\lib",這個是我的機器中JMeter的lib目錄,在這個例子中,Oracle的jdbc驅(qū)動也已經(jīng)拷貝到該目錄下。
內(nèi)容導航3.新增一個“Thread Group”,重命名為“使用變化的SQL來做數(shù)據(jù)庫壓力測試”。其中,“Number of Threads”表示的是JMeter會同時創(chuàng)建多少個線程來進行壓力測試,對于一個網(wǎng)站而言,也就是模擬一次存在多少個用戶來訪問該網(wǎng)站;而“Ramp-Up Period(in seconds)”表示JMeter每個多少秒發(fā)動并發(fā);“Loop Count”則是指配置好的并發(fā)情形發(fā)生多少次。

4.在“Thead Group”下創(chuàng)建一個“User Defined Variables”,即用戶自定義變量,重命名為“我們定義的動態(tài)語句部分”,這里我們使用它來生成動態(tài)SQL語句,讓用戶每次訪問數(shù)據(jù)庫的SQL語句都不一樣,這樣減少Oracle數(shù)據(jù)庫對相同SQL語句的緩存對測試結(jié)果所帶來的影響。

變量定義的完整內(nèi)容如下:

注:${__split(...)} 是JMeter中自帶的拆分字符串為數(shù)組的函數(shù),可以通過JMeter工具欄"Options"->"Function Helper Dialog"來打開函數(shù)代碼輔助工具生成我們所需的函數(shù)調(diào)用。
另外有個需要注意的問題是:在${__split(...)} 中,如果拆分字符串中的內(nèi)容包含有符號",",一定得用符號"\"進行轉(zhuǎn)義,否則可能被JMeter誤認為是參數(shù)分隔符,會導致無法正確生成字符串數(shù)組。
內(nèi)容導航5.接下來是配置JDBC連接設(shè)置

6.創(chuàng)建一個具體的JDBC請求

"Query Type"中選擇的是預(yù)編譯語句;
SQL語句當中,動態(tài)內(nèi)容的代碼行是"and contains(p.p_name,?) > 0",這里的"?"就是預(yù)編譯語句中的動態(tài)參數(shù),在屬性頁下面的"Parameter Values"和"Parameter types"來指定,由于預(yù)編譯語句在Java教程已有很多講解,這里不再贅述。
注:這里有一個JMeter的函數(shù)"__V..."沒有提到,將在后面說明另外一個JDBC調(diào)用測試的時候進行補充。
內(nèi)容導航7.創(chuàng)建三個監(jiān)聽器,可以從三個不同的層面來觀察響應(yīng)結(jié)果
執(zhí)行一下測試計劃,我們來看看三個監(jiān)聽器所返回的結(jié)果是怎樣的。
以上是表格方式查看響應(yīng)結(jié)果的情況,可以看到通過表格可以查看某個范圍內(nèi)的響應(yīng)時間和響應(yīng)狀態(tài)是否正常;
以上三幅截圖則是來自樹形監(jiān)聽器,樹形監(jiān)聽器在幾種監(jiān)聽器中應(yīng)該是最細致的,可以查看響應(yīng)狀態(tài)、時間、以及執(zhí)行的SQL語句,乃至返回的結(jié)果均能進行驗證。
至于上面的圖形監(jiān)聽器,可以宏觀的觀察SQL語句在壓力測試下響應(yīng)的平滑度,并且有一定的統(tǒng)計信息,能夠觀察平均響應(yīng)時間等。
現(xiàn)在我們來看另外一種方式編寫我們的JDBC調(diào)用。就是使用JMeter提供的函數(shù)動態(tài)生成我們所需要不斷變化的SQL語句部分。之所以需要這么做是為了方便我們觀察執(zhí)行的SQL語句內(nèi)容。
在前面使用預(yù)編譯的方式,傳遞動態(tài)參數(shù)的SQL語句執(zhí)行的結(jié)果,大家已經(jīng)看到過,在樹形監(jiān)聽器中,我們觀察到到執(zhí)行過的SQL語句是:
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
SELECT *
FROM (SELECT tmp.*, ROWNUM rn
FROM (
select p.p_id, p.p_name, c.cmp_name
from test_product p, test_company c
where p.cmp_id = c.cmp_id
and contains(p.p_name, ?) > 0
--and (p.p_name like '%D%' or p.p_name like '%AIX%')
ORDER BY p.p_id desc
) tmp
WHERE 1 = 1 AND ROWNUM <= 100)
WHERE 1 = 1 AND rn >= 1
這樣導致我們無法看出參數(shù)"?"當中表示的具體值是什么,這對我們在某些情況下確定SQL語句的性能是相當不利的。所以我們這里需要使用JMeter的動態(tài)函數(shù)特性。
我們創(chuàng)建第二個"JDBC Request"節(jié)點,而后禁用"產(chǎn)品名 全文關(guān)鍵字 JDBC Request",將新創(chuàng)建的"JDBC Request"重命名為"產(chǎn)品名 like JDBC Request",將其中的SQL語句改寫為:
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
SELECT *
FROM (SELECT tmp.*, ROWNUM rn
FROM (
select p.p_id, p.p_name, c.cmp_name
from test_product p, test_company c
where p.cmp_id = c.cmp_id
AND ( ${__V(smt_${__Random(1,4,rnd)})} )
ORDER BY p.p_id desc
) tmp
WHERE 1 = 1 AND ROWNUM <= 100)
WHERE 1 = 1 AND rn >= 1
這里核心的部分就是代碼行"AND ${__V(smt_${__Random(1,4,rnd)})} "。"${__Random(1,4,rnd)}"用來生成隨機數(shù),取值范圍在1到4之間,而"__V(...)"函數(shù)幫助我們轉(zhuǎn)義"smt_${__Random(1,4,rnd)}"生成的內(nèi)容,很類似于JavaScript中的"eval"函數(shù)。
例如"${__Random(1,4,rnd)}"生成隨機數(shù)為1,則"smt_${__Random(1,4,rnd)}"對應(yīng)的內(nèi)容為"smt_1","__V"將獲取數(shù)組變量"smt"中的第一個元素,于是生成的SQL語句如下:

這里我們可以清楚的看到所執(zhí)行的SQL語句。
后記
本例中我們使用了JMeter附帶的函數(shù)"__split"和"__V","__Random"等等,文章對于這些函數(shù)的描述可能不夠完整,亦可能不夠準確,更多詳盡的解釋,大家可以參考JMeter官方文檔。
posted on 2012-04-26 15:28 順其自然EVO 閱讀(3395) 評論(0) 編輯 收藏 所屬分類: jmeter and badboy