高併發測試指南:JMeter、Locust、k6 工具比較與實作教學|2025
高併發測試指南:JMeter、Locust、k6 工具比較與實作
前言:不測試就上線,等於在賭博
「上線前測過了嗎?」 「測了,功能都正常。」 「壓測呢?」 「……」
然後大促當天,系統掛了。
功能測試只能確保「能用」,壓力測試才能確保「撐得住」。高併發系統不做壓測就上線,跟蒙眼開車一樣危險。
本文將帶你從「為什麼要壓測」開始,比較四大壓測工具,教你撰寫壓測腳本、解讀測試指標,最後介紹如何整合 CI/CD 做持續壓測。
如果你還不熟悉高併發的基本概念,建議先閱讀高併發是什麼?完整指南。
一、為什麼需要壓力測試
1.1 找出系統瓶頸
壓測能暴露系統的弱點:
- 資料庫連線數不夠
- 某個 API 特別慢
- 記憶體洩漏
- 網路頻寬瓶頸
這些問題在低流量時不會出現,壓測才能找出來。
1.2 驗證架構設計
你的架構設計能撐多少 QPS?理論計算不準,實測才知道。
- 讀寫分離有效嗎?
- 快取命中率夠高嗎?
- 負載均衡分配均勻嗎?
壓測是架構設計的驗證手段。詳細的架構設計原則,請參考高併發架構設計。
1.3 容量規劃依據
大促預估有 100 萬用戶同時上線。需要開多少台機器?
沒有壓測數據,只能靠猜。有了壓測數據,才能精準規劃。
1.4 建立 Baseline
壓測不是一次性的。每次發布新版本,效能可能會變。
定期壓測,建立效能基準線(Baseline)。如果新版本效能下降,馬上能發現。
二、壓測工具比較
市面上壓測工具很多,這裡介紹四個最常用的。
2.1 Apache JMeter
簡介:Java 編寫的老牌壓測工具,功能最全面。
優點:
- GUI 介面,上手容易
- 支援多種協議(HTTP、JDBC、LDAP、JMS)
- 插件生態豐富
- 分散式測試支援
缺點:
- Java 編寫,資源佔用較高
- GUI 在大型測試時會卡
- 腳本是 XML,不好維護
適合:
- 需要測試多種協議
- 團隊不熟悉程式語言
- 企業級應用
2.2 Locust
簡介:Python 編寫的現代壓測工具。
優點:
- Python 寫腳本,彈性高
- 輕量,資源佔用少
- 分散式架構原生支援
- Web UI 即時監控
缺點:
- 只支援 HTTP
- Python 寫法有學習曲線
- 極端效能場景稍弱
適合:
- Python 開發者
- Web API 測試
- 需要複雜測試邏輯
2.3 k6
簡介:用 JavaScript 撰寫腳本的現代壓測工具,由 Grafana 維護。
優點:
- Go 編寫,效能極佳
- JavaScript/TypeScript 寫腳本
- 開發者體驗好(CLI first)
- 雲端服務整合(Grafana Cloud)
缺點:
- 只支援 HTTP/WebSocket/gRPC
- 相對較新,社群較小
- 進階功能需要付費版
適合:
- 前端/全端開發者
- DevOps 團隊
- 需要整合 CI/CD
2.4 wrk
簡介:C 語言編寫的極簡壓測工具。
優點:
- 極輕量,資源佔用最少
- 單機就能產生極高 QPS
- Lua 腳本擴展
缺點:
- 功能簡單,只測 HTTP
- 沒有 GUI
- 報告功能弱
適合:
- 快速基準測試
- 對效能要求極高的場景
- 簡單的 API 測試
工具比較表
| 工具 | 語言 | 腳本 | GUI | 分散式 | 資源佔用 | 適合場景 |
|---|---|---|---|---|---|---|
| JMeter | Java | XML | 有 | 支援 | 高 | 企業級、多協議 |
| Locust | Python | Python | Web | 原生 | 低 | Python 團隊、Web API |
| k6 | Go | JavaScript | 無 | 付費版 | 低 | DevOps、CI/CD |
| wrk | C | Lua | 無 | 無 | 極低 | 快速基準測試 |

