具代表性的面試主題

HTTP/3 如何用 GOAWAY 實現可觀測的優雅下線?

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

題幹

你要滾動升級 HTTP/3 閘道,不能中斷已接受的請求,也不能讓用戶端重複提交非冪等請求。請說明 GOAWAY 語義、伺服器下線順序、重試與驗證指標。

題目與背景

HTTP/3 閘道承載長連線和多路並行請求。發布新版本時,希望拒絕新請求、讓已接受請求完成,並在逾時後安全關閉。請基於 RFC 9114 設計 GOAWAY 下線流程,說明它與 QUIC 關閉及 HTTP 重試的邊界。

面試官考察什麼

重點是區分 GOAWAY 的「限制後續請求」與 CONNECTION_CLOSE 的「終止 QUIC 連線」。HTTP/3 GOAWAY 帶有請求串流 ID 上界,伺服器可先送較大值再遞減到最終邊界。還要涵蓋並行、客戶端判斷未處理請求、冪等性、代理、逾時與觀測。

先問清楚的澄清問題

請求與連線形態

確認是否有長輪詢、上傳、WebTransport 或非冪等 POST,以及是否經過反向代理。不同串流的完成時間與重試風險不同。

下線目標與逾時

釐清是連線排空、節點維護或故障隔離,設定最大排空與硬關閉時間及發布批次。沒有上限會讓舊連線無限占用資源。

用戶端能力

確認用戶端和代理是否正確處理 GOAWAY、是否支援遷移與重連,以及能否區分「伺服器拒絕新串流」和「請求已執行但回應遺失」。

30 秒回答框架

「HTTP/3 GOAWAY 宣告請求串流 ID 上界,收到後不能建立超過邊界的新請求。伺服器先送較寬的 GOAWAY 觀察並行請求,再遞減到最終邊界,讓用戶端知道哪些請求可能未處理。排空期間保留已接受串流,逾時後以 QUIC CONNECTION_CLOSE 結束。用戶端只在確認請求未執行且可安全重試時重試。」

深入解答步驟

第一步:區分 GOAWAY 與 CONNECTION_CLOSE

GOAWAY 是 HTTP/3 控制訊息,限制請求串流最大 ID,不會立即終止連線。CONNECTION_CLOSE 會關閉 QUIC,可能中斷執行中的請求。下線先排空,硬逾時才關閉。

第二步:採用先寬後窄的邊界

先送較大 ID 覆蓋已觀察到的並行請求,停止新工作後再送較小的最終 ID。用戶端不能把遞減過程視為允許新請求的訊號,實作要保存控制訊息順序和狀態。

第三步:處理已接受、未開始與未知請求

低於最終邊界且已建立的串流繼續完成;高於邊界的請求視為未接受,可在新連線重試。若無法判斷非冪等請求是否執行,應用需要冪等鍵或查詢路徑,不能盲目重放。

第四步:設計代理與連線遷移

反向代理收到上游 GOAWAY 後應停止向該連線分配新請求並傳播狀態。QUIC 連線遷移不等於請求遷移;不能假定換路徑即可安全轉移執行中的串流。

第五步:設定排空與硬關閉

記錄 GOAWAY 時間、最後活動串流和剩餘請求。排空逾時後取消仍未完成串流,硬關閉時間到才用 CONNECTION_CLOSE 釋放連線。控制器要限制同時下線實例數。

第六步:保護重試與副作用

只對確認未執行的冪等方法或帶冪等鍵的寫操作重試,使用退避與預算。回應遺失不代表請求未執行;付款或扣庫存等副作用必須由伺服器去重。

第七步:驗證發布效果

灰度注入長請求、並行串流、重連、GOAWAY 遞減、代理轉發和硬關閉。監控新串流拒絕、排空時間、未完成串流、重試率、重複副作用、連線錯誤和容量餘量。

高品質示例回答

我會先停止新連線分配,再送寬範圍 GOAWAY 讓用戶端停止建立新串流;確認並行請求後送更小的最終邊界。低於邊界的已接受串流完成,逾時才取消並以 CONNECTION_CLOSE 釋放連線。用戶端只對確認未執行且冪等的請求重試,非冪等寫操作依賴冪等鍵。代理需傳播狀態,連線遷移不能當作請求遷移。

常見錯誤

  • 錯誤: 發送 GOAWAY 就立即關閉 QUIC。→ 原因: 執行中的請求會被中斷。→ 改進: 先排空,硬逾時才關閉。
  • 錯誤: 把 GOAWAY 上界當成已執行清單。→ 原因: 串流 ID 只表示範圍。→ 改進: 用應用狀態和冪等鍵確認結果。
  • 錯誤: 所有失敗請求都自動重試。→ 原因: 回應遺失可能伴隨副作用。→ 改進: 限定冪等方法或帶鍵寫入。
  • 錯誤: 連線遷移可以轉移執行中的請求。→ 原因: 路徑變化不改變 HTTP 串流狀態。→ 改進: 透過新連線安全重試。

追問與回答

追問 1:為什麼 GOAWAY 可以遞減?

伺服器先覆蓋已觀察到的並行請求,再確定最終不接受的新串流邊界。遞減讓用戶端逐步收斂到安全邊界。

追問 2:用戶端如何判斷請求是否被接受?

比較串流 ID 與最終邊界只能判斷可能範圍,不能證明應用是否執行,還要結合回應、連線錯誤與冪等查詢。

追問 3:GOAWAY 會自動跨代理傳播嗎?

不應假定。代理是獨立端點,需要把上游排空狀態轉換為下游連線和路由策略。

追問 4:硬關閉前為何還要取消串流?

先取消可釋放應用資源並記錄原因,讓用戶端區分排空逾時與網路故障;最後關閉 QUIC 才是資源邊界。

公開來源

同類題目