0

アプリケーションサーバーがあります。大まかに言うと、このアプリケーション サーバーにはユーザーグループがあります。ユーザーは 1 つ以上のグループの一部であり、サーバーはすべてのユーザーに自分のグループとグループ内の他のユーザーの状態を認識させます。主な機能は次の 3 つです。

  • ユーザーとそのグループに関連するメタデータの更新とブロードキャスト。たとえば、ユーザーがログインすると、サーバーはこのユーザーのステータスを更新し、このユーザーのグループ内のすべてのオンライン ユーザーにブロードキャストします。
  • 2 人以上のユーザー間でプロキシとして機能する。クライアントはピアツーピア転送を利用しますが、2 人のユーザーが互いに直接接続できない場合、サーバーはそれらの間のプロキシとして機能します。
  • オフライン ユーザーのデータを保存します。クライアントがオンラインでないユーザーにデータを送信する必要がある場合、サーバーはそのデータを一定期間保存し、次にユーザーがオンラインになったときに送信します。

このアプリケーションを変更して、すべてが同じローカル ネットワーク上にあるとは限らず、複数のサーバーに分散できるようにしようとしています。ただし、古いクライアントとの下位互換性が失われないようにする必要があります。基本的に、配布はクライアントに対して透過的である必要があります。

私が抱えている最大の問題は、Server Aに接続しているユーザーがServer Bのユーザーにブロードキャストする必要がある更新を行う場合の処理​​です。

さらに大きな問題は、サーバー Aのユーザーがサーバーをサーバー Bのユーザーとの間のプロキシとして機能させる必要がある場合です。

私の最初のアイデアは、どのユーザーと通信する必要があるかを考慮に入れるアルゴリズムを使用して、各ユーザーに優先サーバーを割り当てようとすることでした。これにより、他のサーバー上のユーザーと通信する必要があるユーザーの数を減らすことができます。

ただし、これは異なるサーバー上のユーザーが通信する必要がある頻度を最小限に抑えるだけです。異なるサーバー上のユーザー間の通信を実現するという問題がまだあります。

これに対して私が思いつく唯一の解決策は、別のサーバーに接続しているユーザーに対処する必要があるときに、サーバーを相互に接続することです。

たとえば、サーバー A に接続していて、サーバー Bに接続している別のユーザーとのプロキシが必要な場合、サーバー Aにこのユーザーへのプロキシ接続を要求します。サーバー Aは、他のユーザーがサーバー Bに接続していることを認識し、サーバー B への「リレー」接続を確立します。この接続は、私の要求をサーバー Bに転送し、応答を私に転送するだけです。

これに伴う問題は、すでに非常に高い帯域幅の使用量が増加することです。残念ながら、他の解決策は見当たりません。

この問題に対するよく知られた、またはより良い解決策はありますか? 分散システムが異なるサーバー上のユーザー間の通信を必要とすることはあまり一般的ではないようです。

4

1 に答える 1

1

既存のサーバーをどの程度柔軟に変更できるかわかりません。私がずっと前にこれを行った方法は、すべてのサーバーが互いに TCP 接続を開いたままにすることでした。私は UDP ブロードキャストを使用して、他のサーバーにお互いのことを伝え、それらが新しいサーバーに接続し、ブロードキャストの送信を停止したサーバーを削除できるようにしました。

次に、ユーザーがサーバーに接続するたびに、そのサーバーは接続先のすべてのサーバーに TCP メッセージをユニキャストし、すべてのサーバーはユーザーのリストとユーザーがいるサーバーを保持します。

次に、あるユーザーから別のサーバー上の別のユーザーにメッセージを受け取った場合、それを他のサーバーに中継する必要があることをお勧めします。これがうまく機能するには、サーバーが同じLAN上にある必要があります。

サーバー間通信をスレッドで実行し、同じサーバー上にいるユーザーを実際にシミュレートできます。

ただし、ユーザーリストを維持してメッセージを送信すると、競合状態が発生しやすくなります (あるサーバーから別のサーバーにメッセージを中継しているときにユーザーが脱落するなど)。

サーバー コードの保守は悪夢であり、これはスケーラブルなサーバーを実装するための最も効率的な方法ではありません。しかし、レガシ サーバー コード ベースを使用する必要がある場合、選択肢はそれほど多くありません。

Erlang のようなリモート プロセスとノードをサポートする言語の使用を検討できる場合。

別の方法としては、RabbitMQ や ActiveMQ などのメッセージ キュー システムを使用し、それを介してサーバーが相互に通信するようにすることもできます。これらのシステムはスケーラブルになるように設計されており、通常はパブリッシュ/サブスクライブ メカニズムで動作します。

于 2011-04-12T09:17:41.313 に答える