2

我正在创建一个网站,允许玩家排队寻找类似技能的多人视频游戏玩家。简单的 Web 后端仅修改数据库并使用模板创建响应,但除此之外,我的后端还必须:

  • 在排队或玩游戏时与玩家实时交流(通过 gevent-socketio)
  • 在后台运行计算以找到平衡的游戏,随着等待时间的增加逐渐降低游戏质量(并在找到游戏时通过 SocketIO 通知玩家)
  • 通过 UDP 套接字监控正在进行的游戏(如果玩家断开连接,请向队列请求替代)并最终使用结果更新数据库

我知道我将如何单独做这些事情,但我想知道我应该如何分离这些组件并让它们通信。我想我的网络框架(Flask)根本不应该参与这些其他事情。

由于我已经必须使用 gevent,我目前正计划为这些任务中的每一个启动单独的 greenlet。这将适用于我的所有任务(计算可能除外),因为它们通常会等待某些事情发生。但是,这根本无法扩展,因为我无法运行更多 Flask 实例。一切都依赖于在一个线程中运行的greenlets。

那么这是最好的方法吗?是否有另一种方法来处理分离这些任务(尤其是我将来可能使用的没有协程的语言)?我听说过 RabbitMQ/ZeroMQ 和 Celery 等工具,但我不确定如何以及是否使用它们来解决这个问题。

4

1 回答 1

1

我的第一个想法是您可以使用面向服务的架构来分离这些任务。这些服务中的每一个都可以在单独的端口(或机器(或机器池))上运行 Flask 应用程序,并使用简单的 HTTP 相互通信。细分可能是这样的:

  • GameService:处理来自玩家的传入连接,并通过socketio与他们通信。
  • GameFinderService:接受来自 GameService 的 POST 请求,开始为玩家 X 寻找游戏。接受来自 GameService 的 GET 请求,为玩家 X 获取下一个最佳游戏。您可以将 Redis 用作每个已连接玩家的短暂游戏队列的后备存储,每次 GameStatusService(如下)通知我们更改时都会更新该队列。
  • GameStatusService:通过 UDP 监控进行中的游戏,当发生重大事件时,例如创建新游戏、玩家断开连接等,它会通知 GameFinderService 更改。然后 GameFinderService 将为每个连接的玩家适当地更新其队列。

Redis 非常好,因为它用作数据结构存储,允许您在没有太多开销的情况下维护短期和长期数据结构(例如队列)。

于 2012-12-08T06:21:26.563 回答