9.3 壓測工具選型
概念定位
壓測工具選型的核心不是「哪個工具最強」、是「哪個工具最貼合本團隊的 workload model 表達能力跟 CI 整合需求」。沒有絕對最好的工具、只有最匹配當前場景的工具。
跟 9.2 Workload Modeling 的關係:9.2 定義 workload 長什麼樣、9.3 找能複製這個樣子的工具。工具選對、壓測結果可信;工具選錯、壓測結果誤導。
本章涵蓋 選型維度 + 主流工具的 適用情境,而不是工具教學。讀者讀完後能回答「我現在這個 workload 該用哪個工具」、而不是「哪個工具最快」。
六個選型維度
選工具時要按六個維度評估、不能只看「能不能跑 HTTP GET」。
腳本表達能力:能不能寫複雜 user journey(登入 → 瀏覽 → 加購物車 → 結帳)、不只是單一 HTTP request。複雜系統的壓測通常是 user journey 級別、單一 endpoint 壓測只能找絕對極限、找不到 cross-endpoint contention。
協議支援:HTTP / WebSocket / gRPC / TCP / 自家二進位協議。WebSocket 跟 gRPC 是現代後端常見、傳統工具(JMeter、wrk)可能要 plugin 補。
規模能力:一台施壓機發得出多少請求、是否能分散到多台施壓機擴容。一台施壓機的上限取決於工具的 I/O 模型(Go runtime、JVM 的 async engine、每個使用者一個 OS thread、gevent 只用一顆 CPU 的程序)、script 的內容與那台機器的 CPU 和網路,所以要在自己的施壓機上逐級加量量出來:施壓機的 CPU 或網路先到頂、而受測服務的指標還沒有變化的那一級,就是這台施壓機的上限(Load Generator Saturation)。量到的單機上限低於要的施壓量時,差距要靠工具的分散式擴容方式(Locust 的 master/worker、JMeter 的 remote testing、託管的 cloud runner)補足,擴容方式決定補足這段差距要付多少維運成本。
CI 整合:能不能在 PR 上跑 lightweight perf check、結果能不能機器可讀(JSON / Prometheus exposition)、能不能跟 baseline diff。沒有 CI 整合的工具只能做「事件型壓測」、無法做 continuous perf governance。
結果分析:原生 dashboard(k6 Cloud、Gatling Enterprise)/ Prometheus + Grafana 整合 / 純文字輸出。要看結果分發、團隊成員能不能輕鬆查詢歷史。
學習曲線:腳本語言(JavaScript / Scala / Python / Go)、團隊熟悉度。工具好但團隊不會用、會變成 1-2 個工程師的孤島技能、流失時整套廢掉。
主流開源工具對照
| 工具 | 腳本 | 規模 | 學習曲線 | 適用情境 |
|---|---|---|---|---|
| k6 | JS | 中 | 低-中 | 複雜 user journey + CI 整合、現代工具首選 |
| JMeter | XML/GUI | 中 | 中-高 | 企業已有流程、protocol 廣、reluctant 改 |
| Gatling | Scala | 高 | 高 | 報表精美、Scala 學習門檻 |
| Locust | Python | 高 | 中 | 複雜邏輯、Python 生態、單機 throughput 受限 |
| Vegeta | CLI | 中 | 低 | CLI driven、quick HTTP 壓測 |
| wrk/wrk2 | C | 高 | 低 | 單機極限 RPS、saturation discovery 用 |
k6 是過去 5 年崛起的綜合首選。JavaScript 腳本(前端工程師也能寫)、原生 dashboard、Prometheus exposition、CI 友善。Grafana 收購後生態加速。缺點:複雜 stateful 場景(DB connection pool 共享)需要繞 workaround。executor 的選擇、threshold 與 Grafana 的整合在 k6 的工具頁,從 JMeter 換到 k6 時 thread group 怎麼對到 executor 在 JMeter → k6 的遷移。
JMeter 是企業常見的 incumbent。協議支援廣(含 LDAP、JDBC、JMS)、有 GUI 編輯器。缺點:腳本是 XML、版本控制困難;GUI 主要用來生成腳本、實際跑壓測還是要 headless。已經在用的團隊建議繼續、新團隊不必特意選它。拿 JMeter 找飽和點時,thread group 與 timer 決定量的是 open 還是 closed model,Open Model Thread Group 的逐級加壓、knee 的判讀、施壓端與 TLS 連線的失真寫在 JMeter 在容量探測的用法:thread group 固定的負載變數、逐級加壓、knee 的判讀、施壓端與分散施壓的檢查、多 protocol 的涵蓋範圍與排查順序;工具本身的定位、listener 與分散施壓的設定在 Apache JMeter 在效能容量的工具總覽;在本機用 Docker 照著跑一次、看 CLI 輸出與結果檔長什麼樣,見 JMeter 在本機跑負載測試的實測紀錄,它跟 Locust 那一篇用同一個受測服務與負載模型,兩個工具的輸出可以並排比較。
Gatling 高 throughput 純 async、性能優秀、報表精美。缺點:Scala / Kotlin DSL 學習曲線陡、新版本(11+)改了 DSL 不向後相容。Gatling 的注入步驟分成 open 與 closed 兩組,用 open model 逐級加壓、從 report 判讀 knee point、檢查施壓端與 feeder 資料的分佈寫在 Gatling 在容量探測的用法:open model 的逐級加壓、knee point 的判讀、施壓端的檢查、feeder 資料的分佈與排查順序;工具本身的定位與 Enterprise 版的差異在 Gatling 的工具頁。
Locust 是 Python 生態的選擇、特別適合複雜業務邏輯(用 Python 寫 user journey 自然)。分散式部署原生支援。缺點:一個 worker 程序只用得到一顆 CPU、throughput 受限、要靠多個 worker 擴容。Locust 只有 closed model,逐級增加使用者時怎麼從每秒 task 數與延遲換算受測服務的狀態、pacing 的上限與 worker 的檢查寫在 Locust 在容量探測的用法:closed model 下的逐級加壓、吞吐量與延遲的換算、pacing 的上限、worker 的檢查與排查順序;工具本身的定位、custom client 與 worker 的擴展在 Locust 在效能容量的工具總覽;在本機用 Docker 照著跑一次的紀錄,見 Locust 在本機跑負載測試的實測紀錄。
Vegeta 跟 wrk 是「quick check」工具、用於單一 endpoint 的極限測試。不適合複雜場景、適合 saturation discovery 第一輪「找這個服務的天花板」。
Production traffic replay 工具
當需要複製 真實 production traffic 的壓測場景時、需要另一類工具。
GoReplay 是最常用的開源 traffic replay 工具。在 production server 上 tcpdump-based 捕獲 HTTP traffic、可以 store 到 file 或 stream 到 staging 環境。優點:開源、無 vendor lock-in;缺點:HTTP only、加密流量要拿到 key 才能用。
Service mesh shadow(Istio / Linkerd mirror):mesh 層 mirror traffic 到 staging service。優點:mesh 已部署的話 zero infra cost、加密 traffic 也能 mirror。缺點:需要 service mesh 已落地。
AWS VPC Traffic Mirroring:底層網路層 mirror、application 完全無感。優點:最低 invasion;缺點:AWS only、加密 traffic 要另外處理。
Diffy(Twitter / X 開源、已 deprecated 但概念仍有效):dual-write 同時打到舊 / 新版本、比對結果。適合驗證「新版本是否邏輯正確」、不是純壓測。
對應案例:Tixcraft 10K t2.micro 壓測 — 用分散式 EC2 跑 synthetic load 模擬 100K 同時搶票;SeatGeek Virtual Waiting Room — token 配發邏輯通常用 dual-write 驗證新舊版本一致。
雲端 managed 壓測服務
當不想養 load test infrastructure、想 ad-hoc 跑大規模壓測時、用 managed service。
AWS Distributed Load Testing:CloudFormation 起 Fargate cluster 跑 JMeter 或 Taurus、報表寫到 S3。優點:一鍵部署、Fargate 計費;缺點:JMeter-based、不是現代 k6 風格。
Grafana k6 Cloud:託管 k6、跨地理 distributed 壓測(從多個 region 同時發流量)。優點:地理分散原生、跟 Grafana 整合無縫;缺點:vendor cost。
Azure Load Testing:Azure 原生、整合 Application Insights。優點:Azure 用戶無縫;缺點:相對較新、生態還在補。
GCP 沒有 first-party managed load testing:要靠 Marketplace 方案或自管 Locust on GKE。
工具選型決策樹
落地時的快速決策:
- 想快速驗證單一 API 極限 → wrk / Vegeta
- 想寫複雜 user journey + CI 整合 + JavaScript 團隊 → k6(新項目首選)
- 企業已有 JMeter 流程、不想換 → JMeter(接受 XML / GUI 複雜度)
- 大規模分散式 + Python 生態 → Locust
- 報表給管理層看、Scala 團隊 → Gatling
- 想複製真實 production traffic → GoReplay 或 service mesh shadow
- 想 ad-hoc 雲端大規模壓測 → 對應雲商的 managed load test
壓測結果失真的原因
選好工具之後,結果仍可能失真:只測單一 API 而不測使用者動線、壓測機跟被測機在同一網段、壓測時主機被其他工作負載佔用、工具自己先飽和(Load Generator Saturation)、注入方式跟 production 流量的模型不同(到達率型的流量用固定人數的 closed model 壓,服務變慢時工具自己減壓,見 Open and Closed Workload Model)、只看平均延遲(tail latency 被蓋掉)、壓測環境跟 production 硬體不一致、沒拿結果驗證流量模型。每一種的訊號與避法見 壓力測試工具與方法〈讓結果失真的反模式〉。
案例對照
| 案例 | 教學重點 |
|---|---|
| Tixcraft | 10,000 台 t2.micro 跑分散式壓測($130 / 小時) |
| Tubi | ML p99 < 10ms 壓測必須帶 latency distribution |
下一步路由
- 上游:9.2 Workload Modeling
- 下游:9.4 Saturation Discovery(用工具找 knee)
- 下游:9.9 Improvement Loop(CI 整合)
- 跨模組:06.1 CI Pipeline(壓測在 CI 的位置)
- 跨模組:運維 模組五:壓力測試工具與方法(k6 實跑、怎麼讀延遲分布的動手層)