"Error-Contract"
- 11.11 Status 與錯誤的雙向契約
status 與錯誤是兩端的合作契約:provider 該讓 consumer 知道什麼、consumer 收到錯誤怎麼判讀與回報、以及單邊設計怎麼把成本外部化給對方
- Status 裝不下的東西:部分成功、延遲失敗、gateway 歧義
單一 status 表達不了部分成功、延遲失敗與 gateway 歧義時怎麼辦:把狀態下放 body 讓中介層變盲、或收窄語意保持 status 恆為真
- 接收方的重試決策:從單一請求到 retry 風暴
收到錯誤之後重不重試:從單請求的 status 加冪等合判、集體的去同步責任、到 retry 預算與斷路閘門
- 錯誤傳播與信任邊界:中間服務的雙重身分
錯誤跨服務傳遞時誰該轉譯、收到的錯誤能信多少、對外暴露多少細節 — 服務鏈上每一跳同時是 consumer 與 provider 的責任判準
- 錯誤回報的回饋迴路:request-id、trace 與呈現回報分工
consumer 收到錯誤之後怎麼跟 provider 溝通:error 要帶什麼定位鉤子、同一個錯誤怎麼分別投影給使用者與回報、持續錯誤什麼時候該升級
- 11.C64 RFC 4918 207 Multi-Status:status line 降格為「請讀 body」
一個 status code 裝不下批次結果:WebDAV 把每資源狀態下放到 body、解析責任隨之轉給 consumer
- 11.C65 Google AIP 部分成功立場:同步必原子、非同步才准部分成功且要顯式 opt-in
AIP-193 明文「不該支援 partial errors」、批次三部曲給出原子性階梯與 LRO 出口:部分成功要 client 顯式同意
- 11.C66 RFC 9110 202 Accepted:接受不等於承諾、HTTP 沒有回傳非同步結果的機制
202 是規範明文的 intentionally noncommittal:一旦回了 202、協定層不再有管道通知最終失敗、通知責任移轉到應用層
- 11.C67 RFC 9110 502/504:gateway 只回報自己的觀察、不回報上游的執行狀態
502/504 定義只說 gateway 沒收到有效或及時回應、沒有欄位區分「請求沒送到」與「執行了但回應丟了」— retry 安全性相反的兩種情況拿到同一個 code
- 11.C68 Exponential Backoff And Jitter:無 jitter 的退避是明確輸家
N 個 client 同時競爭時總工作量隨 N² 成長;三種 jitter 公式實測、Full Jitter 總工作量最少 — consumer 之間的隱性同步要主動打散
- 11.C69 Google SRE Book:retry 放大與跨層疊乘、per-request 上限與 retry budget
retry 放大讓有效工作遞減;三層各 retry 3 次在底層變 64 次;建議 per-request 上限 + server-wide retry budget、provider 要用不同 code 分開可重試與不可重試
- 11.C70 AWS DynamoDB 2015 事故:內部元件的 retry 自保把錯誤率推到 55%(反例)
反例:metadata 服務過載後 storage server 逾時自我下線再重試、風暴成形後系統不自癒、要人工暫停請求才能喘息;事後修正同時動兩端
- 11.C71 Slack 2021-01-04 事故:復原期 retry 加 circuit breaking 是藥方
retry 的反向平衡:網路恢復後正是 retry 與 circuit breaking 讓系統爬回服務狀態 — retry 是否有害取決於 provider 處於過載中還是恢復中
- 11.C72 AWS retry 指南:retry storm 的官方定義與分層限制
Well-Architected 逐字定義 retry storm、建議低層服務 retry 上限 0-1 次、把 retry 委派給上層;Builders' Library 的 token bucket 路線
- 11.C73 gRPC 兩層錯誤模型:status code 是保證層、richer detail 是選配層
標準模型全語言保證、richer error model 走 trailing metadata — proxy 與 logger 看不到、中間節點對錯誤細節是盲的
- 11.C74 gRPC status code 產生者歧義:收到的 code 不一定來自 server 應用層
17 個 code 裡只有 7 個保證來自 user code;UNAVAILABLE / INTERNAL 可能是 library 或 channel 自產 — consumer 對錯誤來源的信任判讀有一手依據
- 11.C75 AIP-193 錯誤內容規範:三層受眾與「不假設使用者懂內部實作」
機器可讀的 (reason, domain) 契約、developer-facing message、LocalizedMessage 三層分工;message 穩定性規則反向揭露 Hyrum's Law
- 11.C76 W3C Trace Context:traceparent 的傳播義務與 security boundary 重開機制
跨 vendor trace 關聯的標準鉤子:每一跳 MUST 傳播、security boundary 可 restart trace、無效 id MUST ignore — 信任邊界寫進規範
- 11.C77 OWASP error handling:錯誤訊息是攻擊者的偵察面
非預期錯誤回 generic response、細節只留 server side log — provider 少暴露的安全端論證、跟 AIP-193 的機器可讀路線形成張力