「壓力測試」這個詞在工程師的對話裡大概有三種意思,視說話的人是誰而定。這三種意思指的不是同一件事。
Load Testing:用預期的正常流量(或高峰流量)持續打系統,驗證在這個負載下 latency 和 error rate 是否在 SLO 以內。問的是「這個系統夠不夠用」。
Stress Testing:持續增加負載,直到系統開始降解——latency 暴增、error rate 上升、memory 用光。問的是「系統的極限在哪裡,超過極限時會優雅降級還是直接崩潰」。
Chaos Testing / Chaos Engineering:不是打流量,而是故意在 infrastructure 層製造故障——殺掉一個 pod、切斷網路、讓磁碟滿掉。問的是「當基礎設施出現預期外的故障,系統有沒有設計好的 fallback,還是直接連帶崩潰」。
Load Testing:驗證 SLO
Load test 的目標是確認系統在預期流量下的行為符合 SLO。腳本模擬真實用戶行為,持續一段時間(通常 15–30 分鐘),監控 p50 / p95 / p99 latency 和 error rate。
k6 的 load test 腳本:
import http from 'k6/http'
import { check } from 'k6'
export const options = {
vus: 100, // 100 個虛擬用戶
duration: '30m', // 跑 30 分鐘
thresholds: {
http_req_duration: ['p95<500'], // 95% 請求要在 500ms 內
http_req_failed: ['rate<0.01'], // 錯誤率 < 1%
},
}
export default function () {
const res = http.get('https://api.example.com/orders')
check(res, { 'status 200': (r) => r.status === 200 })
}Load test 的結果用來回答「我的系統在這個流量下夠不夠用」,以及「在上線前對 SLO 做一次壓力確認」。
Stress Testing:找系統極限
Stress test 用 ramp-up 的方式持續增加負載,直到系統明顯降解。目的不是讓系統通過測試,而是找到「在什麼負載下系統開始撐不住」,以及超過極限時的行為是否可接受(graceful degradation vs crash)。
export const options = {
stages: [
{ duration: '5m', target: 100 }, // 爬升到 100 VU
{ duration: '5m', target: 500 }, // 爬升到 500
{ duration: '5m', target: 1000 }, // 繼續加壓
{ duration: '5m', target: 0 }, // 降回 0,觀察恢復
],
}降回 0 後的恢復觀察很重要——系統在解壓後能不能自己恢復,還是需要重啟?這影響 on-call 的 runbook 設計。
Chaos Testing:驗證容錯設計
Chaos testing 不測流量,測的是基礎設施故障下的系統韌性。Netflix 的 Chaos Monkey(隨機殺 EC2 instance)是這個概念的起源。
現代 Kubernetes 環境:
- Chaos Mesh(CNCF):可以注入 pod failure、network partition、CPU/memory pressure、磁碟故障
- Litmus:類似功能,有完整的 chaos 實驗 workflow
Chaos test 問的問題:
- 殺掉一個 pod,Kubernetes 重啟它的期間,用戶有沒有感知?
- 兩個 AZ 之間的網路切斷,系統會不會 split-brain?
- DB primary 掛掉,failover 切到 replica 需要多久?這段時間 error rate 是多少?
三者的使用時機
| 問的問題 | 適合時機 | |
|---|---|---|
| Load Test | 正常/高峰流量下 SLO 是否達標 | 每次大功能上線前、定期 |
| Stress Test | 系統極限在哪裡 | 架構變更後、容量規劃前 |
| Chaos Test | 基礎設施故障時系統是否有韌性 | 微服務架構穩定後、Game Day |
三者不互相取代。Load test 通過不代表 chaos test 也會通過——一個系統可以在正常流量下表現完美,但在一個 pod 掛掉時引發 cascade failure。