Casha | 3. Jmeter 壓力測試與監控(Baseline + Capacity / Grafana, Prometheus)

Casha | 3. Jmeter 壓力測試與監控(Baseline + Capacity / Grafana, Prometheus)

關於壓力測試, 會注重於在特定情境之下, 系統能夠運行的極限。其中比較費工的點分為 TestCase 的定義, 以及事前的準備, 這些都需要在執行之前有完善的計畫。

本報告彙整 Scan→MenuScan→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。
  • 使用者行為腳本(共用)
    1. 一次掃碼 → /cis/seat/resolve
    2. 菜單刷新 2–3 次(每 3–7s) → /cis/menu/active
    3. 建立訂單(隨機 1–3 個商品、每個 qty=1~3) → /cis/order/create
    4. 模擬付款回調 → /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

Response Times Over Time
Active Threads Over Time

1.3 監控觀察(Grafana/Prometheus)

  • QPS by Service:峰值約 130–140 req/s(主在 cis-service),其餘服務 20–40 req/s,負載分布合理。
  • p95cis-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%。

Grafana

1.4 結論(Scan→Menu)

  • 800 並發(~75 RPS) 條件下,MenuRefresh p95 ≈ 22 ms、p99 ≈ 67 msError% < 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

Response Times Over Time

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

Grafana

結論(50 店):在 800 users 下,端到端 Error = 0%、CreateOrder p95 ≈ 255 ms;可對外主張 穩定承載 ≈ 130 TPSp95 < 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,075
    sum(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%。

Grafana

結論(7 店):在受限庫存場景下,系統正確拒絕售罄下單、前端菜單同步 isActive=0,且 未發生超賣;延遲/資源保持穩定。


3. 綜合結論與建議

  1. 可穩定承載能力

    • 讀路徑(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 店)。
  2. 正確性

    • 7 店(5,075 件) 受限場景,售罄後返回 400/CIS00004DB 統計與可售量一致,證實 無 oversell
  3. 資源/依賴健康度

    • CPU/Heap/Redis/MQ 均遠離瓶頸,說明單機資源足夠、系統可擴空間大。
  4. 差異解讀

    • JMeter p95(單純 HTTP Sampler 延遲) vs. Grafana p95(含 gateway/metrics)存在落差,屬正常量測口徑差異。
  5. 下一步建議

    • Stress/Break Test:每 3–5 分鐘上調 20–30% RPS,直到 Error% > 5%p99 爆炸,找臨界點與優雅降級行為。
    • 熱門品/熱鍵測試:權重選品,驗證 Redis/DB 熱點行為。
    • 容量預估:以本次曲線外推,規劃 2×–3× 擴容策略(服務副本/連線池/隊列上限)。

目前僅跑完 Baseline 測試, 驗證在設想的情境之下, 菜單的快取設置以及點餐的原子性都有成功的發揮,後面再找時間直接在 AM4 平台上跑更多的 Thread Group 去測試, 看看目前系統的極限。