# 🚨 Cloud Run 伺服器 Memory Leak 事故分析報告

這是一份以 **5W2H** 結構整理的事故分析報告，透過生活化的比喻與技術解析，說明本次伺服器記憶體異常攀升的原因與解決方案。

---

## 🔍 5W：發生了什麼事？

### 1. 👤 Who (誰受影響 / 誰發現的？)
*   **受影響範圍**：所有存取網站的使用者。
*   **相關人員**：負責維護系統與前端架構的工程師團隊。

### 2. ❓ What (發生了什麼事？)
伺服器發生了俗稱的 **Memory Leak（記憶體洩漏）**。
> 💡 **生活化比喻**：想像伺服器的「記憶體」是一個大水槽。正常情況下，處理完網頁請求後，用過的水就會排掉（也就是 Garbage Collection 垃圾回收機制）。但現在排水管塞住了，水一直流進來卻排不出去，最後水槽滿出來（Out Of Memory），導致伺服器當機或重啟。

### 3. 🕒 When (什麼時候發生的？)
*   **潛在問題引入**：今年 2 月底，工程師寫下了引發問題的程式碼。
*   **問題引爆點**：在 **3 月 17 日下午 13:01**，該段程式碼被正式發布到雲端伺服器後，隨著網站流量增加，記憶體即開始呈現線性且無法回復的上升趨勢。

### 4. 📍 Where (在哪裡發生的？)
*   **雲端主機**：GCP Cloud Run（位於亞洲東區 `asia-east1` 的 `cola-flight` 服務）。
*   **程式碼位置**：`app/_lib/core/fetcher.js` 檔案內部（負責處理全站 API 資料請求的核心通道）。

### 5. 🤔 Why (為什麼會這樣？)
這是由於為了規避框架限制，而採取了不適當的動態載入方式：
*   **原本面臨的限制**：在 Next.js 的快取機制 (`unstable_cache`) 中，系統規定不能直接讀取使用者的 Request Headers，否則會觸發編譯或執行錯誤。
*   **導致問題的解法**：為了規避報錯，工程師使用了 `await import('next/headers')` 這個寫法，也就是**「動態載入模組」**。

> 💡 **生活化比喻**：這就像是為了解決「圖書館不能大聲說話」的規定，發明了一招：「那我每次都花錢請一個『外送員』把紙條偷偷送進來！」。
> 
> 結果，只要有人點擊網頁，系統就叫一個外送員。悲劇的是，因為 Node.js/Webpack 底層機制的缺陷，**這些外送員送完紙條後，產生的紀錄竟然留在圖書館不走了（系統無法自動回收他們）**！最後幾千個外送員把圖書館擠爆，伺服器資源耗盡而崩潰。

---

## 🛠️ 2H：證明與解決方案

### 6. 🔬 How (如何證明是它惹的禍？怎麼修復？)

**🕵️‍♂️ 證明方式 (A/B 壓力測試對比)**
我們可透過科學的壓力測試（Load Testing）直接驗證：
1. **壓測當前版本（異常版）**：使用測試軟體在一秒內對伺服器發送大量請求。監控圖表會顯示伺服器記憶體瞬間飆高，且測試結束後，**記憶體使用量無法回落**（外送員不走），證實洩漏確實存在。
2. **壓測修復版本（正常版）**：將程式碼裡的「動態載入」改為「靜態載入」。再次進行相同的壓測，記憶體在測試期間會微幅上升（正常資源配置），但測試結束後，**會迅速掉回原本的安全基準線**，100% 證明了原程式碼即為元凶。

**✅ 修復建議**
避免在每次請求時動態載入核心模組。應將代碼修改如下：
```javascript
// ❌ 錯誤示範：於 Request 生命週期內頻繁動態載入
const { headers } = await import('next/headers');
```
改為檔案頂端靜態宣告：
```javascript
// ✅ 正確示範：於檔案頂部靜態載入
import { headers } from 'next/headers'; 
```
**最佳實踐**：**不要在最底層的 fetcher 讀取 Request Context**。應由最外層的頁面（Page/Layout）準備好需要的資料（如 Correlation ID），再以參數形式「傳遞」給 fetcher，從根本上解耦並消除潛在的快取衝突與記憶體問題。

### 7. 💰 How much (影響程度與代價？)
*   **系統可用性受損**：記憶體被耗盡後，Cloud Run 容器會被迫重啟。這會導致瞬間的 API 請求中斷，使用者會遇到卡頓或 502/503 錯誤畫面。
*   **運算資源浪費**：高頻繁的動態載入（`await import`）會增加不必要的 CPU 開銷與解析時間，拖慢整體網站的 API 回應速度，並無謂地增加了雲端資源的帳單成本。
