題幹與適用場景
這道題考察你能否把傳輸層的低延遲最佳化轉化為清楚的業務安全邊界。TLS 1.3 Early Data 可能在連線建立前傳送,但 RFC 8470 明確提醒它存在重放風險;因此不能只按 HTTP 方法名稱決定請求是否安全。回答需要涵蓋請求分類、狀態機、冪等性、快取與代理、用戶端重試、監控及降級。
面試官考察什麼
- 能否區分「重複讀取無害」與「重複執行副作用」兩類語意。
- 能否把 Early Data 限制在明確的安全集合,並為不確定請求提供可解釋的拒絕路徑。
- 能否設計 425、冪等鍵、請求去重與重試退避之間的協作。
- 能否說明代理鏈、日誌、指標、回滾及逐步放量的風險控制。
回答前需要澄清的問題
先確認哪些請求可能攜帶 Early Data、TLS 終止點在哪裡,入口後是否還有代理或訊息重試。哪些操作會改變餘額、庫存、訂單、權限或發送通知?業務是否已有冪等鍵、請求狀態表與唯一約束?用戶端、SDK、閘道是否理解 425?重試由誰發起、最多幾次、是否使用指數退避與抖動?如果去重儲存不可用,是拒絕、降級到完整握手,還是允許唯讀請求繼續?
30 秒回答框架
我會預設把帶副作用或無法證明冪等的請求排除在 Early Data 之外。邊緣層識別 Early Data 並安全傳給應用;安全讀取可繼續,訂單、扣款與權限變更則回傳 425 或要求完整握手。對確實需要低延遲的寫入,使用用戶端提供的冪等鍵、伺服器唯一約束與短期結果快取,把「已執行」與「處理中」狀態持久化。用戶端只對明確可重試的結果做有上限與抖動的退避,逐步放量並監控重複執行、425、重試量與業務異常。
分步驟深入解答
1. 定義 Early Data 的信任邊界
在 TLS 終止層識別請求是否使用 Early Data,並以受保護的內部訊號傳給後端,不能讓公網用戶端任意偽造「安全請求」標記。代理、快取與服務間呼叫要明確是否會複製或延遲請求。預設策略應是未識別、訊號遺失或路徑不確定時按高風險處理。
2. 依據業務副作用分類
無狀態讀取、重複結果不影響資源的查詢通常較容易接受;建立訂單、扣款、庫存扣減、權限變更、發送訊息與觸發外部呼叫都應視為可重放風險。即使方法是 PUT 或 DELETE,也要確認實作確實符合冪等語意;POST 不代表一定不能冪等,關鍵在業務狀態模型與唯一約束。
3. 設計 425 與完整握手降級
對不允許 Early Data 的路徑回傳 425 Too Early,並提供可重試的回應標頭與文件約定,讓用戶端先完成完整握手再重送。閘道應避免收到 425 後自動無限重試;需要記錄原始請求是否可能已到達應用,防止邊緣層與用戶端各自重試造成放大。無法識別用戶端能力時,選擇明確失敗優於靜默執行。
4. 用冪等鍵與狀態機抵禦重複寫入
冪等鍵必須綁定租戶、操作類型與請求參數摘要,伺服器用唯一約束保存處理中、成功與失敗結果。並發到達同一鍵時,一個請求取得處理權,其他請求讀取狀態或等待有限時間;參數不一致直接拒絕。結果快取要設定保留期,避免舊結果與業務重試窗口不匹配。資料庫提交與外部副作用之間仍需採用交易外發、狀態輪詢或可補償設計。
5. 約束重試與代理行為
用戶端只在回應語意允許且請求符合冪等條件時重試,使用截斷指數退避、抖動與總次數上限。閘道、SDK、佇列消費者不能疊加無界重試;應區分 425、連線失敗、限流與業務拒絕。對高價值寫入,可讓用戶端查詢冪等鍵狀態,而不是重新傳送原始副作用請求。
6. 監控、放量與降級
先在唯讀路徑與少量租戶啟用,保留按路由、用戶端與地區關閉的開關。監控 Early Data 請求量、425 比例、重複鍵衝突、重複扣款或庫存異常、重試放大係數、握手降級延遲與去重儲存錯誤。發現指標越過門檻時停止放量、關閉 Early Data 或強制完整握手,並保留稽核樣本判斷請求是否實際執行。
高品質示範回答
我會把 Early Data 當作可能被重放的輸入,而不是普通 HTTPS 請求。入口識別並保護傳輸訊號,讀取類請求在風險可接受時繼續;下單、扣款、庫存、權限與外部通知預設回傳 425,要求完整握手。對確需低延遲的寫入,用戶端必須提供綁定租戶、操作與參數摘要的冪等鍵,伺服器用唯一約束與狀態機保存處理中、成功與失敗結果,參數衝突直接拒絕。425、連線失敗與限流分別定義重試條件,用戶端使用有上限的指數退避與抖動,閘道不做無限自動重試。先小範圍放量,監控 425、重複鍵、業務重複執行、重試放大、降級延遲與去重儲存故障;出現異常就關閉 Early Data 或強制完整握手,並核對稽核紀錄。
常見錯誤
- 認為 TLS 已加密,所以 Early Data 不會被重放。
- 只按 GET、POST 等方法名稱分類,不檢查實際業務副作用。
- 收到 425 後由閘道與用戶端同時無限重試。
- 冪等鍵不綁定租戶與參數,導致跨請求串用或參數衝突被吞掉。
- 只快取成功結果,不記錄處理中狀態與失敗可重試語意。
- 只看延遲收益,不監控重複扣款、庫存異常與重試放大。
- 沒有按路由關閉、完整握手降級與稽核核對方案。
追問及應對
425 與 429 有什麼差別?
425 表示請求在目前 Early Data 條件下過早,用戶端應在完整握手後重試;429 表示請求受到頻率或配額限制。兩者的重試條件、等待提示與監控含義不同,不能用同一個自動重試分支處理。
如果用戶端不支援 425 怎麼辦?
對關鍵寫入路徑在閘道直接拒絕 Early Data 或強制完整握手,避免依賴用戶端正確解讀狀態碼。升級 SDK 時提供相容策略;唯讀路徑可以繼續服務,但要記錄用戶端能力與風險邊界。
冪等鍵儲存掛了,是否允許扣款繼續?
不能在無法證明去重的情況下繼續高風險副作用。可以回傳可重試錯誤、降級到完整握手後再次檢查,或把請求轉為可查詢的待處理狀態;決策要以業務損失上限與恢復路徑為依據。
Early Data 請求已到達應用,隨後回傳 425,會不會仍然執行?
會有這種競態,所以應用必須在執行副作用前再次檢查 Early Data 訊號與冪等狀態,不能把 425 當作撤銷。所有副作用都透過狀態機與唯一約束提交,並用稽核紀錄確認是否已執行。