1. 程式人生 > ><轉>性能測試淺談

<轉>性能測試淺談

專業知識 事故 線程 現在 精確 個人 相關 大量 得出

本文主要針對WEB系統的性能測試。不涉及具體的執行操作,只是本人對性能測試的一點理解和認識。

  性能測試的目的,簡單說其實就是為了獲取待測系統的響應時間、吞吐量、穩定性、容量等信息。而發現一些具體的性能相關的缺陷(如內存溢出、並發處理等問題),我認為只是一種附加結果。從更高的層次來說,性能測試最想發現的,是瓶頸。如何能得到所需要的信息,就需要從多方面進行測試。

  性能測試的內容

  性能測試種類的劃分與定義這裏就不說了,各有各的說法,比如性能測試、負載測試、壓力測試這三個詞,在網上能找到N個版本的定義,大體理解就行了,沒必要在文字層面上較這個真。以下的內容也只是我個人的理解,一些名詞的定義可能和其他資料有所不同,但在我的工作中,這樣是比較形象和容易理解的。

  在實際工作,一般的應用系統會從這麽幾個方面進行性能測試。

  1.基準測試   Benchmark或者Baseline測試。一般為單用戶測試,或者是零數據量環境下的測試。目的在於建立一個可度量的參考標準,為其他測試場景或者調優過程提供對比參考。也可認為是最基礎的性能測試,如果基準測試的結果都不能達到預期要求,那麽後續場景也就沒必要測試了。

  2.日常壓力測試   在基準測試通過後,應該先進行較小壓力下的測試,首先對系統在日常壓力下的表現進行測試。此壓力需要根據系統使用相關數據得出,如系統平均每天訪問量、平均在線人數、每日完成事務數等。通過此測試,發現一些較表面的性能問題並進行處理。

  3.峰值壓力測試   在日常壓力測試通過後,需要進行更大壓力的測試。此處壓力同樣需要相關數據的支持,一般為未來幾年後的預期壓力。可根據歷史日均壓力、日最高壓力等信息,估算出未來幾年的日均以及日最高壓力。再通過一些通用估算方法、如二八原則(80%的工作在20%時間內完成,相當於2小時完成一天8小時的工作量),將日壓力轉換成峰值壓力。   峰值壓力為可預期到的最大負載壓力,通過了此測試,則認為系統有能力滿足未來增長的壓力。

  4.容量測試   驗證了系統是否可滿足預期的壓力後,還需要知道系統能夠承受的最大壓力,也就是容量。一般通過“拐點法”進行測試,逐步增大系統的壓力,直到性能指標不可接受或者出現了明顯的拐點。如下圖,拐點在哪?

