服務

「開賣三分鐘就掛了」:600 RPS 尖峰的容量規劃怎麼做——從 k6 壓測、虛擬候位、快取分層到超賣防治

2026.08.16 · 55 次瀏覽
「開賣三分鐘就掛了」:600 RPS 尖峰的容量規劃怎麼做——從 k6 壓測、虛擬候位、快取分層到超賣防治

多數人買的是更大台的主機,真正倒下的卻是資料庫行鎖——含真實成本級距與 90 天路線圖

分享:

晚上 8:00 開賣,8:03 首頁還在轉圈

某服飾品牌限量 300 件,8:00 開賣。8:00:12 客服 LINE 跳出「一直轉圈」,8:01 連線數頂到上限,8:03 首頁打不開,8:11 重啟才恢復。最後只賣掉 47 件,還多 12 筆超賣要致電退款,18 萬廣告費換一週客訴。老闆說「主機不夠力」,但八成不是。

誰需要做,誰不需要

適用:限量開賣、課程與活動報名(開放瞬間 RPS 是平日 30-50 倍)、票券與掛號。不適用:單日訂單低於 200 筆,或已託管在 SHOPLINE、Shopify——預算放在轉換率上回報更高。

四種做法,治的不是同一層

方案解決哪一層成本級距(估計)限制
加大主機規格只解 CPU/記憶體,對行鎖無效每月 +NT$5,000–30,000資料庫仍是單點
SaaS 電商平台(SHOPLINE/Shopify/91APP)代管三層,含 CDN 與庫存扣減年約 NT$60,000 起加抽成客製受限、難接 ERP
只加 Cloudflare Waiting Room擋前端與部分應用層每月數十至數百美元放行後結帳照塞
全套自建容量規劃三層全治NT$260,000–650,000需 6-9 週與 staging

主機規格治不了行鎖,候位室治不了超賣。

五個階段:從盤點到實彈演練

階段一.盤點與瓶頸定位(1 週) 分清三種掛法:CDN 被打爆、worker 排隊耗盡、連線數與行鎖打結。交付:架構圖、瓶頸清單、慢查詢報告(Laravel Telescope)。

階段二.基準壓測(1-2 週) 所需併發槽數 = 尖峰 RPS × 平均回應時間(秒):3,000 人、每人 5 秒送 1 次請求即 600 RPS,回應 200ms 需約 120 槽。用 k6、JMeter 或 Locust 在 production-like staging 測完整結帳曲線。交付:容量報告。

階段三.快取/佇列/鎖(2-4 週) 快取分層 CDN 邊緣、全頁、片段、Redis、OPcache;用 Cache-Control 的 stale-while-revalidate 保住商品頁,庫存獨立打 API。寄信、發票、推播丟進 Laravel Queue,主線只留扣庫存與建訂單。交付:鎖策略文件。

階段四.候位與降級(1 週) 導入 Cloudflare Waiting Room、Queue-it 或自建 token bucket;金流、簡訊、物流 API 設 timeout、重試上限與 circuit breaker。交付:降級手冊。

階段五.實彈演練(1 週) 檔期前 7 天跑全流程演練,含 綠界 ECPay 沙盒付款與退款,刻意打掛一台確認降級。交付:on-call 手冊。

真實成本拆解(估計值,台幣)

  • 壓測與容量報告:NT$60,000–150,000(2-3 輪)
  • 快取與佇列改造:NT$120,000–300,000
  • 虛擬候位:Cloudflare 每月數十至數百美元;自建 NT$80,000–150,000
  • 超賣防治:NT$80,000–200,000
  • 檔期當日 on-call:NT$15,000–40,000/日

隱藏費用

  • staging 複本每月 NT$3,000–15,000
  • 尖峰雲端費用是平日 3-8 倍,要抓進檔期毛利
  • 金流的高併發方案多半另談
  • 簡訊與推播單價低,總額常超出預期

客戶想像 vs 實施真相

  • 以為「主機加大就好」——倒的是連線數與行鎖,8 核換 32 核只讓塞車晚 40 秒。
  • 以為「auto-scaling 會自動救」——暖機要 2-5 分鐘,救不了 30 秒尖峰;有效的是預先擴容加排隊。
  • 以為「掛掉最慘」——超賣更慘:人工退款、賠券、道歉,損失大於少賣的訂單。

五個最常踩的坑與解法

  • 庫存數字被快取:顯示「剩 3 件」其實早已歸零。解法:庫存獨立打 API,TTL 5-10 秒。
  • 悲觀鎖鎖太大:SELECT ... FOR UPDATE 範圍過寬,600 RPS 下全部排隊。解法:鎖單一 SKU 資料列,或改用 version 樂觀鎖重試。
  • Redis 扣減沒對帳DECR 扛量最好,落庫失敗就對不上。解法:加事後對帳與補償交易。
  • 第三方沒設 timeout:金流慢 10 秒就吃光 worker。解法:3-5 秒 timeout、重試上限、circuit breaker,備妥「先建單、後補金流」。
  • 沒有觀測就上線:出事只能猜。解法:APM 與四個黃金訊號(延遲、流量、錯誤率、飽和度)儀表板要先上。

成功指標與 90 天路線圖

第 30 天:壓測完成,尖峰 p95 低於 800ms、錯誤率低於 1%,LCP 守住 2.5 秒。第 60 天:佇列積壓在尖峰後 3 分鐘內清空、超賣 0 筆、放行速率誤差低於 15%。第 90 天:跑完一次真實檔期,比對「雲端成本/訂單」。

決策清單

  • ☐ 知道上一檔尖峰 RPS 與 p95
  • ☐ 有接近正式資料量的 staging
  • ☐ 壓測涵蓋結帳與金流回呼
  • ☐ 知道資料庫連線數上限
  • ☐ 扣庫存有明確鎖策略
  • ☐ 寄信、發票、推播已移出主線
  • ☐ 商品頁與庫存快取策略分開
  • ☐ 第三方 API 都設了 timeout
  • ☐ 有降級模式,也知道誰有權啟用
  • ☐ 已裝 APM,檔期前 7 天排了演練與 on-call

常見問題

只加虛擬候位,可以撐過去嗎?

候位室只控制進門速度。結帳仍要 3 秒、扣庫存仍鎖整批資料列的話,塞車只是從門口移到櫃檯,超賣照樣發生。

壓測要打多大才夠?

打三種曲線:預估尖峰、尖峰的 2 倍,以及「開賣瞬間 30 秒」的垂直拉升。傷害集中在前 60 秒,平均值沒有參考價值。

悲觀鎖、樂觀鎖、Redis 原子扣減怎麼選?

100 RPS 以下用悲觀鎖;100-500 RPS 用樂觀鎖加重試;500 RPS 以上用 Redis DECR 擋量、訂單非同步落庫,但一定要事後對帳。

下一檔開賣前,先做一次健檢

ScriptWalker 的「檔期容量健檢」NT$60,000 起,含壓測、瓶頸定位與容量報告;「高併發架構改造」NT$180,000 起,含快取分層、佇列、鎖策略與候位。完整改造 6-9 週,建議檔期前 10-12 週啟動。

分享: