2

マルチプレイヤー ビデオ ゲームで同様のスキルを持つプレイヤーをキューに登録できる Web サイトを作成しています。単純な Web バックエンドは、データベースを変更し、テンプレートを使用して応答を作成するだけですが、それに加えて、私のバックエンドは次のことを行う必要があります。

  • プレイヤーがキューまたはプレイ中にリアルタイムで (gevent-socketio を介して) 通信する
  • バックグラウンドで計算を実行してバランスの取れたゲームを見つけ、待機時間が長くなるにつれてゲームの品質を徐々に低下させます (ゲームが見つかったときに SocketIO を介してプレイヤーに通知します)
  • UDP ソケットを介して進行中のゲームを監視し (プレイヤーが切断した場合は、キューに代わりのプレイヤーを要求します)、最終的に結果でデータベースを更新します

これらのことを個別に行う方法はわかっていますが、これらのコンポーネントをどのように分離して通信できるようにするべきか疑問に思っています。私のWebフレームワーク(Flask)は、これらの他のことにあまり関与すべきではないと思います。

すでに gevent を使用する必要があるため、現在、これらのタスクごとに個別の greenlet を開始することを計画しています。これは、通常、何かが起こるのを待っているため、すべてのタスクで機能します (計算は例外となる可能性があります)。ただし、これ以上 Flask インスタンスを実行できないため、これはまったくスケーリングしません。すべては、単一のスレッドで実行される greenlet に依存します。

これが最善の方法ですか?これらのタスクを分離する別の方法はありますか (特に、コルーチンを持たない将来使用する可能性のある言語の場合)。RabbitMQ/ZeroMQ や Celery などのツールについて聞いたことがありますが、この問題を解決するためにそれらをどのように使用するか、どのように使用するかはわかりませんでした。

4

1 に答える 1

1

私が最初に考えたのは、サービス指向アーキテクチャを使用してこれらのタスクを分離できるということです。これらの各サービスは、別のポート (またはマシン (またはマシンのプール)) で Flask アプリを実行し、単純な HTTP を使用して相互に通信できます。内訳は次のようになります。

  • GameService: プレイヤーからの着信接続を処理し、socketio を介してプレイヤーと通信します。
  • GameFinderService: GameService からの POST 要求を受け入れて、プレーヤー X のゲームの検索を開始します。GameService からの GET 要求を受け入れて、playerX の次に最適なゲームを取得します。GameStatusService (以下) が変更を通知するたびに更新される、接続されたプレーヤーごとのこの短期間のゲームのキューのバッキング ストアとして Redis を使用できます。
  • GameStatusService: UDP を介して進行中のゲームを監視し、注目すべきイベント (新しいゲームの作成、プレイヤーの切断など) が発生すると、変更を GameFinderService に通知します。その後、GameFinderService は、接続されている各プレイヤーのキューを適切に更新します。

Redis は、キューなどの短期間および長期間の両方のデータ構造をオーバーヘッドなしで維持できるデータ構造ストアとして機能するため、非常に優れています。

于 2012-12-08T06:21:26.563 に答える