web-dev-qa-db-ja.com

TCPロードバランサーを使用したWebSocketのプロキシセッションなしのプロキシ

Amazon Elastic Load Balancerを使用して、複数のnode.jsサーバーへのWebSocket接続をプロキシしたいのですが。 Amazon ELBは実際のWebSocketサポートを提供していないので、そのVanilla TCPメッセージングを使用する必要があります。しかし、これはある種のスティッキーセッション機能なしでどのように機能するかを理解しようとしています。

WebSocketが最初にクライアントからHTTPアップグレードリクエストを送信することで機能することを理解しています。これは、サーバーによって処理され、キー認証を正しく処理する応答を送信することによって処理されます。サーバーがその応答を送信し、それがクライアントによって承認された後、そのクライアントとサーバーの間には双方向接続があります。

ただし、クライアントがサーバーの応答を承認した後、サーバーにデータを送信するとします。データをロードバランサーに送信し、ロードバランサーが元のWebSocketアップグレードリクエストを処理しなかった別のサーバーにそのデータを中継する場合、この新しいサーバーはどのようにしてWebSocket接続を認識しますか?または、クライアントは自動的にロードバランサーをバイパスし、初期アップグレードを処理したサーバーに直接データを送信しますか?

34
Justin Meltzer

この質問に答えるために理解する必要があるのは、基になるTCP接続がWebSocket作成プロセス全体でどのように正確に進化するかです。 WebSocket接続のsticky部分が、基盤となるTCP接続自体であることがわかります。 WebSocketのコンテキストでの「セッション」の意味がわかりません。

高レベルでは、「WebSocket接続」を開始するには、クライアントがHTTP GETリクエストをHTTPサーバーに送信する必要がありますが、リクエストにはUpgradeヘッダーフィールドが含まれています。ここで、この要求が発生するためには、クライアントがHTTPサーバーへのTCP接続を確立している必要があります(これは明白かもしれませんが、ここでは明示的に指摘することが重要だと思います)。その後のHTTPサーバー応答は、sameTCP接続を介して送信されます。

サーバーの応答が送信された後、クライアントまたはサーバーのいずれかによってアクティブに閉じられない場合でも、TCP接続はまだ開いている/アクティブであることに注意してください。

さて、RFC 6455、WebSocket標準に従って セクション4.1 の最後に:

上記のようにサーバーの応答が検証されると、
は次のように述べていますWebSocket接続が確立されましたであり、
WebSocket接続はOPEN状態です

ここから、最初のHTTP GET(アップグレード)リクエストを送信する前にクライアントによって開始されたのと同じTCP接続が開いたままになり、今後はフルのトランスポート層として機能することを読みました二重WebSocket接続。そして、これは理にかなっています!

あなたの質問に関して、これはロードバランサーが役割を果たすだけであることを意味しますbefore最初のHTTP GET(アップグレード)リクエストが行われます、つまりbefore唯一のTCP上記のWebSocket接続の作成に含まれる接続は、2つの通信エンドポイント間で確立されます。その後、TCP接続は確立されたままになり、その間のネットワークデバイスによって「リダイレクト」されることはありません。

セッションの用語ではthe TCP connection is the sessionと結論付けることができます。 WebSocket接続が有効である(つまり、終了していない)限り、それは定義によりが提供し、独自のセッションで有効になります。このセッションを変更することはできません。ただし、この図で言えば、2つの独立したWebSocket接続は同じセッションを共有できません。

「セッション」で他のことを言及した場合、それはおそらくアプリケーション層によって導入されたセッションであり、そのセッションについてコメントすることはできません。

コメントに関して編集:

つまり、ロードバランサはTCP接続に関与していないと言っています

いいえ、少なくとも一般的にはそうではありません。 TCP接続の確立に影響を与える可能性があるのは、クライアント接続の試行で何を行うかを決定できるという意味です。詳細は、ロードバランサーの正確なタイプによって異なります(*、以下を参照)。重要:2つのエンドポイント間で接続が確立された後-私はロードバランサーをエンドポイントとは見なしませんが、WebSocketクライアントとWebSocketサーバーを参照します-2つのエンドポイントは、WebSocket接続の存続期間中は変更されません。ロードバランサー*はまだネットワークパスに存在する可能性がありますが、これ以上影響を及ぼさないと見なすことができます。

したがって、全二重接続はクライアントとエンドサーバー間のものですか?

はい!

***ロードバランシングにはさまざまなタイプがあります。タイプに応じて、ロードバランサの役割は、2つのエンドポイント間の接続確立後は異なります。例:

  • ロードバランシングがDNSベースで発生する場合、ロードバランサーは最終的なTCP接続にまったく関与していません。ホストが接続しているクライアントに直接通知するだけです。
  • ロードバランサーがAWSのレイヤー4 ELB(docs here )のように機能する場合、つまりTCP接続をプロキシします。したがって、クライアントは実際にはELB自体をサーバーとして認識します。ただし、ELBはパッケージを変更せずに両方向に転送するだけです。したがって、それは透過的にTCP接続に深く関わっています。この場合、実際には2つの永続的なTCP接続が含まれます。1つはユーザーからELBへの接続、もう1つはELBからサーバーへの接続です。これらは、WebSocket接続の存続期間中、永続的です。

WebSocketは永続的なTCP接続を使用するため、そのTCP接続のすべてのIPパケットを同じバックエンドサーバーに転送する必要があります(= TCP接続)。

粘着性がある必要があります。これは、HTTPリクエストごとにディスパッチできるL7 HTTP LBとは異なります。

LBは、さまざまなアプローチ、つまり.

  • ソースIP /ポートを一連のアクティブなバックエンドサーバーにハッシュする
  • TCP接続の確立時に、バックエンドサーバーを選択し、
6
oberstet