前言

嗯…因為近期有被問到說,我會怎麼做壓力測試,覺得自己答的沒有很好,花了一個下午吃了幾篇文章,把目前看到的東西整理一下。

何謂壓力測試

軟體測試中的壓力測試,是在超過正常運作條件以外的條件下運作系統,以確認軟體體質、可用性的一種測試驗證方式。一般來說,壓力測試會看軟體在高負載下的 Robustness、可用性及異常處理,以及哪些在一般使用環境下算是正常行為。例如一個網站頁面預期是 100 個人同時點擊訪問,壓力測試就要是採用 120 個 (略高) 同時點擊的條件測試。 — 參考自維基百科 Stress testing (software)

根據維基百科的說明,我們可以透過壓力測試,得知軟體 (網站 / API 等) 在一般情況、異常情況下,能夠被多少人訪問存取,系統能承受到多少,反應速度如何,系統是否會發生異常,系統承載量是不是符合預期等,藉由不同的假設,來確認我們設計的軟體,足以應對各種使用場景,讓使用者有良好的體驗。

簡言之,透過壓測,了解系統正常最多可吃多少的訪問量 (不會慢),異常時多少會掛掉。

需要壓測的場景

現實生活中,有很多實務場景,常常需要為系統做好「承受能力」的測試,例如:

  • 演唱會搶票
  • 遊戲上線公測
  • 網路預約施打疫苗
  • 預約申辦 499 吃到飽
  • 雙 11 整點下殺一折商品搶購
  • Twitter 巴魯斯季

若沒有妥善預估好服務應承受合理的人次/訪問次數,做好規劃,等到使用者同時擠進來,則可能會造成服務中斷,背後損失的成本難以預估。

壓力測試計畫

先確認好「測試目標場景」,在制定壓測的方式,如何打到有效的數據;記得,我們要的是「壓測 > 改善 > 壓測」,也就是說,壓測的最終目的就是:藉由壓測結果,取得系統可改善的標的

舉例來說,系統即將於早上 10:00 開放線上預約施打疫苗,預估總預約人數為 10,000 人,假設使用者怕預約不到,全部都很準時想要搶在 10:00 馬上登入預約,則可預期:

  • 瞬間訪問請求數為 10,000 次 (每人 1 次) (正常情況下)
  • 瞬間訪問請求數為 20,000 次 (每人 2 次) (進不來 F5 重整)
  • 瞬間訪問請求數為 40,000 次 (極端條件/最差情況,可能為預估次數的數倍)

在可預期的情況下,我們希望:

  1. 正常情況下,系統應一路順暢,每個請求回應都是低延遲,快速反應
  2. 比正常情況更頻繁的訪問下,雖然每個請求回應可能比正常情況下,延遲略高一點,但不會讓使用者等待過久
  3. 極端情況下,系統不能直接噴/掛掉給使用者看

依據「反應時間」制定測試計畫 (舉例):

  1. 在 2 秒內,模擬達到 10,000 人次訪問,其平均反應時間應在 0.05 秒,且請求成功率為 100%
  2. 在 2 秒內,模擬達到 20,000 人次訪問,其平均反應時間應在 0.12 秒,且請求成功率為 100%
  3. 在 2 秒內,模擬達到 40,000 人次訪問,其平均反應時間應在 0.55 秒,且請求成功率為 100%
  4. 嘗試更高的極限條件,讓反應速度慢到會讓使用者感到不高興 (例如反應時間 5 秒),並針對此情況設計如何優化
  5. 嘗試更高的極限條件,把系統打到掛掉,紀錄極限值,並針對此情況設計如何恢復系統

上述 1~4 又稱為負載測試,這類測試只是為了知道系統可承受的量,所制定的測試計畫;

而 5 可稱為壓力測試,這類測試會制定極端條件,找出系統故障之後的行為,才能知道如果真的發生了,要如何恢復系統。

效能指標

這邊列舉幾個指標供參考:

  • 1 分鐘內,每秒可載入多少頁面
  • 1 分鐘內,可接受完成幾次 API 請求
  • 平均頁面載入時間
  • 平均圖片載入時間
  • 請求失敗次數/失敗率
  • 模擬的客戶人數,與分散訪問時間,例如 10 秒內,每秒幾人訪問,共幾次請求,請參考下圖。
出處 https://techmoon.xyz/loader-io/,此圖為模擬 20 秒內,達到每秒 100 個使用者訪問,共 20,000 次請求 出處 https://techmoon.xyz/loader-io/,此圖為模擬 20 秒內,達到每秒 100 個使用者訪問,共 20,000 次請求

相關工具

  • Apache Bench 適合用於負載測試,比起 JMeter 較為陽春,但速度較快 (日後認真用過再補充)
  • Apache JMeter 支援終端機指令,同時提供 GUI 介面,測試功能較齊全,但要學習使用也比較花時間 (用過一次,但沒有很熟,日後再補充)
  • nodejs 非同步請求,做負載測試,單純用來狂打,可以看硬體扛不扛得住這種瞬間併發 (CPU 會不會飆到 100%,記憶體會不會被吃滿)
  • guzzle 非同步請求,同上
  • Google PageSpeed Insights 這個不是壓測工具,但也可用於分析網頁載入效能

題外話:如何優化

  • 後端程式方面,可使用 php-monitor 這類工具,觀察執行過程看哪邊在慢,重複進行壓測、改善、壓測的循環,藉此提升效能;如果與預期效能差距過大,或許要考慮換個更適合對應場景的語言、第三方服務等方式,提高整體服務效能
  • 承上,從觀測到慢的地方著手改善,例如替不用每次都返回最新的資料加上快取、靜態資源透過 cdn 快取、慢查詢透過優化 SQL Query 、設索引等方式優化調整
  • 後端機器方面,可藉由垂直擴展 (加大 CPU、Memory),或是水平擴展 (新增服務作 LB 分流) 等課金手段優化效能

最後

大力推薦可以去看一下 這篇文章 ,令我收穫良多。

此篇文章標題原本定調為「如何壓力測試」,主軸會是如何使用工具進行壓力測試,但網路上已經有很多篇文章介紹如何使用,因此推翻重寫,主題改為「了解壓力測試」,試著把他搞清楚,這樣之後才不會只是為了測試而測試,卻始終不知到底為何而測試,而是理解「明確知道何為測試的目標、目的」,才去進行壓力測試。

目前覺得寫得還不是很理想,覺得還有很多沒有講到或是寫得太淺我就廢,日後會再使用過工具後,另寫一篇關於工具使用的文章,順便認真看一下 ab 跟 JMeter 有何差別;有任何問題或想法,歡迎留言交流,如果寫的內容有錯誤的地方,希望能不吝指點,感謝。

參考連結



文章作者: littlebookboy
永久鏈結: https://blog.genesu.me/2021/06/learn-about-stress-testing/
許可協議: 署名-非商業性使用-相同方式共享 4.0 國際(CC BY-NC-SA 4.0)