具代表性的面試主題

面試題:跨 RPC 呼叫如何傳遞 deadline 與取消訊號?

後端困難
Offer.cc 編輯團隊發佈 更新

題幹

用戶只等待 2 秒,服務 A 呼叫 B、B 再呼叫 C。如何傳遞 deadline 與取消訊號,避免下游繼續做已經無效的工作?

題幹與適用場景

入口建立 2 秒使用者預算,A 已耗時 500 毫秒後呼叫 B,B 還會呼叫 C 與非關鍵稽核服務。請說明 deadline、取消、重試與觀測契約。時鐘不完全同步;只有唯讀 RPC 或帶冪等鍵的命令可重試。目標是在保留序列化與傳輸餘量下停止注定失敗的工作。

面試官考察點

Staff 系統設計準備資料要求候選人先釐清延遲、失敗與規模,再說明元件邊界和取捨。強回答應明確:入口只建立一個絕對截止時間;每一跳計算剩餘預算;取消沿呼叫樹傳遞;重試受冪等性與剩餘時間限制;指標能分辨 deadline 超時、呼叫端取消、排隊和取消後的無效工作。

回答前需要澄清的問題

  1. 2 秒是硬截止時間還是可接受的 SLO?硬截止時間代表遲到結果無效;要繼續處理就改成非同步工作。
  2. 哪些下游決定回應?稽核、推薦可降級,授權不可省略。
  3. 寫入是否冪等?沒有保護的副作用不可盲目重試。
  4. RPC 框架是否自動傳遞上下文?若沒有,使用攔截器統一實作並跨語言測試。
  5. 匯出等工作是否必須完成檢查點?若必須,建立有狀態非同步任務,不要讓同步 RPC 忽略取消。

30 秒回答框架

「入口建立唯一 deadline,所有 RPC 從上下文計算剩餘時間並保留回應餘量。服務在入隊與長工作迴圈中檢查取消;重試只用剩餘預算且要求冪等。呼叫端斷線或 hedge 有勝者時,取消沿呼叫樹傳到所有分支。我會記錄每跳剩餘預算、排隊時間、重試次數與停止延遲,再用慢下游、取消競態和時鐘偏差注入測試驗證契約。」

分步深入解答

1. 統一預算表示

入口記錄 t0 + 2s 的絕對 deadline,不讓每一跳重新增加 2 秒。服務計算 remaining = deadline - now,再扣除序列化與傳輸餘量。gRPC 文件區分 deadline 與 timeout,並將傳遞值轉成已扣除耗時的剩餘時間,降低時鐘偏差影響。應使用 RPC 上下文傳遞,避免容易漏傳的自訂字串標頭。

2. 按關鍵路徑花費預算

A 用掉 500 毫秒後,最多交給 B 1.5 秒。若 B 需要 400 毫秒本地處理並保留 100 毫秒回應餘量,呼叫 C 的預算不能超過剩餘值和 C 的上限。平行分支共享父 deadline,不可各自獲得完整 1.5 秒。入隊前先判斷預估排隊時間;來不及就快速拒絕或回傳文件化的降級結果。

3. 傳遞取消

截止時間到期、用戶斷線與 hedge 勝者都屬於取消原因。子 RPC 繼承父上下文,工作執行緒在入隊前及長迴圈的有界間隔檢查取消,釋放許可並關閉串流。Google SRE 指出只傳 deadline 仍可能洩漏呼叫樹工作;下游失敗後,取消應回傳並擴散到兄弟分支。需要安全檢查點的工作應改成獨立非同步任務。

4. 讓重試服從預算

attempt_deadline = min(parent_remaining - response_margin, per_attempt_cap)。下一次嘗試無法在父 deadline 前完成時立即停止。只重試瞬時錯誤,且操作必須天然冪等或帶冪等鍵。hedge 共用父預算,第一個可接受回應返回後取消其他嘗試。日誌保留原始 deadline 與 attempt 編號,避免把快過期的重試誤當新請求。

5. 定義可觀測失敗

對 deadline 超時回傳穩定狀態(例如 gRPC DEADLINE_EXCEEDED),保留原始取消原因。Trace 記錄入口與出口剩餘預算、排隊耗時、嘗試次數與取消到停止的延遲。用三跳測試驗證:C 慢於剩餘預算、B 排隊時 A 取消、第一個 hedge 成功、機器存在時鐘偏差;斷言子任務停止、重試終止且許可釋放。

高品質示範回答

「我會讓入口獨占 2 秒 deadline。A 消耗 500 毫秒後把剩餘預算放進 RPC 上下文交給 B,B 扣除回應餘量後呼叫 C;平行分支共享父預算。每個子呼叫在入隊和長工作中檢查取消,用戶斷線或 hedge 勝出時取消向下游擴散。重試必須冪等並受剩餘時間限制。稽核可以轉成可追蹤的非同步任務,但關鍵回應不能把遲到工作算成功。最後用慢依賴、排隊、取消競態和時鐘偏差做整合測試,並在 trace 顯示每跳預算。」

常見錯誤

  • 每跳重新設 2 秒 → 呼叫鏈按跳數放大延遲 → 傳遞單一 deadline。
  • 只傳超時不傳取消 → hedge 和斷線請求繼續占用執行緒 → 取消上下文扇出並測停止延遲。
  • 所有超時都重試 → 非冪等寫入產生重複副作用 → 分類錯誤、限制嘗試並要求冪等。
  • 先排隊再檢查預算 → 注定失敗的請求占滿容量 → 入隊前拒絕或降級。
  • 固定餘量沒有資料 → 大回應持續失敗或浪費預算 → 用傳輸和序列化分位數推導餘量。

追問及應對

服務時鐘不一致怎麼辦?

不要直接比較不同機器的牆上時鐘。使用 RPC 框架的剩餘時間轉換,或傳遞扣除已耗時的 timeout,並在測試注入時鐘偏移。

下游能否延長 deadline?

同步回應不能延長;遲到結果已不符合父契約。需要繼續處理時改成可查詢的非同步任務。

如何替慢回應保留餘量?

分別測量序列化與網路尾端延遲,設定有界餘量並限制載荷;餘量長期吃掉預算時調整 SLO 或回應形狀。

取消後哪些工作可以繼續?

只有冪等且持久化的檢查點或稽核事件,並透過任務 ID 觀測;不可繼續占用同步連線與工作執行緒。

公開來源

同類題目