具代表性的面試主題

系統設計面試:設計 CloudEvents 事件接入閘道

系統設計困難
Offer.cc 編輯團隊發佈 更新

題幹

設計一個多租戶閘道,接收 HTTP CloudEvents 並路由給內部消費者,既不丟事件,也不重複業務副作用。

題目與情境

生產方會重試,負載模式持續演進,流量也可能不均勻。閘道必須校驗信封、隔離租戶、保留投遞證據,並讓消費者明確面對至少一次投遞。

面試官在考察什麼

  • 把協議信封轉化為清晰的接入與投遞契約。
  • 選擇冪等範圍、重試狀態和持久化交接邊界。
  • 設計租戶隔離、模式演進和運維證據。

作答前的釐清問題

  • 每個租戶需要支援的峰值每秒事件數和負載大小是多少?
  • 生產方能否無限重試,是否要求按來源或主題有序?
  • 哪些消費者需要至少一次投遞,能否按來源加 ID 去重?
  • 是否有集中式模式註冊表,原始事件需要保留多久以支援重放?

30 秒回答框架

我會在認證邊緣終止 TLS,校驗 CloudEvents 信封和租戶配額,然後先持久化原始事件再確認接收。分區佇列向消費者提供至少一次投遞;當生產方保證 ID 穩定時,使用租戶、來源和 ID 作為去重鍵。消費者確認、重試計畫、死信、模式版本和租戶限額讓丟失與重複都可觀測。

分步深挖

1. 接入與校驗

支援結構化或二進制 HTTP 綁定,限制大小與內容類型,並校驗 specversiontypesourceid 等必填屬性。先認證租戶,信封無效時不進入持久化流程。保留接收位元組和請求標頭以便稽核與重放。

2. 選擇持久化邊界

在返回成功前,用一次持久化操作寫入不可變事件記錄以及 outbox 或日誌偏移。只在佇列發布尚未提交時確認可能丟事件;只用資料庫又可能限制高吞吐扇出。說明延遲和持久性取捨。

3. 去重但保留重試事實

使用租戶範圍的 (source, id) 鍵,保留時間覆蓋生產方重試。保存負載摘要與模式版本;同一鍵對應不同位元組時衝突並隔離。把投遞嘗試與邏輯事件分開,保持重試可觀測。

4. 投遞與重試

消費者從分區拉取,或透過帶租約的推送接收。成功確認推進嘗試;超時和暫時錯誤使用帶抖動的指數退避。永久失敗進入租戶範圍的死信流,並提供受稽核的重放控制。

5. 演進與運營

入口校驗模式版本,不相容的事件進入隔離區,並支援消費者聲明能力。按租戶和來源統計接收、拒絕、重複、延遲、重試、死信和重放。實施配額、加密、保留與存取控制,不記錄密鑰或無限制負載。

高品質示範回答

「我會在邊緣認證租戶、校驗 CloudEvents 信封、限制大小和配額,再把原始事件和請求標頭持久化後確認接收。分區日誌提供至少一次投遞。生產方保證 ID 穩定時,去重鍵使用租戶加來源加 ID;同一鍵摘要變化就隔離。消費者確認推進嘗試,暫時錯誤帶抖動退避,永久錯誤進入可重放死信流。模式版本、租戶指標、保留策略和稽核日誌讓投遞語義明確。」

常見失誤

  • 持久化前確認 → 崩潰會丟事件 → 在選定持久化邊界後確認。
  • 全局按 ID 去重 → 租戶或來源會衝突 → 限定鍵範圍並校驗摘要。
  • 承諾恰好一次 → 重試和消費者副作用仍可能發生 → 聲明至少一次並要求消費者冪等。
  • 丟棄不相容模式 → 無法除錯和重放 → 隔離並保留帶版本證據。

追問與回答

閘道能保證有序嗎?

只能在明確範圍內保證,例如來源和主題分區。保留序列資訊,讓同一鍵進入同一分區,並說明重試或並行消費者可能延遲後續事件。

生產方重用 ID 但更換負載怎麼辦?

比較已保存摘要,衝突時拒絕或隔離。不能靜默覆蓋首個事件,應告警生產方,因為去重契約已被破壞。

如何支援租戶級重放?

保留不可變事件記錄,使用綁定授權的重放令牌、新的嘗試 ID、速率限制和稽核軌跡。重放仍需通過模式與去重校驗,不能繞過消費者隔離。

公開來源

同類題目

相關面試工具

用 Solve 整理系統設計回答

從澄清需求開始,展開規模、架構、元件選擇和取捨。

查看工具