在Twisted和Django之间共享数据库

9 投票
2 回答
2480 浏览
提问于 2025-04-16 12:07

我正在开发一个多人游戏服务器,使用Django来处理网页部分(比如HTML前端、用户登录、可玩的游戏、排行榜等等),而用Twisted来管理玩家之间的连接和游戏的交互。游戏服务器、网页服务器和数据库可能会运行在不同的机器上。

我想知道,怎么设计这个共享数据库才是“最佳”方案,以便将来可以对数据库的结构进行修改。我是否应该尝试把Django的ORM(对象关系映射)整合进Twisted框架,并使用延迟操作(deferreds)来避免阻塞?还是说我得创建和维护两个不同的数据库结构,一个在Django的模型里,另一个用twisted.enterprise.row来处理?

另外,关于用户登录,我是应该使用Twisted自带的用户认证功能,还是尝试把Django的模块引入到游戏服务器中来处理游戏端的用户认证呢?

2 个回答

2

我建议你不要使用Django的ORM(对象关系映射),它并没有想象中那么好,而且在Django以外的环境中使用起来会很麻烦(比如为了让Django支持多个数据库,做了很多工作)。使用Twisted进行数据库访问总是需要线程(即使是用twisted.adbapi),而线程可以让你使用任何你想要的ORM。SQLalchemy是个不错的选择。

10

首先,你需要弄清楚为什么要同时使用Django和Twisted。假设你对Twisted已经很熟悉,使用twisted.web和身份验证就足够了,这样你就可以在前端和后端应用中重复使用你的数据库层。

另外,你也可以反过来想,Twisted作为游戏服务器有什么优势?你是希望支持更多玩家(更多同时连接)还是其他什么?要考虑的是,如果你在Twisted中使用线程来进行阻塞的数据库访问,那么你很可能无法有效或可靠地支持数百个同时线程。记住,Python有一个全局解释器锁,所以线程不一定是扩展的最佳方式。

你还应该考虑为什么要使用SQL数据库和ORM。你的游戏数据是否真的适合存储在关系型数据库中?也许可以考虑使用MongoDB或其他键值存储或对象数据库来保存游戏状态。这些NoSQL存储中有很多都有适用于Django的阻塞驱动和适用于Twisted的非阻塞驱动(例如txmongo)。

不过,如果你坚持要同时使用Django和Twisted,有一些方法可以将阻塞的数据库访问嵌入到非阻塞的Twisted服务器中。

  1. adbapi(使用Twisted线程池)
  2. 直接使用Twisted线程池,通过reactor.deferToThread
  3. Storm ORM有一个分支支持Twisted(它内部处理deferToThread调用)
  4. SAsync是一个尝试让SQLAlchemy以异步方式工作的库
  5. 通过RPC让Twisted与管理阻塞数据库的进程进行交互

所以,你应该能够通过在Twisted中导入Django ORM对象,并小心地调用reactor.deferToThread来管理这些对象。在Twisted中使用这些对象时可能会遇到很多问题,因为某些ORM对象在访问或设置属性时会发出SQL请求等。

我知道这可能不是你期待的答案,但如果能提供更多关于你希望实现的目标以及为什么选择这些特定技术的细节,大家可能会给你更好的建议。

撰写回答