API 一直掛怎麼辦?三層容錯讓使用者無感
我請 Claude 一段一段教我讀蒸餾精華。第一段講 API 呼叫的三道防線,我一開始以為是「避錯」,結果搞錯了。
梵谷《麥田與柏樹》(Wheat Field with Cypresses),1889 年。梵谷(Vincent van Gogh)於聖雷米精神療養院期間創作此畫,翻騰的天空、搖曳的麥浪與挺拔的柏樹,以厚重筆觸與旋轉線條交織,展現他對普羅旺斯風景的強烈情感投射。現藏於紐約大都會藝術博物館。
你的程式呼叫外部 API,突然回傳 500 錯誤。使用者只看到一個空白畫面,什麼都做不了。這種事不是偶爾發生,而是遲早會發生——差別只在你有沒有準備好防線。
三層容錯架構
只要你的服務依賴外部 API(抓資料、呼叫 AI、第三方登入),就需要這套防線。核心精神:錯誤一定會來,但使用者不該感受到。
┌─────────────────────────────────────────────┐
│ Tier 1(主要 API) │
│ → 4 次重試,指數退避 + 隨機抖動 │
│ → 5xx 才重試,4xx 直接放棄 │
├─────────────────────────────────────────────┤
│ ↓ 全部失敗 │
├─────────────────────────────────────────────┤
│ Tier 2(備用 API) │
│ → 同樣 4 次重試 │
├─────────────────────────────────────────────┤
│ ↓ 全部失敗 │
├─────────────────────────────────────────────┤
│ Tier 3(最終 API) │
│ → 同樣 4 次重試 │
├─────────────────────────────────────────────┤
│ 每次降級 → 自動發 Webhook 通知 │
└─────────────────────────────────────────────┘
三件事讓這套架構有效:重試(同一個 API 再試幾次)、降級(主要的掛了,自動換備用)、通知(每次降級都告訴你,事後能處理)。
關鍵區分
| 錯誤類型 | 該怎麼做 | 為什麼 |
|---|---|---|
| 5xx(伺服器掛了) | 重試 | 通常是暫時的 |
| 4xx(請求有問題) | 直接停 | 重試也沒用 |
我的追問與發現
「這就是一個好的『避錯』架構吧?」
不是「避錯」,是「容錯」。差一個字,觀念完全不同。避錯是想辦法不讓錯誤發生(幻想),容錯是承認錯誤一定會來,但設計好防線讓使用者感受不到(工程)。
「不打 API 的服務需要這個嗎?」
不需要。純靜態 HTML 頁面沒有外部依賴,完全不需要這套。這個模式只在「你依賴別人的服務」時才有價值。依賴越多、越關鍵,架構就越重要。
你可以怎麼用
- 盤點你的專案裡有哪些外部 API 呼叫,列出來
- 最關鍵的那個 API,先加上重試 + 指數退避(不需要三層,一層就有用)
- 區分 4xx 和 5xx 的處理邏輯,別傻傻全部重試
- 加一個通知機制(Slack Webhook、Email、LINE Notify 都行),讓降級不是無聲的
延伸連結
- 頁面載入太慢怎麼辦?先給舊資料,背景再更新 — API 掛了有容錯,那 API 太慢呢?
- 該綁住 AI 還是放飛它?看錯誤代價決定自由度 — 容錯是對外部服務,那對 AI 的不可預測性呢?
一句話帶走
避錯是幻想,容錯是工程——錯誤會來,但使用者不該感受到。
📚 完整學習對話紀錄(想看完整脈絡可展開)
原文(蒸餾精華 第 1 段)
最可靠的 API 呼叫模式:
Tier 1(主要)→ 4 次重試,指數退避 + 隨機抖動
↓ 失敗
Tier 2(備用)→ 4 次重試,同上
↓ 失敗
Tier 3(最終)→ 4 次重試,同上
↓ 每次降級都發 Webhook 通知
關鍵細節:
- 區分 5xx(可重試)和 4xx(直接放棄)
- 指數退避 + 隨機抖動避免雷擊效應
- 每次降級自動通知(Google Chat Webhook)
Claude 的白話解釋
你呼叫外部 API 時,不要只試一次就放棄。這個模式設計了三道防線:
主要 API → 試 4 次失敗 → 換備用 API → 再試 4 次失敗 → 換最終 API → 再試 4 次
每次重試之間的等待時間會越來越長(指數退避),而且加一點隨機秒數(抖動),避免一堆使用者同時重試把伺服器打爆(雷擊效應)。
為什麼好?
- 4xx 錯誤(你的請求有問題)→ 直接停,不浪費時間重試
- 5xx 錯誤(伺服器掛了)→ 值得重試,可能只是暫時的
- 每次降級都自動發 Webhook 通知 → 你不在電腦前也知道出事了
實際應用:任何你寫的程式只要會打外部 API(抓網頁、呼叫 AI 服務、短網址跳轉預覽),都應該套這個模式。
我的提問:這就是一個好的「避錯」架構吧?
讀完之後我的直覺是:情境發生在當服務有呼叫 API 的時候,這就是一個好的避錯架構,對吧?
Claude 的修正:不是「避錯」,是「容錯」
更精確地說:不是「避錯」,是「容錯」。
錯誤一定會發生(網路斷、伺服器掛、API 限流),你避不掉。這個架構的精神是:
錯誤會來,但使用者不該感受到。
它做了三件事:
- 重試 — 同一個 API 再試幾次(因為很多 5xx 是暫時的)
- 降級 — 主要的真的掛了,自動換備用的頂上
- 通知 — 每次降級都告訴你,讓你事後能處理
如果你的服務不呼叫外部 API(比如純靜態 HTML 頁面),就完全不需要這個。這個模式只在「你依賴別人的服務」時才有價值。
依賴越多、越關鍵,這個架構就越重要。
我學到的
「避錯」跟「容錯」差一個字,觀念完全不同。避錯是想辦法不讓錯誤發生,容錯是承認錯誤一定會來,但設計好防線讓使用者感受不到。前者是幻想,後者是工程。