2011/01/06

效能/負載/壓力測試的分別(Performance vs. load vs. stress testing)

這篇文章是在 Google 中以「Performance load stress testing」做關鍵字搜尋後所找到的第一篇文章《Performance vs. load vs. stress testing》。如果沒意外,這篇應該是網路上最人重視、並大量引用(已知 12 篇)、且有眾多留言(扣除作者的回覆在 100 篇以上)的文章。
Performance VS Load VS Stress Testing
從這個部落的名稱「Agile Testing」以及作者的介紹、及發表的文章來看,作者 Grig Gheorghiu 已從事 SW Tester 多年,對多種語言、腳本語言都有涉獵,也對 Agile 有相當的經驗,以實作的角度出發提出三者測試方式的差異,對 SW Tester 而言非常具有參考價值。

因此,通達人就請該作者同意翻釋、轉載該文,以供軟體業從業人員參考。

以下是原文的完整翻譯


這裏有一個對測試者(Tester)的面試問題:你如何定義效能/負載/壓力測試?在大多的時候人們交互地使用這些專有名詞,但他們實際上卻不能分辨有什麼不同。這篇文章是依照我過去的經驗對這些觀念所做的簡捷探討,但同時使用了以下文獻內對測試的定義:
  • Kaner的《Testing computer software》
  • Loveland的《Software testing techniques》
  • Nguyen的《Testing applications on the Web》

July 7th, 2005更新


從參考記錄(log)中我看到這篇文章在google內被頻繁地搜索,我更新它鏈接到我後來寫的《更多關於效能VS.負載測試(More on performance vs. load testing)》一文。

效能測試(Performance testing)


效能測試的目標不是要找缺陷(bug),而是要消除瓶頸和替未來的回歸測試(regression tests)建立一個底線,執行效能測試是在一個謹慎控制的量測和分析流程內進行,理想上軟體是在夠穩定的情況下進行測試,因此測試的過程可以很順利的進行。

對有意義的效能測試而言,更清楚地定義期望組是必要的,如果就系統的效能而言你不知道自己要去那裏,那你的方向就有點重要(記得愛麗絲和那隻嘻笑的貓),例如:對網頁程式(Web application)而言,你需要知道以下幾件事:
  • 在線的使用者或 HTTP 連線的期望負荷
  • 允許的回應時間
一旦你知道自己要去那,當你知道要找瓶頸時,你就可以藉由不斷地增加負荷到系統以達到你要去的地方。再舉網頁程式的例子,這些瓶頸會存在於不同層,你可以藉由以下工具準確地確定:
  • 在應用程式層,開發者可以使用 profiler 在他們的程式碼中 spot 無效率的地方(例如粗糙的搜尋演算法)
  • 在資料庫層,開發者和 DBA 可以使用資料庫專屬的 profiler 和 query 最佳化工具
  • 在作業系統層,系統工程師可以使用小程式,如:top、vmstat、iostat(在Unix類系統)和 PerfMon(在Windows)以觀察硬體資源,如:CPU、記憶體、swap、I/O磁碟;也能使用特殊化的 kernel 觀察軟體。
  • 在網路層,網路工程師能使用封包探測工具,如:tcpdump;網路協定分析器,如:ethereal;以及不同的小工具,如:netstat、MRTG、ntop、mii-tool。
從測試的觀點來看,上述活動會因為系統「從內部向外」(from the inside out)和不同角度被檢查和觀察而被認定是白箱測試的手法。

然而測試者也可以對測試系統用黑箱測試的手法執行負載測試。對網頁程式而言,測試者將使用模擬在線使用者或 HTTP 連線、與量測回應時間的工具,以這個目的而言有一些我過去使用過的輕量級開源工具:ab、siege、httperf,有我沒使用過的更重量工具有 OpenSTA,我也尚未使用 Grinder,但它在我的 TODO 清單中名列前矛。

當負載測試的結果說明系統效能不能滿足它的期望目標時,就是開始調校應用程式和資料庫的時候,你要先確保你的程式碼儘可能有效地執行、同時你的資料庫已在OS/硬體設定中最佳化,TDD practitioners 將會非常有效地找出先後順序的框架,如 Mike Clark 的 jUnitPerf 能提昇負荷測試和定時功能測試的既有單元測試程式碼,一旦一個特定功能或方法被數據表示和調校,開發者就能用 jUnitPerf 接著包裹它的單元測試和確保它符合負載和時效的效能需求,Mike Clark 稱這個為「持續效能測試」,我應該提及我曾經在 Python 下完成一個 jUnitPerf 的埠起始程式-我稱它為 pyUnitPerf。

在調校應用程式和資料庫後,如果系統就效能而言仍不能符合期望目標時,有一個調校步驟的陣列在前述的所有階段皆可利用,這裏有一些在應用程式程式碼之外你可以作的事、以提昇網頁程式效能的例子:
  • 使用網頁快取(cache)機制,例如由 Squid 所提供的;
  • 公開高需求的靜態網頁需求,這樣它們就不會接觸到資料庫;
  • 藉由負載平衡以度量伺服器農場;
  • 按比例度量資料庫伺服器、和切開讀/寫伺服器和唯讀伺服器,接著負載平衡唯讀伺服器;
  • 藉由增加硬體資源(CPU、記憶體、磁碟)垂直地度量網頁和資料庫伺服器;
  • 增加可用的網路頻寬;