三、測試指標解讀
跑完壓測,看到一堆數字。這些數字代表什麼?
3.1 吞吐量指標
QPS(Queries Per Second)
每秒查詢數。對於 Web API,這是最常用的吞吐量指標。
- 100 QPS:小型網站
- 1,000 QPS:中型網站
- 10,000+ QPS:大型網站
TPS(Transactions Per Second)
每秒交易數。一筆交易可能包含多個查詢。
例如:一次購買 = 查商品 + 扣庫存 + 建訂單 + 扣款 = 1 TPS,但可能是 4 QPS。
RPS(Requests Per Second)
每秒請求數。通常和 QPS 同義。
3.2 回應時間指標
平均回應時間(Avg)
所有請求回應時間的平均值。看起來直觀,但容易被極端值影響。
P50 / P95 / P99
百分位數(Percentile),更能反映真實體驗。
- P50:50% 的請求在這個時間內完成(中位數)
- P95:95% 的請求在這個時間內完成
- P99:99% 的請求在這個時間內完成
為什麼關注 P99?因為 1% 的慢請求可能影響大量用戶。
舉例:
- 平均回應時間:100ms
- P50:80ms
- P95:200ms
- P99:1000ms
這表示雖然平均看起來還好,但有 1% 的用戶要等 1 秒以上。這 1% 可能就是你的 VIP 客戶。
3.3 錯誤指標
錯誤率(Error Rate)
請求失敗的比例。包括 HTTP 5xx 錯誤、超時、連線失敗。
- < 0.1%:優秀
- 0.1% - 1%:可接受
-
1%:需要關注
超時率(Timeout Rate)
請求超時的比例。通常設定 30 秒或 60 秒超時。
3.4 資源指標
壓測時要同時監控服務端資源:
- CPU 使用率:超過 80% 要警覺
- 記憶體使用率:注意有沒有持續上升(洩漏)
- 網路 I/O:頻寬有沒有打滿
- 磁碟 I/O:有沒有大量讀寫
這些指標幫你定位瓶頸在哪裡。
四、壓測腳本撰寫教學
光說不練假把式。這裡示範三種工具的實際寫法。
4.1 JMeter 範例
JMeter 主要用 GUI 設計測試計畫,核心元件:
- Thread Group:設定並發用戶數
- HTTP Request:定義要測試的 API
- Listener:收集和顯示結果
<ThreadGroup>
<numThreads>100</numThreads>
<rampTime>10</rampTime>
<duration>60</duration>
</ThreadGroup>
<HTTPSampler>
<domain>api.example.com</domain>
<path>/products</path>
<method>GET</method>
</HTTPSampler>
實際操作流程:
- 開啟 JMeter GUI
- 新增 Thread Group,設定 100 用戶、10 秒 ramp-up、跑 60 秒
- 新增 HTTP Request,填入 API 資訊
- 新增 Summary Report 查看結果
- 點擊運行
4.2 Locust 範例
Locust 用 Python 寫腳本,彈性很高。
# locustfile.py
from locust import HttpUser, task, between
class WebUser(HttpUser):
# 每次請求間隔 1-3 秒
wait_time = between(1, 3)
@task(3) # 權重 3,執行頻率較高
def get_products(self):
self.client.get("/products")
@task(1) # 權重 1
def get_product_detail(self):
product_id = 123
self.client.get(f"/products/{product_id}")
@task(1)
def create_order(self):
self.client.post("/orders", json={
"product_id": 123,
"quantity": 1
})
def on_start(self):
# 每個用戶啟動時執行(例如登入)
self.client.post("/login", json={
"username": "test",
"password": "test123"
})
運行指令:
# 啟動 Locust Web UI
locust -f locustfile.py --host=https://api.example.com
# 或直接命令列運行
locust -f locustfile.py --host=https://api.example.com \
--users 100 --spawn-rate 10 --run-time 60s --headless
想深入了解 Python 處理高併發的方式,請參考Python vs Golang 高併發。
4.3 k6 範例
k6 用 JavaScript 寫腳本,對前端開發者友好。
// script.js
import http from 'k6/http';
import { check, sleep } from 'k6';
// 測試設定
export const options = {
stages: [
{ duration: '10s', target: 50 }, // 10 秒內爬升到 50 用戶
{ duration: '30s', target: 100 }, // 維持 100 用戶 30 秒
{ duration: '10s', target: 0 }, // 10 秒內降到 0
],
thresholds: {
http_req_duration: ['p(95)<500'], // 95% 請求要在 500ms 內
http_req_failed: ['rate<0.01'], // 錯誤率 < 1%
},
};
export default function () {
// 取得商品列表
const productsRes = http.get('https://api.example.com/products');
check(productsRes, {
'products status is 200': (r) => r.status === 200,
});
sleep(1);
// 取得商品詳情
const detailRes = http.get('https://api.example.com/products/123');
check(detailRes, {
'detail status is 200': (r) => r.status === 200,
'detail has name': (r) => r.json('name') !== undefined,
});
sleep(1);
// 建立訂單
const orderRes = http.post(
'https://api.example.com/orders',
JSON.stringify({ product_id: 123, quantity: 1 }),
{ headers: { 'Content-Type': 'application/json' } }
);
check(orderRes, {
'order created': (r) => r.status === 201,
});
sleep(1);
}
運行指令:
k6 run script.js
五、CI/CD 整合持續壓測
壓測不應該是一次性的。整合到 CI/CD,每次發布都自動跑。
5.1 為什麼要持續壓測
- 新程式碼可能引入效能問題
- 及早發現,避免上線後才出事
- 建立效能基準線,追蹤趨勢
- 防止效能迴歸
5.2 整合方式
GitHub Actions + k6 範例
# .github/workflows/load-test.yml
name: Load Test
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
load-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install k6
run: |
sudo gpg -k
sudo gpg --no-default-keyring --keyring /usr/share/keyrings/k6-archive-keyring.gpg --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys C5AD17C747E3415A3642D57D77C6C491D6AC1D69
echo "deb [signed-by=/usr/share/keyrings/k6-archive-keyring.gpg] https://dl.k6.io/deb stable main" | sudo tee /etc/apt/sources.list.d/k6.list
sudo apt-get update
sudo apt-get install k6
- name: Run load test
run: k6 run --out json=results.json tests/load-test.js
- name: Check thresholds
run: |
if grep -q '"thresholds":{"http_req_duration":\[{"ok":false' results.json; then
echo "Performance threshold failed!"
exit 1
fi
5.3 測試門檻設定
設定明確的門檻,自動判斷通過/失敗:
// k6 thresholds
export const options = {
thresholds: {
http_req_duration: ['p(95)<500', 'p(99)<1000'],
http_req_failed: ['rate<0.01'],
http_reqs: ['rate>100'], // 至少 100 QPS
},
};

