根據在實際項目中的實踐經驗,我把常用的性能測試方法分為七大類:后端性能測試(Back-end Performance Test)、前端性能測試(Front-end Performance Test )、代碼級性能測試(Code-level Performance Test)、壓力測試(Load/Stress Test)、配置測試(Confguration Test)、並發測試 (Concurrence Test),以及可靠性測試(Reliability Test)。接下來,我將詳細為你介紹每一種測試 方法。
第一,后端性能測試
其實,你平時聽到的性能測試,大多數情況下指的是后端性能測試,也就是服務器端性能測試。
后端性能測試,是通過性能測試工具模擬大量的並發用戶請求,然后獲取系統性能的各項指標,並且驗 證各項指標是否符合預期的性能需求的測試手段。
這里的性能指標,除了包括並發用戶數、響應時間和系統吞吐量外,還應該包括各類資源的使用率,比 如系統級別的CPU占用率、內存使用率、磁盤I/O和網絡I/O等,再比如應用級別以及JVM級別的各類資 源使用率指標等。
由於需要模擬的並發用戶數,通常在“幾百”到“幾百萬”的數量級,所以你選擇的性能測試工具,一定不 是基於GUI的,而是要采用基於協議的模擬方式,也就是去模擬用戶在GUI操作的過程中實際向后端服 務發起的請求。
只有這樣才能模擬很高的並發用戶數,盡可能地模擬出真實的使用場景,這也是現在所有后端性能測試 工具所采用的方法。
根據應用領域的不同,后端性能測試的場景設計主要包括以下兩種方式:
基於性能需求目標的測試驗證; 探索系統的容量,並驗證系統容量的可擴展性
隨着系統並發用戶數的增長,系統處理能力達到過飽和狀態。此時,如果繼續增加並發用 戶數,最終所有用戶的響應時間會變得無限長。相應地,系統的整體吞吐量會降為零,系 統處於被壓垮的狀態。我們往往把這個階段稱為“過飽和區間”。
第二,前端性能測試
前端性能測試並沒有一個嚴格的定義和標准。
通常來講,前端性能關注的是瀏覽器端的頁面渲染時間、資源加載順序、請求數量、前端緩存使用情 況、資源壓縮等內容,希望借此找到頁面加載過程中比較耗時的操作和資源,然后進行有針對性的優 化,最終達到優化終端用戶在瀏覽器端使用體驗的目的。
目前,業界普遍采用的前端測試方法,是雅虎(Yahoo)前端團隊總結的7大類35條前端優化規則,你 可以通過雅虎網站查看這些規則,以及對各規則的詳細解讀。
我在這里列出了其中幾個最典型也是最重要的規則,來幫助你理解前端性能測試優化的關注范圍。
減少http請求次數:http請求數量越多,執行過程耗時就越長,所以可以采用合並多個圖片到一個 圖片文件的方法來減少http請求次數,也可以采用將多個腳本文件合並成單一文件的方式減少http請 求次數; 減少DNS查詢次數:DNS的作用是將URL轉化為實際服務器主機IP地址,實現原理是分級查找,查 找過程需要花費20~100ms的時間,所以一方面我們要加快單次查找的時間,另一方面也要減少一個 頁面中資源使用了多個不同域的情況; 避免頁面跳轉:頁面跳轉相當於又打開一個新的頁面,耗費的時間就會比較長,所以要盡量避免使 用頁面跳轉; 使用內容分發網絡(CDN):使用CDN相當於對靜態內容做了緩存,並把緩存內容放在網絡供應商 (ISP)的機房,用戶根據就近原則到ISP機房獲取這些被緩存了的靜態資源,因此可以大幅提高性 能; Gzip壓縮傳輸文件:壓縮可以幫助減小傳輸文件的大小,進而可以從網絡傳輸時間的層面來減少響 應時間;
第三,代碼級性能測試
代碼級性能測試,是指在單元測試階段就對代碼的時間性能和空間性能進行必要的測試和評估,以防止 底層代碼的效率問題在項目后期才被發現的尷尬。
如果你從事過性能測試相關的工作,一定遇到過這樣的場景:系統級別的性能測試發現一個操作的響應 時間很長,然后你要花費很多時間去逐級排查,最后卻發現罪魁禍首是代碼中某個實現低效的底層算 法。這種自上而下的逐級排查定位的方法,效率通常都很低,代價也很高。
所以,我們就需要在項目早期,對一些關鍵算法進行代碼級別的性能測試,以防止此類在代碼層面就可 以被發現的性能問題,遺留到最后的系統性能測試階段才被發現。
但是,從實際執行的層面來講,代碼級性能測試並不存在嚴格意義上的測試工具,通常的做法是:改造 現有的單元測試框架。
最常使用的改造方法是:
1. 將原本只會執行一次的單元測試用例連續執行n次,這個n的取值范圍通常是2000~5000;
2. 統計執行n次的平均時間。如果這個平均時間比較長(也就是單次函數調用時間比較長)的話,比 如已經達到了秒級,那么通常情況下這個被測函數的實現邏輯一定需要優化。
這里之所以采用執行n次的方式,是因為函數執行時間往往是毫秒級的,單次執行的誤差會比較大,所 以采用多次執行取平均值的做法。
第四,壓力測試
壓力測試,通常指的是后端壓力測試,一般采用后端性能測試的方法,不斷對系統施加壓力,並驗證系 統化處於或長期處於臨界飽和階段的穩定性以及性能指標,並試圖找到系統處於臨界狀態時的主要瓶頸 點。所以,壓力測試往往被用於系統容量規划的測試。
還有些情況,在執行壓力測試時,我們還會故意在臨界飽和狀態的基礎上繼續施加壓力,直至系統完全 癱瘓,觀察這個期間系統的行為;然后,逐漸減小壓力,觀察癱瘓的系統是否可以自愈。
第五,配置測試
配置測試,主要用於觀察系統在不同配置下的性能表現,通常使用后端性能測試的方法:
1. 通過性能基准測試(Performance Benchmark)建立性能基線(Performance Baseline);
2. 在此基礎上,調整配置;
3. 基於同樣的性能基准測試,觀察不同配置條件下系統性能的差異,根本目的是要找到特定壓力模式 下的最佳配置。
這里需要注意的是,“配置”是一個廣義配置的概念,包含了以下多個層面的配置:
宿主操作系統的配置; 應用服務器的配置; 數據庫的配置; JVM的配置; 網絡環境的配置; …
第六,並發測試
並發測試,指的是在同一時間,同時調用后端服務,期間觀察被調用服務在並發情況下的行為表現,旨 在發現諸如資源競爭、資源死鎖之類的問題。
談到並發測試,我就不得不和你說說“集合點並發”的概念了,它源於HP的LoadRunner,目前已經被廣 泛使用了。那,到底什么是“集合點並發”呢?
假設我們希望后端調用的並發數是100,如果直接設定100個並發用戶是無法達到這個目標的,因為 這100個並發用戶會各自執行各自的操作,你無法控制某一個確定的時間點上后端服務的並發數量。
為了達到准確控制后端服務並發數的目的,我們需要讓某些並發用戶到達該集合點時,先處於等待狀 態,直到參與該集合的全部並發用戶都到達時,再一起向后端服務發起請求。簡單地說,就是先到的並 發用戶要等着,等所有並發用戶都到了以后,再集中向后端服務發起請求。
比如,當要求的集合點並發數是100時,那么前99個到達的用戶都會等在那里,直到第100個用戶到了, 才集中向后端服務發起請求。當然,實際達到服務器的並發請求數,還會因為網絡延遲等原因小 於100。
所以,在實際項目中,我建議在要求的並發數上進行適當放大,比如要求的並發數是100,那我們集合 點並發數可以設置為120。
第七,可靠性測試
可靠性測試,是驗證系統在常規負載模式下長期運行的穩定性。
雖然可靠性測試在不同公司的叫法不同,但其本質就是通過長時間模擬真實的系統負載來發現系統潛在 的內存泄漏、鏈接池回收等問題。
由於真實環境下的實際負載,會有高峰和低谷的交替變化(比如,對於企業級應用,白天通常是高峰時 段,而晚上則是低峰時段),所以為了盡可能地模擬出真實的負載情況,我們會每12小時模擬一個高峰 負載,兩個高峰負載中間會模擬一個低峰負載,依次循環3-7天,形成一個類似於“波浪形”的系統測試 負載曲線。
然后,用這個“波浪形”的測試負載模擬真實的系統負載,完成可靠性測試。同樣地,可靠性測試也會持 續3-7天。