← Node / Backend Course

BACKEND ADVANCED · 145

Timeout / Retry / Idempotency:重送一次真的安全嗎?

分散式系統最麻煩的情況之一:client timeout,不知道 server 到底「沒做」還是「其實做成功但 response 丟了」。Retry 如果沒有 idempotency,可能把一次操作變兩次。

Learning outcomes

1. Ambiguous timeout

Client
  ↓ POST create
Server writes DB
  ↓
Response lost / delayed
  ↓
Client timeout

Client 只知道「沒收到 answer」,不知道 DB 是否已 commit。

2. Retry 可能重複 side effect

POST /payments
POST /payments  // retry

如果每次都建立新付款,就可能 double charge。

3. Idempotency key

Idempotency-Key:
  8f...client-operation-id

Server 保存 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 key

Knowledge check

  1. timeout 為什麼不是「server 沒做」的證明?
  2. GET 通常比 POST 更容易 retry 的原因?
  3. idempotency key 要在哪一層持久化才有意義?
  4. 設計一個最大 3 次 exponential backoff 策略。