簡體   English   中英

我們能否長時間可靠地保持 HTTP/S 連接打開?

[英]Can we reliably keep HTTP/S connection open for a long time?

我的團隊維護着一個處理長時間運行的批處理作業的應用程序(用 Java 編寫)。 這些作業需要按定義的順序運行。 因此,應用程序在預定義端口上啟動套接字服務器以接受作業執行請求。 它使套接字保持打開狀態,直到作業完成(成功或失敗)。 通過這種方式,作業調度程序知道一個作業何時結束,並且在作業成功完成后,它會按預定義的順序觸發下一個作業。 如果作業失敗,調度程序會發出警報。

這是我們已經有十多年的設置。 我們有一些作業只運行幾分鍾,而另一些則需要幾個小時(取決於數量)才能完成。 該設置工作正常,沒有任何問題。

現在,我們需要將該應用程序移動到一個容器(RedHat OpenShift 容器平台),並且現有的基礎設施策略只允許公開默認的 HTTPS 端口。 調度程序位於 OCP 之外,無法訪問除默認 HTTPS 端口以外的任何端口。

理論上,我們可以使用 HTTPS,將客戶端超時設置為非常長的持續時間,並嘗試模仿 TCP 套接字的當前設置。 但是這種設置是否足夠可靠,因為 HTTP 協議旨在為短期請求提供服務?

由於節點(路由器、負載均衡器、代理、nat 網關等)可能位於您的客戶端和服務器之間,因此沒有一種可靠的方法可以在 inte.net 上長時間保持連接,它們可能在負載下放棄中間連接,他們中的一些人會很高興地忽略你的 HTTP 保持活動請求,或者有一個內部最大連接持續時間會殺死長時間運行的 TCP 連接,你今天可能會發現它對你有用,但不能保證它會工作明天給你。

因此,您可能需要將作業作為短期請求提交並通過其他方式檢查狀態:

  • 基於推送的策略通過發送一個 webhook URL 作為作業提交的一部分,並讓服務器在作業完成時調用它(可能會重試)以通知相關方。
  • 基於拉取的策略,讓服務器在提交時返回作業 ID,然后讓客戶端定期檢查。 由於您的工作持續時間的性質,您可能希望通過某種形式的指數退避來實現這一點,直到達到一定的限制,例如,先等待 2 秒后檢查,然后等待 4 秒再進行下一次檢查,然后等待 8 秒,依此類推,直到您願意在每次檢查之間等待的最大時間。 這樣您就可以更快地了解短期工作的完成情況,而不必過於頻繁地檢查長期工作。

當您使用套接字和 TCP 協議時,您可以控制保持連接打開的時間。 使用 HTTP,您只能控制邏輯連接,而不能控制物理連接。 實際連接由操作系統控制,通常 IT 人員可以配置所有這些超時。 但默認情況下,它的工作原理是,當您甚至關閉邏輯連接時,實際連接並沒有關閉,以等待下一次通信。 它由操作系統關閉,不受您的代碼控制。 但是,即使它關閉並且您的下一個請求之后它也會對您透明地打開。 所以它是否關閉並不重要。 它應該對您的代碼透明。 所以簡而言之,我假設您可以毫無問題地遷移到 HTTP/HTTPS。 但是你必須測試看看。

關於服務器到客戶端通信的其他選項,您可以查看我對這個問題的回答: How to continues send data from backend to frontend when something changes

恕我直言,您應該將調度程序改進為 REST API 服務器,Websocket 在這種情況下無效,大部分時間連接將處於非活動狀態

這些作業可以是短暫的或長期運行的。 那么,當一個長時間運行的作業中途失敗時,作業的重啟是如何發生的呢? 是從頭再來嗎?

在類似的場景中,我們有一個數據庫來跟蹤作業的進度(沒有成功處理的記錄)。 因此,作業可以在失敗后恢復。 通過這樣的設計,另一個 web 服務可以通過查看數據庫來監控作業的狀態。 因此,主進程不受客戶端不斷輪詢的影響。

我們在長期存在的 HTTP/HTTPS 連接方面有過糟糕的經歷。 我們過去常常通過 HTTP 安排短期工作(只有幾分鍾)並等待它完成並發送響應。 這工作正常,直到工作變得更長(小時)並且一些網絡基礎設施關閉了非活動連接。 我們最終只通過 HTTP 提交請求,立即得到響應,然后實施輪詢以等待響應。 當時,遷移對我們來說非常快,但從那時起我們進一步遷移它以使用“webhooks”,例如允許作業的處理器使用已知的 webhook 地址將其 state 發回服務器。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM