接続のためにポートをリッスンするアプリケーションがありますが、更新などのために時々オフになることがあります。プログラムが実行されている場合は、ポートへの要求がアプリケーションに送信され、プログラムが実行されていない場合は、要求が別のアプリケーションに転送されるようにシステムを構成する方法が必要です(おそらく「一時的に」を返します)。利用できません") メッセージ). これを達成する最も簡単な方法は何ですか?
ターゲットコンピュータへのrootアクセス権がないためiptables
。
答え1
あなたの質問は、両方のプログラムが同じコンピュータで交互に実行され、同じポートにバインドされることを意味します。これは悪い考えです。これを実行しようとすると、TIME_WAIT
問題(別名2MSL)が発生します。この記事問題を説明します。 (Windows中心ですが、ここで議論する内容のほとんどはすべてのTCP / IPスタックに適用されます。)
BSDソケットAPIはこの保護を無効にする方法()を提供しますsetsockopt(SO_REUSEADDR)
が、これは合理的なケースの1つではありません。
代わりに、高可用性ユーザーと同じ方法で問題にアクセスしてください。リバースプロキシ世界と「実際の」バックエンドサーバー。
HTTP 世界でこの問題を解決する一般的な方法は次のとおりです。nginx。バックエンドサーバーがダウンしたら、クライアントに静的コンテンツを提供するように構成できます。プロトコルがHTTP、IMAP、POPのようなものであれば、nginxをそのまま使用できます。そうでない場合は、カスタムプロキシサーバーを構築できます。
正しい動作には 2 つの TCP ポートが必要な場合があります。プロキシはパブリックIPのパブリックポート番号にバインドされます。バックエンドサーバーは、localhostインターフェイスのセカンダリポートにのみバインドされます。このように、トラフィックはプロキシを介してのみパブリックネットワークからバックエンドサーバーに到達できます。
両方のプログラムが同じポートにバインドできるように作成されている場合は、バインディングをエスケープできます。たとえば、パブリックIPがパブリック1.2.3.4
サービスポートがある場合、リバースプロキシが2345
IPにのみバインドされ、「本物の」サーバーがポートにのみバインドされている場合、両方のプログラムがポートにバインドできます。どちらかが(0.0.0.0)にバインドされている場合は、別のポートが必要です。2345
1.2.3.4
127.0.0.1
INADDR_ANY
クライアントは常に同じプログラム(プロキシサーバー)と通信するため、これは2MSLの問題を解決します。ネットワークスタックは、2MSL時間内に消去された迷子になったパケットをどのように処理するかを混同しません。
リバースプロキシのバリエーションは次のとおりです。ロードバランサー、ここでも動作します。ロードバランサは、インテリジェントにトラフィックを他のシステムにルーティングするように設計されています。この種のプロキシは、アプリケーションがいつか水平に拡張する必要があると思う場合に適しています。すべての一般的なアプリケーションサーバーがダウンしたときに特別な「サービスダウン」ホストにトラフィックを送信する方法を知っているロードバランサーを選択します。
ロードバランサソリューションのバリエーションの主な問題は、ユニバーサルロードバランサがプロキシするすべてのバックエンドサービスが同じポート番号を使用し、IPのみが異なると盲目的に想定できることです。ただし、より柔軟なロードバランサーを取得したり、共有サーバーに対して複数のIPを取得したりできます。