結論先講
功能測試回答「能不能動」,壓力測試回答「能撐多少人」。 兩個問題的答案都是「Yes」,系統才算準備好上線。大部分團隊只回答了第一個問題,然後在上線當天用真實用戶回答第二個。
一個你可能經歷過的場景
行銷團隊花了三個月準備大促活動。開發團隊準時交付,QA 全部通過,PM 信心滿滿地按下部署按鈕。
活動開始後 15 分鐘:
- API response time 從 200ms 飆到 8 秒
- 資料庫連線池耗盡,新請求全部排隊
- 錯誤率從 0% 跳到 40%
- 客服電話被打爆,社群開始罵
工程團隊緊急加機器、調參數、重啟服務,折騰了兩個小時才穩定。事後覆盤,大家都知道原因:沒做過壓力測試。
這不是假設情境。這是大多數中型團隊遲早會遇到的事。
功能測試和壓力測試的根本差異
| 維度 | 功能測試 | 壓力測試 |
|---|---|---|
| 問的問題 | 這個 API 回傳的結果對不對? | 100 個人同時打這個 API 會怎樣? |
| 測試條件 | 單一請求、理想環境 | 併發請求、資源競爭 |
| 發現的問題 | 邏輯錯誤、驗證遺漏 | 記憶體洩漏、連線池耗盡、CPU 阻塞 |
| 失敗的表現 | 回傳錯誤結果 | 回傳正確結果但要等 10 秒 |
| 什麼時候壞 | 開發階段就能發現 | 上線後流量上來才爆 |
關鍵差異在於:功能測試是在真空中測試邏輯,壓力測試是在資源競爭中測試行為。
一個 API 在單一請求時可以完美運作。但當 500 個請求同時進來,搶同一個資料庫連線池、搶同一顆 CPU 的運算時間、搶同一塊記憶體,行為會完全不同。
壓力下才會出現的問題
這些問題在功能測試中永遠不會被發現:
1. Bcrypt 阻塞 CPU
單一請求:bcrypt.hash() 花 80ms,沒感覺
50 個併發:每個 bcrypt 都在排隊等 CPU,response time 飆到 3 秒
Bcrypt 是 CPU-bound 操作,Node.js 的 single-thread 模型讓它在高併發時特別痛苦。這是我們在 9 框架壓測中發現的共同瓶頸——功能測試不會告訴你這件事。
2. 資料庫連線池耗盡
Pool Max: 20
併發請求: 100
結果: 80 個請求在排隊等連線,timeout 後返回 500
3. 記憶體洩漏在高流量下加速
單一請求:每次請求洩漏 1KB,一天 1000 個請求,漏 1MB,沒人在意
高流量:每秒 100 個請求,一小時漏 360MB,OOM Kill
4. 競態條件(Race Condition)
用戶 A 和用戶 B 同時購買最後一件商品
單一請求測試:A 買成功
併發測試:A 和 B 都買成功,庫存變成 -1
壓力測試的類型
不是所有壓力測試都一樣。根據你想回答的問題,選擇不同的測試類型:
Load Test(負載測試)
在預期的正常流量下,系統表現如何?
- VU(虛擬用戶): 預期流量的 1-2 倍
- 持續時間: 10-30 分鐘
- 用途: 確認日常負載下的 response time 和 error rate
Stress Test(壓力測試)
系統的極限在哪裡?超過極限後會怎樣?
- VU: 逐步增加直到系統崩潰
- 持續時間: 每個階段 5 分鐘
- 用途: 找出系統的 breaking point 和降級行為
Spike Test(尖峰測試)
流量突然暴增 10 倍,系統能撐住嗎?
- VU: 瞬間從正常流量跳到 10 倍
- 持續時間: 尖峰維持 1-5 分鐘
- 用途: 模擬大促開始、新聞曝光等突發流量
Soak Test(耐久測試)
系統跑 24 小時會不會慢慢劣化?
- VU: 正常流量
- 持續時間: 4-24 小時
- 用途: 發現記憶體洩漏、連線洩漏、日誌膨脹
什麼時候該做壓力測試
不是每個專案都需要壓力測試。 判斷標準很簡單:
一定要做
- 面向消費者的 API(電商、社群、金融)
- 有明確的流量高峰(大促、開學季、報稅季)
- SLA 有明確的 response time 承諾
- 微服務架構(一個服務慢會拖垮整條鏈路)
- 付費的基礎設施(你需要知道要買多少資源)
可以不做
- 內部工具、後台管理系統(同時用的人不超過 10 個)
- 一次性的資料處理腳本
- 開發中的原型、MVP
做了但做錯的常見情況
- 只測單一 API: 真實流量是多個 API 同時被打。用戶登入的同時在查商品、加購物車
- 在本地測: 本地跑壓測的結果和生產環境差十萬八千里
- 只看平均值: P99 10 秒但平均 200ms,平均值什麼都看不出來
- 測完不留記錄: 下次上線前又從零開始猜「應該撐得住吧」
壓力測試的投資報酬率
壓力測試不是免費的。它需要:
- 時間: 設計測試場景、寫腳本、跑測試、分析結果
- 基礎設施: 測試環境、壓測工具、監控工具
- 專業知識: 看懂結果並做出正確決策
但比起「上線後才發現撐不住」的成本:
| 成本項目 | 沒做壓測 | 有做壓測 |
|---|---|---|
| 發現問題的時機 | 上線後,用戶在罵 | 上線前,QA 環境 |
| 修復的壓力 | 極高,邊修邊接客服電話 | 低,排進正常開發週期 |
| 信譽損失 | 用戶流失、媒體報導 | 無 |
| 修復成本 | 緊急加機器 + 通宵加班 | 正常工時內調整 |
壓力測試的核心價值不是「讓系統變快」,而是「在上線前就知道極限在哪裡」。 知道極限,你就能做決策:加機器、調架構、或是告訴行銷「最多同時 5000 人」。
為什麼會有這個系列
先講背景。我們原本是單體架構,一個 FastAPI 服務搞定所有事。後來拆成微服務——Auth Service、Post Service、File Service 各自獨立。拆完之後才發現:單體時代「一個服務慢就是慢」,微服務時代「一個服務慢,整條鏈路一起死」。
一個 Auth Service 的 bcrypt 佔滿 CPU,Post Service 和 File Service 的請求全部卡在等 JWT 驗證。用戶看到的不是「登入慢」,是「整個網站都慢」。
這才意識到:微服務不是拆完就沒事,你得知道每個服務的極限在哪。壓力測試從「有空再做」變成「不做不行」。
所以我們蓋了一個壓測平台,拿 9 個後端框架(Express-TS、Express-JS、Django、FastAPI、Go、NestJS、Laravel、Spring Boot、.NET Core)在完全相同的條件下比較。這個系列就是從搭平台到跑數據到做決策的完整紀錄。
這個系列的結構
68 篇文章,分成三大段。你可以從任何一段開始讀,但按順序會有完整的敘事線。
主系列(01-30):一步一步走完壓測的過程——從搭平台、發現 bcrypt 天花板、9 框架 CRUD 排名、混合場景翻盤、前端框架、DB 選型、儲存層、架構模式,到跨層容量規劃和微服務經驗。每一步都是因為上一步的發現才走到這裡。
延伸系列(31-61):主系列回答了「選什麼」,延伸系列回答「怎麼做」——資料庫深入、Cache 策略、搜尋與推薦、併發控制、微服務通訊、資料一致性、框架選型、微服務拆分、部署與容器、可觀測性、安全、開發者體驗、成本。
總結篇(62-68):把所有數據整合成一張地圖——五層最佳化路線圖、各層最終結論、從零開始的全棧選型指南。
下一篇
壓測平台架構設計 — 用 k6 + InfluxDB + Grafana + 自建規則引擎,搭建一個可重複使用的壓測平台。
本系列文章
完整 68 篇目錄見 系列首頁
→ 下一篇:壓測平台架構設計:從 k6 腳本到全自動分析
