Casha | 3. Jmeter 壓力測試與監控(Baseline + Capacity / Grafana, Prometheus)
關於壓力測試, 會注重於在特定情境之下, 系統能夠運行的極限。其中比較費工的點分為 TestCase 的定義, 以及事前的準備, 這些都需要在執行之前有完善的計畫。
本報告彙整 Scan→Menu 與 Scan→Menu→Order(含付款回調) 兩條路徑的
基準/容量測試與監控觀察,重點在:可穩定承載的 RPS/併發、延遲 SLA(p50/p95/p99)、錯誤率、依賴服務健康度。
關於 JMX 和用 Procedure 建立假資料則收錄在 git doc 監控與壓力測試報告(Baseline + Capacity) 內。
0. 測試環境與共用設定
- 執行環境:Local(AMD R5 4600H / 32GB RAM),各服務 單實例。
- 負載模型:Ultimate Thread Group,五段階梯並發
100 → 200 → 400 → 600 → 800 users
每段:Startup 60s / Hold 300s / Shutdown 30s。 - 使用者行為腳本(共用)
- 一次掃碼 →
/cis/seat/resolve - 菜單刷新 2–3 次(每 3–7s) →
/cis/menu/active - 建立訂單(隨機 1–3 個商品、每個 qty=1~3) →
/cis/order/create - 模擬付款回調 →
/cis/payments/mock-callback
- 一次掃碼 →
- 量測指標:p50/p95/p99、Error%、TPS、各服務 p95、CPU/Heap、Redis Ops/Hit Ratio、MQ Queue Depth。
在前面的章節: 菜單設置與快取機制 中有提到, 在首次解析該qrcode 時, 會真的到 DB 內查詢, 儲存到 Redis 後返回, 後面的請求則在 Data TTL 前都使用 Redis 的資料。
1. Scan→Menu 基準/容量(Baseline + Capacity)
目標:針對讀路徑(Scan→Menu)量出固定資源下可穩定承載的 RPS,並給出 p50/p95/p99 SLA。
輸出:各階段(100/200/400/600/800 users)之延遲分佈、錯誤率、依賴服務健康度,與結論(穩定承載 RPS、建議 SLA)。
1.1 測試模型與資料規模
- 分店:800 間,每店 5 桌 → 4,000 QR
- 菜單版本:每店 1 版,共 800 版
- 品項:每版 10 品項(3 分類),全部緩存在 Redis(首刷命中 DB,TTL 內皆走 Redis)
使用者行為:
抵達後掃碼 1 次;在 5 分鐘 Hold 期間,每 3–7 秒刷新菜單;段尾逐步退出,進入下一並發段。
設計目的:最大化讀路徑覆蓋,反映「高頻看菜單」的真實流量型態。
1.2 結果(JMeter)
Error% 中觀察到的 Response was null 判定為 JMeter 偶發、非伺服器錯誤(Error% 1.44% < 2%)。
ResolveSeat(掃碼)
p50 ≈ 45 ms / p95 ≈ 60 ms / p99 ≈ 85 ms / Error% = 0%
需觸發 DB 與狀態解析,延遲高於菜單,但仍 < 100 ms 且只發生一次,體驗可接受。MenuRefresh(核心讀菜單)
p50 ≈ 12 ms / p95 ≈ 22 ms / p99 ≈ 67 ms / Error% ≈ 1.44%
低毫秒級,Redis 快取表現穩定,tail latency 無明顯拖尾。
| Label | #Samples | Error % | Avg (ms) | p90 | p95 | p99 | TPS |
|---|---|---|---|---|---|---|---|
| ResolveSeat | 4,200 | 0.00% | 56.90 | 88 | 112 | 160 | 2.59 |
| MenuRefresh | 262,503 | 0.00% | 16.30 | 22 | 29 | 92 | 134.8 |
| Total | 138,605 | 0.00% | 19.20 | 20 | 26 | 77 | 71.1 |


1.3 監控觀察(Grafana/Prometheus)
- QPS by Service:峰值約 130–140 req/s(主在
cis-service),其餘服務 20–40 req/s,負載分布合理。 - p95:
cis-service(含 seat/resolve + menu/active)< 100 ms;整體 < 200 ms,符合常見 SLA。 - CPU/Heap:各服務 CPU 峰值 < 6%;Heap 約 1.0–1.7%,GC 無異常;Redis Ops 峰值 ~300 ops/s、Hit Ratio 100%。

