Webソケットの負荷を分散する方法について質問があります。
Webソケットをサポートするサーバーがあります。ブラウザが私のサイトに接続し、それぞれがwww.mydomain.com
へのウェブソケットを開きます。そうすれば、私のソーシャルネットワークアプリはクライアントにメッセージをプッシュできます。
従来は、HTTPリクエストのみを使用して、2台のWebサーバーの前に2台目のサーバーとロードバランサーを追加してスケールアップしていました。
Webソケットの場合、接続はロードバランサーではなくWebサーバーと直接接続する必要があります。マシンの物理的な制限が64kのオープンポートなどで、クライアントがロードバランサーに接続している場合、サポートできなかったためです64k以上の同時ユーザー。
どうすればいいですか-
ページがロードされたときに、クライアントが(ロードバランサーではなく)Webサーバーに直接接続するようにしますか?ノードからJavaScriptをロードするだけで、ページが最初にリクエストされるたびに、ロードバランサー(または何でも)がスクリプトのURLをランダムに変更しますか?
リップルスタートを処理しますか?ブラウザは、Webサーバーがシャットダウンすると接続が閉じられたことを認識します。 JavaScriptコードを記述して接続を再度開くことはできますが、ノードはしばらく消えます。だから私はロードバランサーに戻って使用する次のノードのアドレスを照会する必要があると思いますか?
ブラウザが最初にwww.mydomain.com
を要求し、www34.mydomain.com
にリダイレクトされるように、最初のリクエストでロードバランサーがリダイレクトを送信することについて疑問に思いました。ノードがダウンするまで、それは非常にうまく機能します-Facebookのようなサイトはそうしません。どうやってやっているの?
ソースIPポートハッシュに基づいてIPパケットをWebSocketサーバーファームに配布するL3ロードバランサーを配置します。 L3バランサーは状態を維持しないため(ハッシュされたソースIPポートを使用)、ローエンドハードウェア(たとえば10GbE)のワイヤ速度に合わせてスケーリングします。 (ハッシュされたソースIPポートを使用して)配布は決定的であるため、TCP(したがってWebSocket)で動作します。
また、64kのハード制限は、特定の(ソース)IPアドレスのoutgoingTCP/IPにのみ適用されることに注意してください。着信TCP/IPには適用されません。 Autobahn (高性能WebSocketサーバー)、2コア、4GB RAM VM。
また、最初のWebSocketハンドシェイク中に通知されたHTTPパスでL7ロードバランシングを実行できることに注意してください。その場合、ロードバランサーは状態(どのソースIPポートペアがどのバックエンドノードに行くか)を維持する必要があります。それにも関わらず、適切なセットアップで数百万の接続に拡張されるでしょう。
免責事項:私はアウトバーンの原著者であり、タベンドで働いています。
Websocketサーバーロジックがsocket.ioを使用してnodejsで実行される場合、socket.ioに同期のために共有redisキー/値ストアを使用するように指示できることに注意してください。この方法では、ロードバランサーを気にする必要さえありません。イベントはサーバーインスタンス間で伝播します。
var io = require('socket.io')(3000);
var redis = require('socket.io-redis');
io.adapter(redis({ Host: 'localhost', port: 6379 }));
参照: http://socket.io/docs/using-multiple-nodes/
しかし、ある時点でredisがボトルネックになる可能性があると思います...
検査と「ルーティング機能」を使用して、レイヤー7の負荷分散を実現することもできます。
「Stingray Traffic Managerを使用してWebSocketトラフィックを検査および負荷分散する方法、および必要に応じて、同じIPアドレスとポートで受信されるWebSocketおよびHTTPトラフィックを管理する方法」を参照してください。 https://splash.riverbed.com/docs/DOC-1451