私は現在、node.js ゲーム サーバー アプリケーションに取り組んでいますが、ここで少し壁にぶつかりました。私の問題は、ゲーム クライアントからの受信接続を受け入れるために socket.io を使用していることです。これらのクライアントは、ゲーム世界のいくつかのゾーンまたはエリアの 1 つに接続されている可能性があります。
基本的なアーキテクチャを以下に示します。マスター プロセスは、Zone Manager プロセスを実行するゲームのゾーンごとに子プロセスを fork します。ゾーン データ (3D モデル、プレイヤー/エンティティの位置など) を維持するための専用プロセス。次に、マスター プロセスは、作成するゾーン マネージャーごとに複数の「通信スレッド」をフォークします。これらのスレッドは、socket.io のインスタンスを作成し、そのゾーンのポートをリッスンします (1 つのポートでリッスンする複数のスレッド)。これらのスレッドは、独自のプロセスでゲーム ロジックの大部分を処理し、ゲーム サーバーを支えるデータベースと通信します。唯一の問題は、状況によっては、ゾーンやプレーヤーなどに関する情報を受け取るために、ゾーン マネージャーと通信する必要がある場合があることです。
例として: プレイヤーは、ゾーン内のノンプレイヤー キャラクター (NPC) と売買/取引したいと考えています。ゾーン通信スレッドは、取引を行う前に、プレイヤーが取引を行うのに十分なほど NPC に近いかどうかをゾーン マネージャー スレッドに問い合わせる必要があります。
ここで私が直面している問題は、node.js クラスター機能を利用し、プロセスのsend()
およびon()
メソッドを使用してメッセージの受け渡しを処理することを計画していたことです。私が遭遇した1つの警告を除いて、それは問題ありません。すべての子プロセスがcluster.fork()
「マスター」プロセスとのみ通信できます。node.js ルート プロセスは、すべての通信のボトルネックになります。クラスターのプロセス間通信 (IPC) を使用して文字通りメッセージを前後にバウンスし、実行されている 1 秒あたりのリレー数を追跡するスクリプトを使用して、システムでいくつかのベンチマークを実行しました。最終的に、ノードが中継できる IPC の数に関して、ノードは毎秒約 20k で上限に達するようです。この数値は、Phenom II 1.8 GHz クアッド コア ラップトップと FX-8350 4.0 GHz 8 コア デスクトップの両方で一貫していました。
これはかなり高いように聞こえますが、これは基本的に、ゾーンまたは通信スレッドの数に関係なく、すべての IPC が、アプリケーション全体の「リレー」として機能する単一のプロセスによって依然としてボトルネックになっていることを意味します。つまり、個々のスレッドは 1 秒あたり 20,000 を超える IPC を中継できるように見えますが、すべての通信が 1 つのスレッドを通過するため、アプリケーション全体が非常識な 32 コア システム上にあったとしても、それ以上中継することはありません。
それが私が抱えている問題です。今ジレンマ。私はそこにある他のさまざまなオプションについて多くのことを読んでおり、このトピックに関するスタックに関する 20 の異なる質問を読んでおり、いくつかのことが定期的にポップアップしているのを見てきました。
Redis : 現在、サーバーで Redis を実際に実行しており、それを socket.io データストアとして使用しているため、複数のスレッドの socket.io が接続データを共有できるため、ユーザーは N 個の socket.io のいずれかに接続できます。サーバーが着信接続を自動的に負荷分散できるように、ゾーンのスレッド。
これに関する私の懸念は、ネットワーク スタックを介して実行されることです。同じサーバー上の複数のプロセス間の通信には理想的ではありません。長期的にはレイテンシが大きな問題になると思います。
0MQ (zeromq/zmq) : これまで何にも使用したことがありませんでしたが、最近少し耳にするようになりました。私が行った読書に基づいて、TCPソケットでそれを使用している人々の多くの例を見つけましたが、IPCに使用している人についての話題はあまりありません. おそらく、ここの誰かが以前に IPC の 0MQ で作業したことがあり (おそらく node.js でも?)、このオプションに光を当ててくれることを期待していました。
dnode : 繰り返しますが、私はこれを使用したことはありませんが、私が見たところ、ネットワークスタックが再び邪魔になることを意味する TCP で動作するように設計された別のオプションのようです。
node-udpcomm : 誰かがここの別の質問でこれをリンクしました (残念ながらもう一度見つけることができないようです)。聞いたこともありませんが、UDP 接続を開いてリッスンする非常に小さなソリューションのように見えます。これはおそらく TCP オプションよりも高速ですが、まだネットワーク スタックが適切に処理されているのでしょうか? 私は間違いなく、ここにある「プログラマー ゾーン」から 1 マイルほど離れており、ネットワークやコンピューター アーキテクチャーの領域に入り込んでいて、あまり詳しくありません (笑)
とにかく、肝心なのは、私はここで完全に立ち往生しており、このシナリオでの IPC の最適なオプションが何であるかわからないということです。現時点では、0MQ が上にリストしたものの中で最良のオプションであると想定しています。通信プロトコルの「IPC」オプションを提供しているように見えるのは 0MQ だけだからです。ネットワーク スタックを通過していませんが、確認できません。
ここにいる何人かの人々が、私を正しい方向に向けるのに十分な知識を持っているか、私がすでにそこに向かっていると言ってくれることを望んでいる. 私が取り組んでいるプロジェクトは、Three.js を使用して 3D グラフィックス/計算を強化するマルチプレイヤー ゲーム クライアントで「箱から出して」動作するように設計されたマルチプレイヤー ゲーム サーバーです。クライアントとサーバーは、すべてが満足のいくように機能するようになったら、すべての人にオープンソースになります。アーキテクチャが可能な限りスケーラブルであることを確認して、人々がこれでゲームを構築してからスケールすることがないようにしたいと考えています。壁にぶち当たります。
とにかく、実際にこれをすべて読んでくれてありがとう:)