python - 当 Web 后端不仅仅是简单地回复请求时,我的应用程序应该如何构建?

标签 python architecture rabbitmq web-frameworks gevent

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

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

我知道我将如何单独完成这些事情,但我想知道我应该如何分离这些组件并让它们进行通信。我认为我的 Web 框架 (Flask) 根本不应该涉及这些其他事情。

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

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

最佳答案

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

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

Redis 非常好,因为它用作数据结构存储,允许您维护短期和长期数据结构(例如队列)而无需太多开销。

关于python - 当 Web 后端不仅仅是简单地回复请求时,我的应用程序应该如何构建?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13656736/

相关文章:

python csv到xlsx拆分文件excel

python - 如何打印关键字后的所有内容?例如打印单词 "Apple"和单词 "Pen"之间的所有内容

python - 如何在 IPython 中嵌入工作生成器表达式?

java - 如何在 PHP 和 Java 程序之间进行通信?

rabbitmq - 如何从 RabbitMQ 中删除队列绑定(bind)?

php - 如何制作用于RabbitMQ PHP任务消费的Docker容器

python - 调用 Google App Engine Cloud Endpoints 内的 Drive API

c - 测试缓存失效和刷新

api - API 是否应该将所有工作委托(delegate)给其他服务?

python - Django Celery 目录结构和布局