背景
2024 年 5 月 17 日,在歐洲盃(Euro Cup)賽季開始前,針對 Mobile App SPI 的 Performance 問題召開專案會議,出席人員涵蓋 App 團隊、BO 團隊與 PM。
會議的核心動機:歐洲盃期間流量預計達正常的 2~3 倍,現有 API 設計若未調整,將造成 DB 或 API 無法正常服務。
問題描述
API 呼叫量異常:是 STAR4 的 8 倍
透過 ELK REQUEST 日誌對 Account Summary API(收件匣 + 公告未讀數)進行統計:
1 | Mobile App SPI Account Summary 呼叫量 |
以公告(Announcement)API 為例,數據差異極為顯著:
| 平台 | 每日 API 呼叫量 |
|---|---|
| STAR4 RWD | 約 230,000 次 |
| Mobile App SPI | 約 1,610,000 次 |
Mobile App SPI 的呼叫量是 RWD 的 7 倍以上,而兩者服務的用戶基數相近,顯示 App 端存在明顯的多餘呼叫問題。
ELK Performance Log 實際數據對比:
效能劣化:30% 請求出現延遲
1 | Mobile App SPI:30% 的請求回應時間超過正常門檻 |
這些 API 直接查詢 DB,在歐洲盃高流量期間若無保護機制,DB 壓力將達到臨界點。
flowchart TD
A[Mobile App] --> B[App SPI]
B --> C["Account Summary API\n(每日 161 萬次)"]
B --> D["Announcement List API\n(無 Cache,直打 DB)"]
C --> E[DB]
D --> E
E --> F{Euro Cup 流量\n2~3 倍}
F -->|壓力超載| G[DB / API 無法服務]
F -->|30% 請求已延遲| H[效能劣化加劇]
根本原因分析
flowchart LR
subgraph App端["App 端呼叫邏輯問題"]
A1[每個頁面切換\n都觸發 Account Summary]
A2[不只 Lobby,\n多個入口重複呼叫]
end
subgraph API端["API 端缺乏保護"]
B1[Announcement List\n每次直接查 DB]
B2[Inbox / Notification Count\n無 Cache]
B3[MessageHub 與 BO SPI\n共用同一台伺服器]
end
App端 --> C[呼叫量爆增]
API端 --> C
C --> D[DB 壓力過高\n30% 請求延遲]
兩層問題同時存在:
- App 端呼叫頻率過高 — Account Summary 不應在每個頁面都觸發,只需在 Lobby 主選單呼叫
- API 端缺乏 Cache 保護 — 公告列表、未讀數等低變動資料每次都直查 DB
以下為 App 中涉及高頻呼叫的 UI 元件位置:
改善方案
Ticket IDP-10145:App 端呼叫邏輯調整 + Announcement Cache
flowchart TD
subgraph Before["改善前"]
A1[任意頁面切換] --> B1[Account Summary API]
A2[Announcement 入口] --> B2[Announcement List API\n直接查 DB]
end
subgraph After["改善後 IDP-10145"]
C1[僅 Lobby Menu 觸發] --> D1[Account Summary API]
C2[Announcement 入口] --> D2[Announcement List API]
D2 --> E2{Redis Cache\n10 分鐘}
E2 -->|Cache Hit| F2[直接回傳]
E2 -->|Cache Miss| G2[查 DB 並寫入 Cache]
end
改善項目:
- 減少 Account Summary 呼叫 — 限制只在 Lobby Menu 觸發,消除其他頁面的多餘呼叫
- Announcement List 加入 10 分鐘 Cache — 公告內容變動頻率低,10 分鐘 Cache 可大幅降低 DB 壓力
Ticket IDP-10136:SPI 端 Cache 保護
flowchart TD
subgraph APIs["受保護 API"]
A[Get Inbox / Notification /\nAnnouncement Count]
B[Get Announcement List]
end
A --> C{Redis Cache\n5 分鐘}
B --> D{Redis Cache\n5 分鐘}
C -->|Hit| E[回傳快取結果]
C -->|Miss| F[查 DB 寫入 Cache]
D -->|Hit| E
D -->|Miss| F
改善項目:
- Inbox / Notification / Announcement Count — 加入 5 分鐘 Redis Cache
- Announcement List — 加入 5 分鐘 Redis Cache
基礎設施:MessageHub 拆分至獨立伺服器
原本 BO SPI 與 SPI MessageHub 共用同一台伺服器,MessageHub 的長連線特性會佔用大量連線資源,影響一般 SPI 的請求處理。
flowchart LR
subgraph Before["改善前(共用)"]
S1[Server]
S1 --- P1[BO SPI]
S1 --- P2[SPI MessageHub]
P2 -->|長連線資源競搶| P1
end
subgraph After["改善後(拆分)"]
S2[Server A] --- Q1[BO SPI]
S3[Server B] --- Q2[SPI MessageHub]
end
拆分後:
- BO SPI 與 MessageHub 資源互不干擾
- MessageHub 長連線不再影響一般 API 的回應速度
- 兩者可以各自獨立擴展(Scale Out)
改善效益預估
| 項目 | 改善前 | 改善後(預估) |
|---|---|---|
| Account Summary 日呼叫量 | ~1,610,000 次 | 大幅減少(僅 Lobby 觸發) |
| Announcement DB 查詢 | 每次呼叫都查 | Cache Hit 率 > 80%,DB 查詢降至 20% |
| Inbox Count DB 查詢 | 每次呼叫都查 | 5 分鐘內同一用戶只查一次 |
| API 延遲 > 門檻比例 | 30% | 預期降至 < 5% |
| MessageHub 對 SPI 影響 | 資源競搶 | 完全隔離 |
小結
這次效能問題的根源在於 App 端呼叫邏輯與 API 端保護機制都不完善,在正常流量下尚可接受,但一旦遇到歐洲盃這類流量高峰,就會造成 DB 無法服務的風險。
改善策略分三個層次:
- 呼叫頻率控制(App 端) — 從源頭減少不必要的 API 請求
- Cache 保護(API 端) — Redis 攔截高頻低變動資料,保護 DB
- 基礎設施隔離(部署端) — MessageHub 獨立,避免資源競搶
三者缺一不可,才能在歐洲盃高流量期間確保服務穩定。