1. 程式人生 > >效能、負載、壓力測試——從效能測試角度理解系統開發

效能、負載、壓力測試——從效能測試角度理解系統開發

引言

最近,由於舊機器下線,我對過去部署的一些服務做了遷移,順帶對新部署的服務做了一個簡單的效能測試。在實施過程中,我發現自己對很多效能指標的理解很不清晰,對於併發數壓力吞吐量延遲等概念,通常是以望文生義的方式使用。對於系統應該關注什麼樣的效能指標,認識也不完整。為此,我閱讀了wiki百科以及一些部落格,希望能對這方面的概念有一個較完整的認識。

跑個題,最近重新提到了工程能力。這個詞包含的範圍很廣,從技術路線選擇、系統可維護性,到程式碼可讀性、系統性能優化等,凡是能想到的有利於實現功能、提高效率的實踐,似乎都可以被歸為這個能力。然而,可以確定的是,工程能力的很大一部分體現,都與效能指標及其優化有關。如果在實現一個服務或系統時,對效能指標沒有足夠的關注,對效能相關的問題沒有胸有成竹的回答,則很難說是有足夠的工程能力。

本文的主要內容是對效能測試做了簡要總結。通過閱讀維基百科及一些部落格,瞭解效能測試的內容、指標、方法、目標。對這些文章做了一些摘要、總結、翻譯。

本文分為以下幾部分:第二部分,是效能測試的分類,主要內容來自維基百科;第三部分,是如何實施效能測試,主要注意哪些問題,以及優化的方向,內容來自維基百科以及Grig Gheorghiu的兩篇部落格;第四部分,是如何區分效能測試、負載測試、壓力測試,內容主要來自Grig Gheorghiu的兩篇部落格。

效能測試分類

在維基百科上效能測試的定義是

In software engineering, performance testing is in general, a testing practice performed to determine how a system performs in terms of responsiveness and stability under a particular workload. It can also serve to investigate, measure, validate or verify other quality attributes of the system, such as scalability, reliability and resource usage.

第一層含義是判斷在一定工作負載下,系統響應能力穩定性。進一步延伸,包括測量、驗證系統的其他質量屬性,如可擴充套件性可靠性資源消耗

效能測試可以包括但不限於以下型別:

  1. 負載測試(load testing)
    負載測試的目的,是為了解在預期的工作負載下,系統的行為。
  2. 壓力測試(stress testing)
    壓力測試是為了解系統提供服務能力的上限,瞭解系統在超出預期的壓力下是否足夠穩定。使我們瞭解如果當前負載增加至超出設計範圍,系統是否能承受。
  3. 滲透測試(soak testing)
    滲透測試也叫忍耐力(endurance)測試,瞭解系統能否較長時間持續支撐的某個負載量,是否在持續的負載下會導致效能下降。
  4. 尖峰測試(spike testing)
    尖峰測試是突然增加或降低負載,看系統在負載量突然變化時的行為。
  5. 斷點測試(breakpoint testing)
    斷點測試與壓力測試很相似,持續增加系統的負載,觀察系統是否在預期的負載壓力下出現效能下降或失敗。
  6. 配置測試(configuration testing)
    觀察修改系統配置,會對系統行為造成怎樣的影響,例如負載均衡的配置。
  7. 隔離測試(isolate testing)
    隔離測試並非一個獨立的測試專案,而是通過不斷地重複某種測試,將出現問題的部分隔離出來。
  8. 網際網路測試(internet testing)
    網際網路測試通常是對全球性的服務來說的。測試負載的生成者,來自實際的目標使用者所在地。

上面的分類摘自維基百科。可以看出,不同型別測試有重疊甚至重複的部分,但每種測試又有其各自的目的。負載測試(load testing)和滲透測試(soak testing)可以同時進行。壓力測試(stress testing)、尖峰測試(spike testing)和斷點測試(breakpoint testing)似乎也可以同時進行,只要針對不同的目的做好對應的記錄。如果出現問題,所有測試的目的最終都是將問題區域隔離出來(isolate testing)以進行優化。

如何實施效能測試

效能測試的目的和效能目標

首先需要明確的一個問題是“why are we performance-testing?”。從目的來看,效能測試可以用來:

  • 驗證系統達到預期的效能要求;
  • 對比兩個系統,看哪個系統性能更好;
  • 找出系統的瓶頸以便優化

