BACKEND ADVANCED · 145
Timeout / Retry / Idempotency:重送一次真的安全嗎?
分散式系統最麻煩的情況之一:client timeout,不知道 server 到底「沒做」還是「其實做成功但 response 丟了」。Retry 如果沒有 idempotency,可能把一次操作變兩次。
Learning outcomes
- 能解釋 timeout 不代表 remote operation 一定沒執行。
- 能辨識哪些 operation 可安全 retry。
- 能設計 idempotency key 基本流程。
- 能區分 transient 與 permanent failure。
1. Ambiguous timeout
Client
↓ POST create
Server writes DB
↓
Response lost / delayed
↓
Client timeoutClient 只知道「沒收到 answer」,不知道 DB 是否已 commit。
2. Retry 可能重複 side effect
POST /payments
POST /payments // retry如果每次都建立新付款,就可能 double charge。
3. Idempotency key
Idempotency-Key:
8f...client-operation-idServer 保存 key → operation result;相同 key 重送時回同一個 outcome,而不是再做一次 side effect。
4. Retry policy
| Failure | 通常策略 |
|---|---|
| validation 400 | 修 input,不盲目 retry |
| auth 401/403 | 修 credential/permission |
| rate limit 429 | 依 Retry-After/backoff |
| transient 5xx/network | 可能 retry,但要有上限與 jitter/backoff |
5. Backoff 與 Retry Budget
Retry 不應無限立即重送。常見設計會限制最大次數,使用 exponential backoff,並加入 jitter,避免大量 clients 在同一時間再次打爆正在恢復的服務。
attempt 1
wait ~200ms
attempt 2
wait ~400ms
attempt 3
stop / surface failure
真正參數要依 service contract、deadline、operation cost 決定;不是所有 5xx 都應自動 retry。
6. Idempotency record 也需要 lifecycle
Server 需要決定 key 的 scope、保存多久、request payload 是否必須一致,以及 operation 還在 processing 時重送要回什麼。只在 process memory 用 Set 記 key,process restart 後就失去保護,通常不足以保證重要 side effect。
Project checkpoint:Course import operation
POST /course-imports
Idempotency-Key: abc123
server:
lookup key
if completed:
return saved result
else:
perform import
save result with keyKnowledge check
- timeout 為什麼不是「server 沒做」的證明?
- GET 通常比 POST 更容易 retry 的原因?
- idempotency key 要在哪一層持久化才有意義?
- 設計一個最大 3 次 exponential backoff 策略。