將給定埠的傳入網路請求路由到不同的應用程序
我有一個應用程序可以偵聽埠上的連接,但我偶爾會將其關閉以進行更新等。我想要一種配置系統的方法,這樣如果該程序正在執行,則對該埠的請求將發送到應用程序,但如果它未執行,則將請求定向到其他應用程序(可以返回“暫時不可用”資訊)。實現這一目標的最簡單方法是什麼?
我在目標機器上沒有 root 訪問權限,所以我寧願避免使用
iptables
. 我考慮過一個輔助應用程序,它除了路由到其他兩個應用程序的連接之外什麼都不做,但我希望有一種更簡單的方法
您的問題意味著這兩個程序將在同一台機器上交替執行,綁定到同一個埠。這是一個壞主意。如果你嘗試這個,你會遇到
TIME_WAIT
(又名 2MSL)問題。這篇文章描述了這個問題。(它以 Windows 為中心,但它所談論的大部分內容適用於任何 TCP/IP 堆棧。)BSD 套接字 API 確實提供了一種方法來破壞這種保護 (
setsockopt(SO_REUSEADDR)
),但這不是這樣做是合理的情況之一。相反,請以與高可用性人員相同的方式解決問題:在世界和您的“真實”後端伺服器之間放置一個反向代理。
在 HTTP 世界中,解決此問題的一種流行方法是nginx。您可以對其進行配置,以便在後端伺服器關閉時向客戶端提供靜態內容。如果您的協議看起來像 HTTP、IMAP 或 POP,也許您可以按原樣使用 nginx。如果沒有,您可以建構自定義代理伺服器。
您可能需要兩個 TCP 埠才能使其工作。代理綁定到公共 IP 上面向公眾的埠號。您的後端伺服器僅在 localhost 介面上綁定到輔助埠。因此,流量只能通過代理從公共網路到達後端伺服器。
如果兩個程序都被編寫為允許,您可以將兩者綁定到同一個埠。例如,如果您的公共 IP 是
1.2.3.4
並且您的公共服務埠是,則如果反向代理僅綁定到 IP並且“真實”伺服器僅綁定到 ,則2345
兩個程序都可以綁定到埠。如果任一綁定到(0.0.0.0),則需要不同的埠。2345``1.2.3.4``127.0.0.1``INADDR_ANY
這解決了 2MSL 問題,因為您的客戶端始終與同一個程序(代理伺服器)通信。網路堆棧永遠不會對如何處理在 2MSL 時間內掃過的任何雜散數據包感到困惑。
反向代理的一個變體是負載均衡器,它也可以在這里工作。負載均衡器旨在智能地將流量路由到不同的機器。如果您認為您的應用程序有一天可能需要水平擴展,那麼這種代理將是有意義的。當所有正常的應用程序伺服器都關閉時,您將選擇一個知道如何將流量發送到特殊的“服務關閉”主機的負載均衡器。
負載均衡器解決方案變體的主要問題是通用負載均衡器可能會盲目地假設它代理的所有後端服務都使用相同的埠號,僅在 IP 上有所不同。不過,您也許可以獲得更靈活的負載均衡器,或者為您的共享伺服器獲得多個 IP。