性能測試原理分析及實戰
【摘要】 在大型軟體系統投入生產之前進行性能測試已經成為趨勢,本文結合一個性能測試案例對性能測試的過程和原理進行了介紹。
【關鍵字】 性能測試 | 並發測試 | 負載測試
? 軟體測試中的性能測試
軟體測試是保證軟體質量的重要手段,也是軟體過程中一個必不可少的環節。而性能測試則隸屬於軟體測試中的系統級測試,它對軟體在集成系統中運行的性能行為進行測試,旨在及早確定和消除軟體中與構架有關的性能瓶頸。
? 性能測試的含義
目前對性能測試沒有明確的定義,一般地,它主要是針對系統的性能指標制定性能測試方案,執行測試用例,得出測試結果來驗證系統的性能指標是否滿足既定值。性能指標里可能包括系統各個方面的能力,如系統並發處理能力,批量業務處理能力等。
? 性能測試的分解
在性能測試的執行中,可以根據具體的性能指標,分解為幾種測試,根據其關係,可以在不同的時間和空間內執行。這些子測試通常包括以下幾種:
並發測試:驗證系統的並發處理能力。一般是和伺服器端建立大量的並發連接,通過客戶端的響應時間和伺服器端的性能監測情況來判斷系統是否達到了既定的並發能力指標。
負載測試:驗證系統的負載工作能力。系統配置不變的條件下,在一定時間內,伺服器端在高負載情況下的性能行為表現。這裡的負載可以是用戶數,交易數,事務數等。
配置測試:核實在操作條件保持不變的情況下,系統在使用不同配置時其性能行為的可接受性。
健壯性測試:核實被測系統的性能行為在異常或極端條件之下的可接受性。這裡的異常或極端條件指的是資源過少,用戶數過多,突發故障等。
隨著軟體系統的規模日益龐大,結構日趨複雜,對軟體系統的性能測試已經成為必須和趨勢。尤其大型的分散式軟體系統更要在正式運行前進行性能測試,因為這樣的系統在投入生產之後,往往要接受大批量的業務量,這對應用程序本身,操作系統, 中心資料庫伺服器,中間件伺服器,網路設備的承受力都是一個嚴峻的考驗。在其中任意一個環節出現的問題都可能給用戶帶來巨大的商業損失。預見軟體系統的並發承受能力以避免商業風險,這是在軟體測試階段就應該解決的。例如中國人民銀行的現代化支付系統和上海外匯交易中心的本幣交易系統都在投入生產之前進行了多輪的第三方性能測試,起到了很好的作用。
下面我就介紹一個性能測試案例。
? 一個性能測試實例
? 被測系統
1)被測系統介紹
本系統應我國金融信息化發展設計,採用當今比較先進和流行的技術,是運行在城域網上的大型分散式應用系統。
本系統遵循J2EE規範,採用B/S體系結構進行設計和開發。業務主要分為交易業務和查詢業務,查詢業務採用J2EE規範,交易業務以J2EE體系架構為基礎,進行進一步的處理,採用了TCP的四層結構。
* 表示層:
運行在終端上。運行java applet程序,提供協議控制和用戶界面,與系統最終用戶實現直接交互,通過TCP/HTTP與前置系統通訊。向前置系統發送請求報文,並接收前置系統返回的回應報文。
* 商業邏輯層:
作為中間層實現核心業務邏輯服務。
交易應用服務:運行在交易主機上。在tuxedo中間件上運行業務處理程序,按交易規則處理前置機發來的交易指令,通過tuxedo jolt與前置機連接,通過DB2 C API與資料庫連接。
交易前置服務和查詢前置服務:運行在前置機上。交易前置服務運行服務程序接收終端請求報文並通過tuxedo jolt客戶端將其轉發給交易主機,再通過輪詢和同步反饋接收交易主機返回的報文,將其轉發給業務終端;查詢前置服務運行在weblogic應用伺服器上並調用Jreport組件,通過JDBC完成對查詢流指令的發送並接受資料庫返回的結果給業務終端。
* 數據層:
運行在資料庫主機上。負責整個系統中數據信息的存儲、訪問及其優化。運行DB2資料庫服務程序。通過DB2 C API與交易主機通訊,JDBC與查詢前置服務通訊。
資料庫主機和交易主機運行在交易中心城市,前置機運行在各個分中心城市,終端是各個城市參加交易的單位,整個系統覆蓋城域網。
2) 被測系統的性能要求和性能指標
金融系統是業務處理十分頻繁、數據交換吞吐量很大的系統,業務處理的速度直接關係到公司的經濟效益和客戶對公司的評價。在客觀條件下,整個廣域網系統必須在大業務量的情況下同時保持快速的實時響應能力,以保證整個業務系統的通暢運行。用戶對此提出如下性能指標:
下面我們會根據此系統和給定的性能指標來進行性能測試:
? 對被測系統進行性能測試
性能測試的目的是最大程度地模擬真實業務場景,來驗證系統的性能指標,並發現可能存在的性能瓶頸。
1)對被測系統進行系統分析
我們可以看到本系統大體上由終端、前置機、交易主機、資料庫主機節點組成。
在整個業務流程中,業務終端→前置機→交易主機→資料庫主機形成了一個壓力流串,每個節點在壓力下能夠正常工作是整個系統正常運轉的基礎。也就是說,如果其中任意一個節點在業務壓力下發生了擁塞、處理不力等不正常情況,那整個系統都無法正常運轉。
我們來看一下業務流程。
首先,從終端到前置機,終端產生業務報文發送至前置機,前置機上運行查詢前置服務和交易前置服務,查詢前置服務向下通過HTTP協議以WEB服務形式和終端連接,向上通過JDBC直接與資料庫系統相連。交易前置服務向下通過基於TCP協議的socket連接和終端通訊,向上通過tuxedo jolt客戶端和交易應用服務連接。交易應用服務進行業務邏輯計算,並操作資料庫系統。
由以上分析,我們可以整理出整個系統的兩條壓力流程線來,之所以我們把其分為兩條流程線,是因為交易前置服務和查詢前置服務的工作原理完全不同,下與終端的連接,上與交易主機的連接也完全是獨立的兩個通路。
終端→交易前置機→交易主機→資料庫系統
終端→查詢前置機→資料庫系統
下面我們先獨立分析兩條流程線,之後我們將再次綜合分析,以考慮二者之間的相互影響作用。
第一條路線上主要運行的是登陸指令和交易指令信息。
當系統運作時,多個交易終端與交易前置服務建立socket連接,完成登陸,之後發送交易指令,造成對交易前置服務的壓力。交易前置服務通過運行服務程序接收到交易指令,並檢驗其合法性,然後通過交易中間件tuxedo的客戶端把業務的壓力傳遞給交易主機進行處理。交易主機進行必要的金融計算和業務邏輯運行,得出反饋結果,生成消息,一方面順原路返回到各個終端上去,一方面記錄入資料庫。
在本條流程線上的加壓主要考驗交易前置服務程序的socket多連接建立能力,tuxedo交易中間件的即時響應能力,交易主機的計算能力,以及DB2資料庫的DML語句加鎖機制。
第二條路線上主要運行的是查詢指令信息。
查詢指令產生時,通過http協議訪問weblogic上的web伺服器和應用伺服器上的相應組件,以JDBC介面訪問後台的DB2資料庫,並把資料庫返回的結果發送至終端界面。
在本條流程線上的加壓主要驗證weblogic處理能力,資料庫中索引是否創建合理。
兩條流程線相對獨立,但又是互相依賴的。由於是對同一個資料庫系統進行讀操作和寫操作,查詢流程的結果依賴於交易流程數據的產生,交易流程的產生的數據又通過查詢流程得到驗證。在進行壓力測試時,兩者的協同會對資料庫形成壓力的衝擊。
鑒於以上分析,結合用戶性能指標,我們決定把本次性能測試分解為如下幾個子測試來進行。
A: 並發登陸測試:750個終端一分鐘內並發登陸系統,並且響應時間在30秒之內。
B: 業務負載測試
此下又有三個子測試。
* 交易流程測試:多個終端發起交易請求,逐漸加壓,以達到300筆/秒的壓力為限。
* 查詢流程測試:多個終端進行查詢,逐漸加壓,以達到400筆/秒的壓力為限。查詢成功與否以所請求的web頁面完全展現為標準。(查詢響應能力其實和資料庫中的數據量有關係,後來和用戶進一步確認,基礎數據為30萬條)
* 綜合測試:
在上面兩種測試都通過的情況下,進行綜合測試。
2)性能測試的執行過程,性能測試依照下面的步驟來進行:
* 第一步:測試腳本的開發
本次壓力測試採用MI公司的loadrunner工具,腳本編輯和編譯工作在VU Generator(腳本作坊)中進行。
理想的腳本是對現實世界的業務行為進行了完全無誤的模擬,這其實是不可能的。我們的目標是使模擬的誤差在我們認可的範圍之內,並能有方法加以控制。
針對並發登陸測試和交易流程測試,由於兩者運行機理相同,都是終端調用socket client,和交易前置的socket server建立連接,將請求消息發送至交易前置機。我們考慮採用將此部分java socket程序編入測試腳本程序,生成登陸和交易業務腳本,通過loadrunner來執行。這樣做的好處是繞過終端IE界面複雜的處理邏輯,直接施壓在前置機上(這種方式同時也帶來了偏差,在執行測試場景時通過其它方法得到了一定的彌補)。
腳本除了要實現與前置機的socket連接,業務發送等功能,還要建立用戶信息數據池,設置檢測點、異常退出點,為腳本執行後的結果統計和分析提供正確的依據。
交易業務腳本內容略。部分如下:
public class Actions {/*登陸變數初始化*/ProtocolManager protocol;//ProtocolManager為實現socket連接的類 ServiceName service; //ServiceName對服務端的信息進行了封裝,包括IP地址和埠號。LoginMessage login;//LoginMessage為登陸時需要向伺服器發送的消息,待伺服器確認並返回回應消息時,登陸成功。protocol = new ProtocolManager(); //創建ProtocolManager類的protocol對象service = ServiceName.getInstance();//獲得ServiceName的實例login=new LoginMessage();//創建LoginMessage類的login對象service.setIP("200.31.10.18");//設置服務端的IP地址service.setPort(17777);//設置服務端的埠號/*設置登陸消息*/ login.serUserName(lr.eval.string(「{loginName}」));//從數據池裡讀出用戶名,設置在login成員變數里login.setPasswd(「1234」);//資料庫中添加的用戶密碼都為1234/*發送登陸消息*/protocol.login(login);//發送登陸消息lr_start_transaction("trade");//交易開始點TradeMessage trademessage;//生成交易消息/*設置交易消息*/
/*發送交易消息*/
if(sendfail)lr_end_transaction("trade", LR_FAIL);//如果發送交易消息失敗,交易結束,返回。/*循環回收主機返回的處理信息*/
if(recievefail)lr_end_transaction("trade", LR_FAIL);//如果不能接收到主機處理回應消息,交易結束,返回。if(recievesuccess)lr_end_transaction("trade", LR_PASS);//如果接收到主機成功處理的回應消息,交易結束,返回。
}
在上面的例子中,我們主要對每筆交易進行了transaction化。在交易開始時設置開始檢測點,交易結束時設置結束檢測點,並給loadrunner報出交易狀態。實際的腳本中在回收交易響應消息時還進行了拆包,在應用層上對交易狀態進行識別,並非例子中只在socket層加以判斷。
針對查詢流程測試,由於loadrunner工具支持基於http的web訪問錄製功能,我們將考慮採用以錄製腳本為主,手工編寫腳本為輔的方法,生成查詢業務腳本,通過loadrunner來執行。由於查詢腳本基本由錄製生成http請求和應答,不同的壓力測試工具錄製會有差別,這裡就不再寫出查詢腳本樣例。
* 第二步:根據用戶性能指標創立測試場景
在本次性能測試中,用戶提出的性能指標不夠細緻和確切,通過對用戶調查和實際業務分析,我們把性能指標的實現方式進行了明確的定位。
A.並發登陸測試場景
並發登陸750用戶/分鐘,登陸響應時間在30秒之內。仔細考慮一下,這裡的並發登陸750用戶/分鐘指的是系統能夠在1分鐘內接受750個用戶的登陸請求,而處理的效果如何則在交易終端體現,即登陸響應時間。基於這樣的理解,我們把用戶性能指標轉化為如下的測試場景:
從第一秒鐘開始,用loadrunner每秒鐘登陸13個用戶,並保持socket連接,直到1分鐘結束,從終端向系統一共發送750個左右的用戶登陸請求,系統在一分鐘內建立了750個連接。在終端觀察並統計登陸響應時間。如果系統不能響應持續增加的登陸請求或平均登陸響應時間大於30秒,並發登陸測試場景都不能算通過。
為了幫助用戶更加深入了解系統的能力,我們對系統的瞬時並發能力進行測試,即測試系統所能承受的最大的瞬時並發用戶登陸連接請求個數。這個場景通過loadrunner在登陸前設置同步點來實現,這個結果將結合上一個結果一同反映系統的登陸處理能力。
B:交易流程測試和查詢流程測試:
在這裡我們只對系統的業務負載能力做測試(並發處理能力在登陸測試中已經得到考證)。測試場景如下:
在loadrunner中,建立goal-orented的測試場景,以400筆/秒為目標,將調度權交給loadrunner來試圖達到這個指標。
C: 綜合測試:
交易流程測試和查詢流程測試同時進行。
以上的測試場景要求均可在loadrunner中的Controller進行設置完成。
測試場景的創建之後,我們的測試任務更加具體化和清晰化。
* 第三步:運行測試場景,同步監測被測系統性能行為
在loadrunner中的controller中開啟unix系統資源計數器,weblogic計數器,DB2計數器,檢測系統資源消耗情況,並最終和測試結果數據合併,成為分析圖表。
測試結果可在測試執行完畢後,通過loadrunner工具中的Analysis(分析器)獲得。
A: 並發登陸測試
依照設計好的測試場景,用loadrunner工具在一分鐘內漸增向系統發送登陸請求。分別進行三次,結果如下
表格 2登陸測試結果數據表
註:這裡的登陸成功用戶指的是系統接受了登陸請求,並建立了連接。平均響應時間在登陸腳本里設置檢測點,由loadrunner工具自動獲得。
考察系統的瞬時並發處理能力:在完成上一步測試的前提下,逐步增加瞬時並發登陸用戶數,直到系統極限。
測試執行結果如下:
B: 負載測試
* 交易流程測試:
測試結果如下:
對於通過網路介面發送的批量業務請求,均在性能指標所指定的時間範圍內得到請求成功的反饋消息,說明主機已經處理成功。
在通過網路介面發送業務請求的同時,開啟IE,通過實際終端界面進行登陸和交易,系統響應時間延長,界面顯示和刷新明顯變慢,到業務量高峰時期,界面已經不能顯示任何信息,處於不可工作的狀態。
需求說明的是系統正常工作時,每個界面終端不僅應該能夠展示己方的交易信息,還要展示其他交易單位的交易信息和系統信息。因此當交易量大的時候,界面需要展示的信息量是巨大的,這本身對終端界面是一個性能考驗。
* 查詢流程測試:
本流程測試在交易流程測試之後進行,以利用其生成的數據。
測試結果基本滿足性能指標。
* 綜合測試
由於交易流程測試的未通過,本測試已經不能執行。
* 第四步:測試結果分析及性能評價
A:並發測試結果分析
根據上述的並發測試響應時間表,我們可以得出以下的結論:
被測系統在一分鐘內並不能接受750個用戶的登陸請求,其可接受的登陸請求用戶數大概為490個左右。在這樣的條件下,登陸響應時間在用戶要求範圍之內。
被測系統的瞬時並發處理能力約為122個用戶。
B: 交易流程測試結果分析及性能評價
根據交易流程測試結果可知,通過腳本程序進行業務行為,發送業務請求消息到回收主機處理回應消息,這段時間系統是順暢的,反應也是迅速的,但是在終端界面卻不能即時展現消息。這說明信息的回饋通路在終端界面出現了性能瓶頸。當界面需要在短時間內展示大量交易信息時,已經不能承受負荷。這與終端採用java applet技術有關。
C: 查詢流程測試結果分析
查詢流程基本符合性能指標。
需要說明的是,實際中,以上每個場景的測試都執行了多次,中間件參數進行了多次的調優。從以上測試的結果分析也可以看出,我們的性能測試瓶頸不是出現在中間件產品上,而是在自身開發的程序上。
? 總結
由以上的實例過程我們可以看出性能測試基本由以下幾個步驟進行
1.系統分析
將系統的性能指標轉化為性能測試的具體目標。通常在這一步驟里,要分析被測系統結構,結合性能指標,制定具體的性能測試實施方案。這要求測試人員對被測系統結構和實施業務的全面掌握。
2.建立虛擬用戶腳本
將業務流程轉化為測試腳本,通常指的是虛擬用戶腳本或虛擬用戶。虛擬用戶通過驅動一個真正的客戶程序來模擬真實用戶。在這一步驟里,要將各類被測業務流程從頭至尾進行確認和記錄,弄清這些交易過程可以幫助分析到每步操作的細節和時間,並能精確地轉化為腳本。此過程類似製造一個能夠模仿人的行為和動作的機器人過程。這個步驟非常重要,在這裡將現實世界中的單個用戶行為比較精確地轉化為計算機程序語言。如果對現實世界的行為模仿失真,不能反映真實世界,性能測試的有效性和必要性也就失去了意義。
3.根據用戶性能指標創建測試場景
根據真實業務場景,將單個用戶的行為進行複製和控制,轉化為多個用戶的行為。在這個步驟里,對腳本的執行制定規則和約束關係。具體涉及到交易量,並發時序等參數的設置。這好比是指揮腳本運行的司令部。這個步驟十分關鍵,往往需要結合用戶性能指標進行細緻地分析。
4.運行測試場景,同步監測應用性能
在性能測試運行中,實時監測能讓測試人員在測試過程中的任何時刻都可以了解應用程序的性能優劣。系統的每一部件都需要監測:客戶端,網路,web伺服器,應用伺服器,資料庫和所有伺服器硬體。實時監測可以在測試執行中及早發現性能瓶頸。
5.性能測試的結果分析和性能評價
結合測試結果數據,分析出系統性能行為表現的規律,並準確定位系統的性能瓶頸所在。在這個步驟里,可以利用數學手段對大批量數據進行計算和統計,使結果更加具有客觀性。在性能測試中,需要注意的是,能夠執行的性能測試方案並不一定是成功的,成敗的關鍵在於其是否精確地對真實世界進行了模擬。
在整個性能測試過程中,自動化測試工具的選擇只能影響性能測試執行的複雜程度,簡便一些或繁雜一些;但人的分析和思考卻會直接導致性能測試的成敗。所以本篇著重於對性能測試思路的整理。測試工具的介紹可以參看有關壓力測試工具的資料。
注1:在本次性能測試案例中,還涉及到健壯性測試和可恢復性測試,限於篇幅,只介紹了並發測試和負載測試。
注2:loadrunner腳本樣例並非實際運行腳本,只是為了表示其流程。
作者:西邊人,一個搞軟體測試的男人。
西邊人西說測試,這裡彙集眾多各個領域的測試大神和自學愛好者,歡迎加入。
Q群:330374464
推薦閱讀:
※從0到1搭建移動App功能自動化測試平台(0)背景介紹和平台規劃
※Android獲取應用大小
※Web自動化測試環境搭建之Python+Selenium
※Eclipst+python+selenium
※Jmeter測試移動介面性能--環境搭建