六、容量規劃方法
壓測數據怎麼用來做容量規劃?
6.1 估算公式
步驟 1:估算預期流量
預期 QPS = 日活用戶 × 人均請求數 ÷ 活躍秒數
例如:
- 日活用戶:100,000
- 人均請求數:50 次
- 活躍時間:8 小時 = 28,800 秒
- 預期 QPS = 100,000 × 50 ÷ 28,800 ≈ 174
步驟 2:考慮峰值
峰值通常是平均值的 2-5 倍。
峰值 QPS = 預期 QPS × 峰值係數
假設峰值是平均的 3 倍:
- 峰值 QPS = 174 × 3 ≈ 522
6.2 安全係數
不要把系統跑到極限。預留空間給突發狀況。
目標容量 = 峰值 QPS × 安全係數
安全係數通常取 1.5-2 倍:
- 目標容量 = 522 × 1.5 ≈ 783 QPS
6.3 擴展計畫
知道目標容量後,用壓測數據反推需要多少資源。
假設壓測結果:
- 單台 4C8G 機器能扛 200 QPS
- 目標容量 783 QPS
- 需要機器數 = 783 ÷ 200 ≈ 4 台
考慮高可用(N+1 冗餘),至少需要 5 台。
不確定系統能撐多少流量?預約壓測諮詢,讓專家幫你規劃容量。
七、常見問題排查
壓測時遇到問題怎麼辦?
7.1 壓測端瓶頸
症狀:壓測機 CPU 飆高,但服務端還很閒。
原因:壓測工具本身成為瓶頸。JMeter 資源佔用高,單機產生的 QPS 有限。
解法:
- 換輕量工具(k6、wrk)
- 分散式壓測(多台壓測機)
- 關閉不必要的監控插件
7.2 網路瓶頸
症狀:網路流量打滿,但 CPU/記憶體都還好。
原因:頻寬不夠,或網路設備成為瓶頸。
解法:
- 檢查壓測機和服務端之間的頻寬
- 壓測機放到同一個內網
- 使用雲端壓測服務
7.3 應用瓶頸
症狀:應用 CPU 飆高,回應變慢。
原因:程式碼效能問題、資源競爭、執行緒耗盡。
排查方向:
- Profiling 找出熱點函數
- 檢查是否有鎖競爭
- 檢查執行緒池/連線池設定
7.4 資源洩漏
症狀:跑一段時間後效能驟降,記憶體持續上升。
原因:記憶體洩漏、連線洩漏、檔案描述符洩漏。
排查方向:
- 用 APM 工具追蹤記憶體使用
- 檢查連線有沒有正確關閉
- 看系統的 open file 數量
常見問題 FAQ
Q1: 壓測應該在生產環境還是測試環境做?
測試環境做初步驗證,生產環境做最終確認。但生產環境壓測要小心,建議在低峰時段、有降級方案的情況下進行。
Q2: 壓測要跑多久?
至少 5-10 分鐘。太短會錯過記憶體洩漏等問題。穩定性測試可以跑幾小時甚至一天。
Q3: 怎麼模擬真實用戶行為?
不是所有用戶都在同一秒發請求。用 ramp-up 模擬用戶逐漸加入,用 think time 模擬用戶思考時間,用不同權重模擬不同行為比例。
Q4: 分散式壓測怎麼做?
JMeter 有 remote testing,Locust 原生支援分散式,k6 付費版有 Cloud 功能。或者手動在多台機器跑,最後合併結果。
Q5: 壓測結果不穩定怎麼辦?
多跑幾次取平均。排除環境干擾(其他程式、網路波動)。確保每次測試的起始狀態一致(重啟服務、清空快取)。
結論:壓測是高併發系統的必修課
沒有經過壓測的系統,就像沒有經過考驗的士兵。
本文重點回顧:
- 壓測能找出瓶頸、驗證架構、規劃容量
- JMeter 功能全、Locust Python 友好、k6 現代化、wrk 極簡
- 關注 P99 回應時間,而不只是平均值
- 錯誤率和資源指標同樣重要
- 整合 CI/CD 做持續壓測
- 容量規劃要考慮峰值和安全係數
延伸閱讀:
架構設計需要第二意見?
好的壓測能預防災難。如果你正在:
- 準備大促,擔心系統撐不住
- 想知道系統的效能極限在哪
- 需要規劃容量和預算
預約架構諮詢,讓我們一起檢視你的系統效能。
所有諮詢內容完全保密,沒有銷售壓力。
參考資料
- Apache JMeter 官方文檔(2024)
- Locust 官方文檔(2024)
- k6 官方文檔(2024)
- Google,《Site Reliability Engineering》(2016)
- AWS,《Performance Testing Best Practices》(2024)
相關文章
高併發是什麼?2025 完整指南:定義、架構設計與雲端解決方案
高併發(High Concurrency)是什麼意思?本文完整解析高併發的定義、常見問題、架構設計模式,以及如何利用 Redis、資料庫優化、雲端服務來處理高流量場景。無論你是要應對電商大促、搶票系統還是即時交易,這篇指南都能幫你設計出高可用的系統架構。
高併發雲端高併發架構:AWS、GCP、Azure 方案比較與最佳實務|2025
雲端如何處理高併發?本文比較 AWS、GCP、Azure 三大平台的高併發解決方案,包含 Auto Scaling、ElastiCache、Lambda 無伺服器架構,以及成本分析和混合雲策略建議。
高併發高併發架構設計:從單體到微服務的演進之路|2025 實戰指南
高併發架構怎麼設計?本文從單體架構的瓶頸談起,解析垂直擴展與水平擴展的選擇、分層架構設計原則,以及微服務拆分策略。包含服務治理、配置中心實務,與 AWS、GCP、Azure 雲端架構推薦。