web-dev-qa-db-ja.com

Node.jsマルチサーバークラスタリング

私はサーバーを含むNode.jsを使用したプロジェクトに取り組んでいます(簡単にするために、このサーバーを特定のクライアントから他のクライアントにメッセージを転送する必要があるチャットサーバーとして想像してみましょう)。このサーバーは常に到達可能であるというQoSの理由で必要なので、クラスタリングを使用して異なるサーバー(異なる物理マシン)間で負荷のバランスを分割し、サーバーがダウンした場合に別のサーバーが要求を処理できるようにすることを考えました。

私の質問は、この種の分散型アプローチはNode.jsで可能ですか?

「クラスター」モジュールについてはすでに読みましたが、私が理解したところによると、同じマシン上のマルチプロセッサーでのみ拡張できるようです。

19
MastErAldo

はい、可能です。

これはNodeJSのプロパティではなく、アプリケーション用に設計したアーキテクチャであり、それを実行できるかどうかを決定します。

主な問題は常にインスタンス間で状態を共有することです。たとえば、4つのチャットサーバーABCDがあり、4つのサーバーに接続を分散するLoadBalancer Lがあり、Aがダウンしたときに、すべてのAの接続をに再接続するとします。残りのインスタンスでは、チャットルームの状態がBCとDで同じであることをどのように確認しますか?

1つの方法は、アプリケーションコードを完全にステートレスにし、すべてのデータをmongoDbやRedisなどの分散インメモリデータベースにプッシュすることです。データベースインスタンスの1つがダウンした場合に備えて、データベースを分散させる必要があります。

最後の問題はLoadBalancerです。それがダウンすると、システム全体がダウンします。

したがって、長い話を短くするために。はい、できますが、潜在的な障害点がどこにあるかについて、いくつかの難しい決定を下す必要があります。単一障害点が必要ない場合は、複雑で費用のかかるセットアップが必要になります。

29
ExxKA

私の推奨事項は、独立したクラスターを活用して状態を共有することです。つまり、サーバーが相互に通信せず、代わりに共通のRedisインスタンス/クラスターを共有し、共通のMongoDBクラスターを共有するAPIクラスターを用意します。これにより、セッションや変数を共有でき、Redisのpub/sub機能を活用して、APIクラスター内でのうわさ話を回避できます。

特にチャットの場合、クライアントとしてSocket.IOを使用してRedisを使用すると、ロビーメンバーが複数のサーバーに存在していても、ロビーにブロードキャストするたびに、そのメッセージをそのロビーにブロードキャストするためにRedisがバックグラウンドで使用されます。さらに、これにより、任意のサーバーがソケットの再接続を管理できるため、別のレベルのフォールトトレランスが作成されます。Socket.ioは、接続が切断された場合、Redisを介して状態を維持しながら、APIクラスターに自動的に再接続します。

5
user2552012