1.4 結論(Scan→Menu)
- 在 800 並發(~75 RPS) 條件下,MenuRefresh p95 ≈ 22 ms、p99 ≈ 67 ms,Error% < 2%。
- 穩定承載能力:保守建議 ≥ 70–80 RPS;讀路徑 SLA 可訂 p95 ≤ 25 ms、p99 ≤ 70 ms、Error% < 2%。
- 資源使用率低,尚有擴容空間。
2. Scan→Menu→Order 基準/容量(Baseline + Capacity)
目標:在多分店 open model 下,量測端到端(掃碼→看菜單→下單→回調)的延遲與穩定度。
測資假設(每店):10 商品、可銷售量總和 725;每位用戶下單 2–3 商品(qty=1)。
2.1 兩組情境
- 性能 SLA baseline(50 店):確保 800 users 後仍有庫存,以量 延遲/TPS/錯誤率。
- 正確性 baseline(7 店):總可售量 7×725=5,075,在後段階段必然售罄,用以驗證 正確拒絕與無超賣。
整場 5 段合計 2,100 users,若以 2.5 件/人估算,約 5,250 件 請求量。
2.2 結果(JMeter)
a) 50 店(性能)
- CreateOrder:Avg 129 ms / p95 255 ms / p99 394 ms / Error% 0%
- MockCallback:Avg 54 ms / p95 106 ms / Error% 0%
- MenuRefresh:如 §1 結果,持續低毫秒級
| Label | #Samples | Error % | Avg (ms) | p90 | p95 | p99 | TPS |
|---|---|---|---|---|---|---|---|
| ResolveSeat | 4,200 | 0.00% | 56.90 | 88 | 112 | 160 | 2.59 |
| MenuRefresh | 262,503 | 0.00% | 16.30 | 22 | 29 | 92 | 134.8 |
| CreateOrder | 2,100 | 0.00% | 129.10 | 211 | 255 | 394 | 1.30 |
| MockCallback | 2,100 | 0.00% | 53.90 | 85 | 106 | 149 | 1.30 |
| Total | 138,605 | 0.00% | 19.20 | 20 | 26 | 77 | 71.1 |

監控:QPS 峰值 130–140;order-service p95 100–150 ms;CPU < 6%、Heap < 2%、Redis Ops 峰值 ~600。

結論(50 店):在 800 users 下,端到端 Error = 0%、CreateOrder p95 ≈ 255 ms;可對外主張 穩定承載 ≈ 130 TPS、p95 < 300 ms。
b) 7 店(正確性)
- 預期:累計到第 4–5 段總購買量 > 5,075,進入售罄。
- CreateOrder Error% ≈ 20.8% 為 400 / CIS00004(售罄),屬於「正確拒絕」。
- MockCallback Error% ≈ 32.6%(因前一步未下單成功,自然無回調對象)。
- DB 校驗:
sum(menu_version_item.daily_quota) = 5,075sum(sales_quota_counter.used_qty) = 5,075→ 完全一致,證實無 oversell。
| Label | #Samples | Error % | Avg (ms) | p90 | p95 | p99 | TPS |
|---|---|---|---|---|---|---|---|
| ResolveSeat | 4,200 | 0.0% | 46.10 | 62 | 74 | 104 | 2.59 |
| MenuRefresh | 262,696 | 0.0% | 12.10 | 15 | 17 | 28 | 134.8 |
| CreateOrder | 2,100 | 20.8% | 82.60 | 120 | 137 | 176 | 1.30 |
| MockCallback | 2,100 | 32.6% | 40.40 | 58 | 73 | 96 | 1.30 |
| Total | 138,700 | 0.8% | 14.10 | 16 | 18 | 27 | 71.2 |
監控:QPS 120–140;order-service p95 ~150 ms,cis-service < 100 ms;CPU 峰值 < 6%、Heap 緩升但 < 2%;Redis Hit 100%。

結論(7 店):在受限庫存場景下,系統正確拒絕售罄下單、前端菜單同步 isActive=0,且 未發生超賣;延遲/資源保持穩定。
3. 綜合結論與建議
可穩定承載能力
- 讀路徑(Scan→Menu):穩定承載 ≥ 70–80 RPS,建議 SLA:p95 ≤ 25 ms / p99 ≤ 70 ms / Error% < 2%。
- 下單路徑(Scan→Menu→Order):在 ~130 TPS 時,CreateOrder p95 < 300 ms、Error ≈ 0%(50 店)。
正確性
- 在 7 店(5,075 件) 受限場景,售罄後返回 400/CIS00004,DB 統計與可售量一致,證實 無 oversell。
資源/依賴健康度
- CPU/Heap/Redis/MQ 均遠離瓶頸,說明單機資源足夠、系統可擴空間大。
差異解讀
- JMeter p95(單純 HTTP Sampler 延遲) vs. Grafana p95(含 gateway/metrics)存在落差,屬正常量測口徑差異。
下一步建議
- Stress/Break Test:每 3–5 分鐘上調 20–30% RPS,直到 Error% > 5% 或 p99 爆炸,找臨界點與優雅降級行為。
- 熱門品/熱鍵測試:權重選品,驗證 Redis/DB 熱點行為。
- 容量預估:以本次曲線外推,規劃 2×–3× 擴容策略(服務副本/連線池/隊列上限)。
目前僅跑完 Baseline 測試, 驗證在設想的情境之下, 菜單的快取設置以及點餐的原子性都有成功的發揮,後面再找時間直接在 AM4 平台上跑更多的 Thread Group 去測試, 看看目前系統的極限。