不同的系統有不同的效能目標,但是通常都包含以下幾個:

  1. 併發量。對於有使用者登入狀態的系統,同時服務的使用者數通常是一個考量指標,因此併發量是一個重要效能目標。
  2. 吞吐量。對於無使用者登入狀態,吞吐量或者transaction rate是其關注的指標。
  3. 響應時間。從伺服器端看,是從系統接收到請求,到系統發出反饋的時間。或者從客戶端機器看,從客戶端發出請求,到客戶端收到響應的時間,壓測指令碼通常只能測到這個時間。伺服器端的時間,需要通過日誌等方式記錄。

效能規格

效能測試之前應該有一個明確的效能規格說明,並且落地成文件。理想情況下,這個效能規格應該在需求階段就制定下來,並且應該先於任何系統設計。

效能規格通常應該至少回答以下問題:

  1. 效能測試的範圍是什麼?哪些子系統,哪些介面,哪些元件要被測試?要測試它們的哪些效能目標?
  2. 對於有使用者介面的系統,使用者併發量是多少?峰值和均值預期是多少?
  3. 目標系統是什麼樣子?包括系統環境、網路配置、硬體配置?
  4. 每個會話中各環節的負載比例是如何的?(登入20%,搜尋40%,登出10%,選擇30%)
  5. 系統中各會話的負載比例是如何的?(A回話20%,B會話40%,...)
  6. 後臺批處理的時間要求什麼?

前提條件

效能測試需要滿足的條件包括:

  1. 系統穩定,或者待測的介面穩定。因為效能測試的目的不是發現bug,而是發現瓶頸。
  2. 目標明確。響應時間、併發、吞吐量?

儘可能滿足的條件是:

  1. 與系統使用真實環境保持一致

效能測試應該儘可能早地開展,因為越早發現瓶頸,修復的代價越小。

測試工具

分為兩部分:

  1. 一部分是用於模擬請求的performance scripting,包括HP LoadRunner, NeoLoad, Apache JMeter, Rational Performance Tester, Silk Performer和Gatling;
  2. 一部分是用於監控系統狀態的monitor,包括系統本身的日誌,以及監控CPU、記憶體、磁碟、網路的使用情況。

實施與優化

當目標、環境和工具已經就緒後,可以開始啟動客戶端模擬。對於一般的效能測試,目的是發現效能瓶頸,通常的做法是逐漸增加負載,記錄並觀察各項指標的變化。

當發現系統的效能指標達不到預期時,以web服務為例,通常的優化思路是:

  1. 首先需要優化的是應用程式資料庫。程式碼邏輯是否足夠高效?資料庫的查詢是否高效?資料庫是否針對常用查詢語句做了優化?可以用的工具有jUnitPerf和pyUnitPerf。

如果上述方案還無法滿足,可以考慮以下思路:

  1. 增加Cache是否能提升效率;
  2. 對常用頁面靜態化;
  3. 考慮使用負載均衡,對系統進行橫向擴充套件;
  4. 將服務劃分為只讀/讀寫;
  5. 提升機器的硬體效能,SSD、CPU、記憶體等;
  6. 提升網路頻寬。

效能、負載、壓力測試的區別

這一步分的內容完全來自於Grig Gheorghiu的部落格,可以在原文看到更詳細的解釋。

效能測試(performance testing)、負載測試(load testing)、壓力測試(stress testing)三個概念經常被替換著使用,因為他們在實施方式上有相同的地方,但他們也確實有一些區別。在本文第一部分效能測試分類中,已經大致介紹了概念上的區別,主要體現在目的不同。

  1. 效能測試。目的是發現系統瓶頸,併為系統設定一個性能baseline,以便為後續的優化設定一個參照。通常是白盒測試。
  2. 負載測試。目的是確認系統是否滿足某負載要求,以及發現在高負載下是否會出現低負載無法出現的bug。通常是黑盒測試。
  3. 壓力測試。目的是看系統在異常環境,如壓力過大、網路斷開、磁碟故障、資源不足等情況下的表現,檢查系統的穩定性、對異常的恢復能力。

其實只要測試的目標明確,具體使用哪個名字並無太大關係。