Node.js プロダクション スタックでも同様の問題が発生しました。通常のユースケースで機能するWebSocketを使用する2つのサーバーがありますが、ロードバランサーが2つのサーバー間でこれらの接続をバウンスし、問題が発生することがあります. (バックエンドにセッション コードがあり、修正されているはずですが、適切に処理されませんでした。)
これらのサーバーの前にある Barracuda ロード バランサーで Sticky Session を有効にしようとしましたが、動作方法が原因で WebSocket トラフィックがブロックされることがわかりました。オンラインで入手できる情報がほとんどないため、正確な理由は調査していませんが、バランサーが HTTP リクエストのヘッダーを取り除き、Cookie を取得し、リクエストを正しいバックエンド サーバーに転送する方法によるものと思われます。WebSockets は HTTP として開始され、その後アップグレードされるため、ロード バランサーは接続の違いに気付かず、同じ HTTP 処理を実行しようとします。これにより、WebSocket 接続が失敗し、ユーザーが切断されます。
以下は、現在非常にうまく機能している場所です。バックエンド サーバーの前に Barracuda ロード バランサーを引き続き使用していますが、ロード バランサーでスティッキー セッションを有効にしていません。バックエンド サーバーでは、アプリケーション サーバーの前に HAProxy があり、これは WebSocket を適切にサポートし、スティッキー セッションを「回り道」で提供できます。
リクエストフロー一覧
- 着信クライアント リクエストがプライマリ Barracuda Load Balancer にヒットする
- ロード バランサーは、アクティブなバックエンド サーバーのいずれかに転送します
- HAProxy がリクエストを受け取り、新しい「スティッキー Cookie」をチェックします
- Cookie に基づいて、HAProxy は正しいバックエンド アプリケーション サーバーに転送します。
リクエストフロー図
WebSocket Request /--> Barracuda 1 -->\ /--> Host 1 -->\ /--> App 1
-------------------> --> -->
\--> Barracuda 2 -->/ \--> Host 2 -->/ \--> App 1
矢印が 1 つの要求に戻る場合、その要求はフローのいずれのポイントにも流れることができます。
HAProxy 構成の詳細
backend app_1
cookie ha_app_1 insert
server host1 10.0.0.101:80011 weight 1 maxconn 1024 cookie host_1 check
server host2 10.0.0.102:80011 weight 1 maxconn 1024 cookie host_2 check
上記の構成では:
cookie ha_app_1 insert
実際に使用される Cookie 名です
cookie host_1 check
またはcookie host_2 check
クッキー値を設定します