效能調校有時比科學更藝術,因為十足複雜的系統糾纏創新的網頁程式,必須更注意修改時間後再作測量,除此之外多種變化微妙的相互作用會很難證明和重複。

在一些如測試試驗室的標準測試環境,將無法總能複製產品伺服器的配置,在這類例子中,將以產品環境分組分段測試環境,因此系統的預期效能需要相應的調低。

這個「執行負荷->量測效能->調校系統」的循環會一直重覆直到系統在測試到達期望效能水準,在這點,測試者會有一個系統處於一般條件下的底線,這個底線可以繼續在回歸測試中使用以衡量一個軟體新版本的效能。

其他效能測試的一般目標是建立系統在測試時的基準(benchmark)值,有非常多的工業標準基準值,例如:發行的 TPC 和許多硬體/軟體供應商會用各種方式微調他們的系統以獲得 TCP 前十名,這是每個人對效能宣稱都需要有的普遍知識,特別是提防任何不指明測試所使用硬體和軟體規格細節的宣稱效能。

負載測試(Load testing)


我們已經看到負載測試是效能測試與調校的一部份,在這個前題下,這意味藉由自動工具不斷地增加負載到系統,對網頁程式而言,負載被定義成在線使用者或 HTTP 連線。

在測試文獻中,「負載測試」一詞經常被定義成提供系統所能執行最大工作量下運作測試的流程,負載測試通常被稱為「容量測試」、或「壽命(longevity)/耐力(endurance)測試」。

容量測試的例子:
  • 藉由修改一個非常大的檔案以測試一個文字處理器;
  • 藉由傳出一個非常大的工作以測試一個印表機;
  • 藉由上千位使用者的收信匣以測試一個郵件伺服器;
  • 一個容量測試的特定案例是 0 容量測試,以確認系統能接受空的工作。

壽命/耐力測試例子:
  • 在 Client 端執行一個 client-server 應用程式以考驗伺服器在延長一段時間下的狀況

負載測試的目標


  • 揭露粗略測試的缺陷,如:記憶體控制的缺陷、記憶體洩露(leaks)、緩衝區溢位(buffer overflows)等;
  • 當效能測試時確保應用程式滿足效能建立的底線,這個是藉由執行回歸測試完成以確保應用程式的特定最大負載。
縱然效能測試和負載測試似乎看來一樣,但他們的目標不同。

首先,效能測試使用負載測試技術和工具以量測和基準化目的和使用多種負載等級。另一方面,負載測試操作一個預先定義的負載等級,通常最高負載下系統依然能運作正常。注意負載測試並不是要藉由壓倒它來中斷系統,反而是要嘗試維持系統持續運作像情況良好的機器。

在負載測試的內容中,我要強調有一個大資料庫以供測試極為重要,在我的經驗中,許多重要的簡單缺陷不會浮出除非你有像上千使用者的容器般非常大的實體,如:LDAP/NIS/Active Directory、上千封信的 mail 伺服器、數G(gigabyte)資料表的資料庫、多層的檔案/目錄架構的檔案系統...等,測試者明顯地需要自動化工具產生這些龐大的資料組,但幸運的是任何好的腳本語言(scripting language)都能勝任這項工作。

壓力測試(Stress testing)


壓力測試藉由超出系統資源或拿走系統資源(在這種情況下有時被稱為「負面測試」(negative testing))的情況下測試以嘗試中斷系統,主要的目的在確保系統失效和正常地回復-這在品質上稱為「可復原性」(Recoverability)。

效能測試需要一個受控制的環境和重覆量測,壓力測試則隨興地引發混亂和不可預測。再舉網頁程式的例子,這裏有許多壓力的方式可以應用於系統:
  • 雙倍於基線數目的在線使用者/HTTP 連線數;
  • 隨機地關閉和重啟網路上連接到伺服器的交換機/路由器的埠(例如透過 SNMP 命令);
  • 關閉資料庫再開啟;
  • 在系統執行時重建 RAID 陣列;
  • 執行消耗網頁/資料庫伺服器資源(CPU、記憶體、磁碟、網路)的程序;
我確信狡猾的測試者能以他們喜愛中斷系統的方式加強這個清單,然而,壓力測試並不是單純地為了想中斷系統而中斷系統,相反地它卻要求測試者觀察系統如何反應失效:
  • 它是否保存其狀態或它突然崩潰?它是否只是凍結或者它能和平的失效?
  • 在重啟時它有能力重回到上次正常的狀態?
  • 它會印出有意義的錯誤訊息給使用者或者它只是顯示一些難以理解的十六進制代碼?
  • 因為意外的失效危及到系統的安全?
這類案例不勝枚舉。

小結


我恐怕我只能就效能/負載/壓力測試內值得一提的爭議、工具和技術層面上提出我的看法,我個人找到這個特別豐富和有趣的效能測試和調校主題,我會嘗試在未來張貼更多這個主題的文章。

2 則留言:

  1. 正在學習了解negative testing從而拜讀到您的文章.
    感謝您的分享!

    回覆刪除