性能測試步驟(一)-熟悉應用html
這是整個性能過程最關鍵的步驟之一,毋庸質疑。linux
咱們必須瞭解:應用的架構數據庫
以我熟悉的應用類型爲例。瞭解了應用架構,咱們才能知道,咱們須要模擬的是:通常的html靜態文件請求、通常的servlet和jsp請求、AJAX請求、仍是遠程調用請求等。數組
咱們必須瞭解:應用的功能邏輯緩存
性能測試步驟(二)-測試需求tomcat
咱們獲得的測試需求每每是這麼描述的:服務器
這個系統可否支撐100萬的uv(天天登陸系統的人次)。網絡
言下之意是:按照目前的硬件性能和數量,系統可否支撐100萬的uv。多線程
然而,咱們瞭解的是吞吐量、響應時間等指標架構
吞吐量:系統每秒能處理的請求數,這個指標從服務器的視角,表徵系統容量
響應時間:從請求發出到第一個字節返回所須要的時間,這個指標從用戶的視角,表徵系統響應速度。
那麼,請問開發同事:能把測試需求轉化成咱們熟悉的吞吐量和響應時間嗎?
。。。。
答案經常是否認的
怎麼辦:只能由咱們根據經驗,把100萬uv轉化成一系列的指標。
響應時間:根據國外的一些資料,通常操做的響應時間不能高於3~5秒;重要操做,如結帳操做的響應時間不能高於15秒。
吞吐量:能夠根據已經上線的相似產品進行估計。或者,採用80/20原則進行估計。咱們常用的是80/20原則。
雖然已經有了響應時間和吞吐量指標,可是測試需求仍是不明確的。
咱們的測試目的是什麼?
是驗證當前硬件和軟件配置可否支撐100萬uv?
是測試當前的硬件和軟件配置最多能支撐多少uv?
是幫助開發尋找性能瓶頸?
雖然已經有了響應時間和吞吐量指標,可是測試需求仍是不明確的。
咱們的測試目的是什麼?
是驗證當前硬件和軟件配置可否支撐100萬uv?
是測試當前的硬件和軟件配置最多能支撐多少uv?
是幫助開發尋找性能瓶頸?
答案每每是:都要!
根據咱們的經驗,開發的需求每每是這樣的(固然開發通常不會說得那麼詳細,^_^):
首先,請大家驗證可否支撐100萬uv。
若是不能支撐,請找一下性能瓶頸。
主要性能瓶頸解決後,請估計能支撐多少uv,若是不到100w,請估計要加多少機器。
若是能支撐100萬,請再加壓,看看達到300萬uv的時候,系統的性能。
這麼一細化,需求基本明確了。
性能測試步驟(三)-測試準備
測試準備包括測試客戶端機器準備、測試數據準備、測試腳本準備。
客戶端機器:
要足夠,不然,若是瓶頸在客戶端,就沒法評估服務端。
要和服務器保持網絡通暢,不然,若是瓶頸在網絡,也沒法評估服務端。包括:
網絡帶寬要高於服務器吞吐量
網絡帶寬要穩定。
測試數據
若是被測功能涉及數據庫和高速緩存,一般須要預設很大的數據量才能凸顯性能瓶頸,這一般是挺困難的一個環節。
若是是已經上線的應用,數據能夠從線上拷貝獲得;若是尚未上線,那須要構造相似於線上的數據量。
好比,要測試羣聊性能,咱們首先須要註冊大量用戶;而後把測試用戶都加入到聊天羣中。
測試數據準備的腳本,有時候比測試腳本自己還要多。
對於實在沒有辦法構造大數據量的狀況,若是要測試高速緩存,咱們有時候會按數據量的比例減小高速緩存,以使測試結果儘可能準確。
測試腳本
Grinder腳本用jython實現
測試腳本的實現每每會花費比較長的時間
由於涉及到應用實現的細節,須要和開發不斷交流才能完成。這也是須要了解應用架構的緣由之一。
關於sleep time
基於真實模擬的考慮,sleep time仍是儘可能按照真實時間,並給必定的誤差。
不過對於測試客戶端來講,sleep time每每會引發不少客戶端測試線程的調度,浪費客戶端系統資源。
Sleep time越小,客戶端能模擬的吞吐量就越大,因此,實際測試中,咱們每每會把sleep time設置爲0 。
性能測試步驟(四)-測試執行
測試的執行中,須要監控測試客戶端和服務器性能,監控服務器端應用狀況:
客戶端的系統資源(cpu、io、memory)狀況
服務端的系統資源(cpu、io、memory)狀況
服務器的jvm運行狀況
服務端的應用狀況,看是否有異常
響應時間、吞吐量等指標
系統資源監控,linux下能夠採用的工具備:vmstat、top、meminfo等。
JVM的監控,能夠用jprofiler工具,linux下面的jmap、jhat等。
響應時間、吞吐量等,由grinder提供。
上述這些信息,通常在測試結束後,均須要歸檔整理,已備後續詳細分析
咱們本身開發一套腳本,用於以固定的頻率獲取測試客戶端和服務器的vmstat和top輸出、grinder的log,並從中截取有用信息保存,用於過後分
析。
每次測試運行完之後,確定會增長不少數據,須要考慮本次執行對數據量的影響,若是數據量的變化對後續測試會有影響,則須要清理數據。
性能測試步驟(五)-測試分析
測試分析通常跟測試監控息息相關,在測試執行的過程當中,用各類監控工具能看到系統運行的狀態,並及時發現問題。
常見的問題有:
內存問題
有限資源競爭問題
內存問題
從top中看tomcat的內存佔用,這個是不許的,須要用專門的內存分析工具來查看。
工具:jmap,jhat,jstat,能夠獲得內存快照,獲得堆內存的詳細信息。
垃圾收集配置會影響系統性能,若是內存塊生成和銷燬量很大,則能看到系統吞吐量隨垃圾收集呈現週期性的變化。
從理論上來講,JAVA會出現內存泄漏的狀況,不過咱們在被測試的應用中尚未發現過這種狀況。
可是,在某些系統架構下,內存會成爲瓶頸問題。好比咱們曾經測試過聊天系統,每一個長鏈接須要佔用5M內存,那麼,一臺10G內存的服務器只能保持2000個長鏈接。
共享資源競爭問題
有限資源的競爭有不少,好比Service層的一個共享對象,好比數據庫鏈接,好比數據庫中的某一個使用頻率很高的數據表。
一個共享資源在一個時間點上,只能被一個線程得到,其餘線程必須等待,這就容易形成不少線程的timed wait狀態。經過jprofiler工具,可以獲得線程快照,並分析改進方法。
性能測試經驗交流-偶然性問題
跟通常的功能測試同樣,性能測試也會出現偶然性問題。
碰到這種問題,咱們須要發揮測試人員的革命精神,追查到底。咱們常發現的因素以下:
外部因素變化,好比,某幾回測試,有時候好,有時候很差,並無規律可循。最後發現原來是由於網絡不穩定形成。請求返回變化。有時候第二次請求的內容取決於第一次的返回信息(也就是所謂的「關聯」),這種關聯通常經過string的parse實現,而這通常都不是很可靠,返回一旦變化,可能就會出錯。
應用服務器若是是集羣,一個用戶請求某一臺服務器能獲得正確返回,可是若是換作另外一個用戶,可能該服務器並無該用戶的信息,因此返回錯誤。
性能測試經驗交流-客戶端併發
測試客戶端要模擬高併發,必然要啓動多線程,因此確定也會存在線程併發問題。好比:
在作參數化的時候,存儲參數的數組就是一個共享對象。若是要使每一個線程的每次循環都讀取不同的參數,那數組下標的更新須要注意併發問題。
好比,若是在腳本中要調用System.out,那麼也須要注意這也是一個共享對象,若是調用System.out過多,會致使線程的等待,使客戶端性能下降。
性能測試經驗交流-測試人員
性能測試因爲涉及面廣,對測試人員的要求就很高。我想,性能測試人員應該培養以下幾方面的能力:
如前所述,對應用架構的透徹理解。
溝通能力,測試進行過程當中,必定要培養勤於跟開發溝通的意識,以提升工做效率。
解決問題的能力,在編腳本或者測試執行過程當中,會碰到不少問題。首先是不要懼怕,先考慮問題的可能緣由,而後一步步定位、驗證。固然,這個過程,須要調試等經驗的不斷積累