技術分享圖片

  5.穩定性測試   驗證系統是否可長期穩定的運行,是否存在一些短時間內可能無法發現的缺陷(如內存溢出、數據庫連接不釋放等)。為了縮短測試工期,一般可將預期一天的壓力集中在2小時內完成(二八原則),這樣持續加壓10小時,便相當於系統運行5天。註意監控各種性能指標是否平穩,有無下降。

  以上幾種類型的測試,是性能測試過程中最多用到的。當然也也其他一些比較常用的類型,如絕對並發測試,測試多用戶對某一功能的瞬時請求,主要用於驗證系統是否存在並發邏輯上的處理問題。此測試也可劃分到不同的壓力測試場景中去,根據不同的用戶壓力,測試相應的絕對並發,一般取在線用戶數的10%進行測試;突發壓力測試,對一些不在預期內的突然壓力進行測試(其實既然想到了,就應該是在預期內了)。以銀行門戶網站為例,可能會由於發布了一條重要消息(政策調整)而導致訪問量激增,這種壓力是否會導致系統宕機或者暫時無法提供服務,就是突發壓力測試需要考慮的了。也有人將此壓力定義為峰值壓力,這就無所謂了,只要考慮到會有這麽一個問題就夠了。

  性能測試的階段

  上面主要說的是測試內容的劃分,也就是說做性能測試時要考慮到的幾個方面。從實際執行層面來看,測試的過程一般分為這麽幾個階段:

  1.測試確認   理解被測系統、尋找測試點、確認測試範圍、測試環境等。一些重要信息需要同PM、需求人員、設計人員討論確認,如用戶最常用哪些功能、最關註哪的性能,程序上哪可能是壓力點,哪些數據需要模擬到真實的量級,大體上需要使用哪種測試方法。

  2.確定通過標準   性能是好是壞、測試是否通過,必須有明確的標準。這個標準,主要從客戶的期望和業務上的需求兩方面來考慮,客戶的期望一般指頁面上的響應時間,業務需求則是系統的處理能力,一般為吞吐量或TPS(每秒完成事務數)。標準制定的不合理,測試結果可能無法反映系統真實的性能表現,或者會讓客戶無法接受我們認為通過的軟件。   至於具體如何去設定,是需要同業務負責人(一般為PM)和技術負責人(一般為設計人員)共同確認的,業務負責人了解用戶的實際需求和期望,技術負責人了解具體的實現,可以判斷哪些是不可達到的要求。   一旦達成了共識,那麽測試就要嚴格的按照標準去執行。

  3.測試設計   主要從上面提到的幾個方面進行分析,針對系統的特點設計出合理的測試場景。為了讓測試結果更加準確,這裏需要很細致的工作。如建立用戶模型,只有知道真實的用戶是如何對系統產生壓力,才可以設計出有代表性的壓力測試場景。這就涉及到很多信息,如用戶群的分布、各類型用戶用到的功能、用戶的使用習慣、工作時間段、系統各模塊壓力分布等等。只有從多方面不斷的積累這種數據,才會讓壓力場景更有意義。最後將設計場景轉換成具體的用例。   測試數據的設計也是一個重點且容易出問題的地方。生成測試數據量達到未來預期數量只是最基礎的一步,更需要考慮的是數據的分布是否合理,需要仔細的確認程序中使用到的各種查詢條件,這些重點列的數值要盡可能的模擬真實的數據分布(數據統計信息、執行計劃相關的內容,此處就不細說了),否則測試的結果可能是無效的。   此外,性能測試執行過程中,需要監控收集的各種指標數據,也需要明確下來。

  4.測試環境準備   部署測試環境,生成測試數據,環境預調優等等。預調優指根據系統的特點和自己的經驗,提前對系統的各個方面做一些優化調整,避免測試執行過程中的無謂返工。比如一個高並發的系統,10000人在線,連接池和線程池的配置還用默認的,顯然是會測出問題的。

  5.測試執行、監控   準備測試腳本,執行之前設計好的各個用例,監控並收集需要的數據。出現問題時,切記要全面的保留事故現場、或者是能進行分析的數據。比如TOMCAT不再響應,不能只把這個現象記錄下來,這對問題的排查定位是沒有意義的,要保留所有相關的日誌,導出線程轉儲和堆轉儲。

  6.問題分析定位、調優   發現問題或者性能指標達不到預期,及時的分析定位,處理後重復測試過程。   性能問題通常是相互關聯相互影響的,表面上看到的現象很可能不是根本問題,而是另一處出現問題後引起的反應。這就要求監控收集數據時要全面,從多方面多個角度去判斷定位。   調優的過程其實也是一種平衡的過程,在系統的多個方面達到一個平衡即可。

  7.性能報告   將測試過程中記錄的各種數據匯總成報告,將各方面需要的結果清楚的展現出來。

  上面所有內容中,如果排除技術上的問題,性能測試中最難做好的,就是用戶模型(或者叫系統使用模型)的分析。它直接決定了壓力測試場景是否能夠有效的模擬真實世界壓力,而正是這種對真實壓力的模擬,才使性能測試有了更大的意義。可以說,性能測試做到一定程度,差距就體現在了模型建立上。

  至於性能問題的分析、定位或者調優,很大程度是一種技術問題,需要多方面的專業知識。數據庫、操作系統、網絡、開發都是一個合格的性能測試人員需要擁有的技能,只有這樣,才能從多角度全方位的去考慮分析問題。

  當然,對於測試人員來說,技術能力只能排在第二號,測試思想才是最根本的。敏銳的嗅覺、嚴謹的邏輯、合理的推測、大膽的實踐是一個合格測試工程師的必備要素。

  模擬演練

  寫了一大堆,新手還是不知道如何去做。其實寫本文的目的也不是講具體操作,而是思想,思想。新手學性能測試,建議找一本從LOADRUNNER開講的書比較好。如51TESTING上有連載的《性能測試從零開始》。

  不過還是盡量說點具體些的內容吧。

  普通BS架構的系統,一般都采用測試工具(如LR)直接錄制手工操作的方式進行測試。這種方式簡單有效,對測試人員要求不高。但在一些情況下,這種基於錄制的方法可能無法完成,比如頁面上有特殊控件、系統是CS架構、或者通訊的協議無法捕獲等。這時就需要更復雜的測試方法,如手動編寫模擬客戶端的JAVA代碼,而把測試工具當作一個調度控制臺,去調度大量的虛擬用戶線程執行編寫好的代碼。

  現在假設有一個簡易版的12306網站,JAVA實現,中間件為TOMCAT,數據庫為SYBASE,沒有集群處理(一切從簡,只有查詢和訂票功能)。如何對它進行性能測試呢?

  按照上面的幾個步驟來想一想吧,這裏只簡單寫幾點。

  第一步,測試確認。海量並發,數據也應該是海量的,但基本都是簡單查詢,沒有復雜的統計,所以主要困難還是在海量並發事務的處理上。中間件、數據庫上都會承受巨大壓力。此類高並發系統還需要對一些功能特別註意,比如一個車次有10張票,5個人同時購票,如何處理?如果是12個人同時點購票,又是如何處理?

  第二步,通過標準。無非是系統能夠滿足多少人同時在線,一分鐘內能處理多少訂單,用戶最大等待時間是幾分鐘。註意這個標準一定要是經過各方面確認過實際可行的啊,定一個訂單響應時間不超過5秒有意義麽?確認了以後,就要按著這個目標來設計測試和執行。

  另一個需要註意的問題,按照預期的壓力測試通過了以後,是不是就高枕無憂了?答案是否定的,因為很可能這個預期或者標準是不合理的,這個是非常可能的,只有長期的數據積累,才會一點點走向精確。想想奧運訂票系統,開通後短短五分鐘,網站就癱瘓了,你們以為這種系統沒有經過專業的性能測試麽?據我所知,奧運訂票系統性能測試時制定的標準是每分鐘處理四百萬訪問(具體數據記不住了,就假設是這個數吧),出事後的檢查發現,每分鐘的訪問量超過了八百萬。這種事故責任在誰呢?測試機構敢拍胸脯保證,每分鐘處理四百萬就是沒問題的。而奧組委自己設定的每分鐘四百萬目標,和實際出現偏差也是正常的,畢竟這種系統是第一次上線。最後的處理方法就是,壓力達到了預期最大值以後,再後來的訪問就被排隊了。好好體會這個案例吧,會有收獲的。

  第三步,測試設計。設計用戶模型,設計測試場景,設計測試用例。一個典型的用戶是如何使用系統的?登錄、查詢車次余票、訂票、付款,這是理想化的情況。實際更可能是這樣的,登錄(一次登不進去,重復多次)、查詢A車次(未到放票時間、不斷重試,時間到無票)、查詢B車次(無票)、查詢C車次(有票)、訂票、付款、查詢訂單。兩種交互方式對系統產生的壓力,差別是很大的。

  將多個用戶行動整合到一起,也就是用戶模型,或者叫系統使用模型,是壓力場景設計的依據。假設系統一天的訪問量是一萬個用戶,這一萬訪問量是在24小時內平均分布的,還是分布在8小時內,還是在某一時間點上集中訪問?這些具體到用例中也就是虛擬用戶的加載策略,直接決定了壓力的大小。

  除了這個壓力場景,針對此系統還需要進行絕對並發測試,參考第一步的分析。

  第四、五步就不細說了,準備環境、數據,針對大量用戶的並發進行一些預調優。按照第三步設計好的各個測試用例準備腳本、執行測試。

  第六步,發現問題了怎麽辦?比如1000人的壓力下,系統響應就比較慢了,查詢車次需要1分鐘,下訂單需要2分鐘,接下來要做什麽?能把這些作為一個性能缺陷提起麽?顯然是不可以的,這只是通過你的壓力測試場景產生的一個現象,可能是測試腳本有問題、也可能是測試環境有問題。作為一個性能測試人員,需要盡量深入的定位到問題產生的原因。就像這個響應慢,只是一個表面現象,慢在哪?是中間件還是數據庫?一些簡單的測試方法就可以進行判斷,如在頁面上進行一些數據庫無關的操作,如果依然比較慢,說明在中間件上壓力就已經比較大了。還可以部署另一套中間件測試環境,連接之前相同的數據庫,在壓力測試出現問題的同時,手動訪問新部署的應用(只有一個用戶),如果同樣很慢,那說明慢在了數據庫端的處理上。還可以通過日誌的方式更準確的進行判斷,如應用日誌和數據庫SQL執行日誌。總之方法是多種多樣的,但目的只有一個,就是不斷的排除無關部分、縮小問題範圍。

  定位到了中間件和數據庫之一,然後又該怎麽辦?此時恐怕就需要一些相關方面的專業知識了,但其實最常見的還是那些。中間件相關的一般是線程池、JVM、數據庫連接池等,數據庫相關的有鎖、緩存、IO(一般就是SQL語句的問題)等。要進行全面的監控和分析,再做一些合理的調優並重復測試。

  問題定位到什麽程度才行?我認為是要讓人看了知道改哪就可以了。比如提一個“這個SQL語句進行了大量的物理IO,性能不好”,這就不是個好問題,物理IO是什麽?怎麽改?如果這麽說就好多了“這個SQL語句沒有使用索引,導致了全表掃描,進行了大量的物理IO,性能不好。如果要避免全表掃描,需要調整SQL語句或者添加XX索引”,這才是定位問題。

  當然了,上面只是一個非常簡陋的舉例,真實的性能測試要比這復雜的多。

  總的來說,我認為,性能測試的難度主要不在技術手段上,互聯網時代技術都是共享的,要善於去搜索利用他人的成果。即使自己搞不定,團隊內一定還有專業的開發工程師、數據庫管理員、系統管理員可以幫你搞定。真正的難點在於,你要想出來如何去測是有效的、有保障的,這才是測試工程師最重要的能力。

<轉>性能測試淺談