Python和Twisted中的消息队列代理
我想做一个轻量级的消息队列代理。它的工作是接收来自网页应用(PHP)的消息,然后异步地把这些消息发送到消息队列服务器。做这个代理的原因是,消息队列有时候并不总是可用,有时会延迟,甚至可能宕机,但我希望确保消息能够送达,同时网页应用能够立即返回结果。
所以,PHP会把消息发送到运行在同一主机上的消息队列代理。这个代理会把消息保存到SQLite数据库中,以防崩溃。同时,它会在连接可用时,将SQLite中的消息批量发送到消息队列,并从SQLite中删除这些消息。
根据我的理解,这个服务里有以下几个组件:
- 消息监听器(监听来自PHP的消息,并将它们写入一个“待处理队列”)
- 数据库刷新器(从“待处理队列”读取消息并保存到数据库中;因为SQLite是单线程的)
- 消息队列连接处理器(通过重新连接保持与消息队列服务器的连接)
- 消息发送器(从SQLite数据库中收集消息并发送到消息队列服务器,然后从数据库中删除这些消息)
我考虑用Twisted来实现第一个部分(TCPServer),但在将它与其他部分结合时遇到了问题,因为其他部分并不是基于事件驱动的。我的直觉告诉我,这些部分应该在不同的线程中运行,因为它们都是IO密集型的,并且彼此独立,但我也可以把它们放在一个线程里。尽管如此,我找不到任何好的、对我来说清晰的例子,来说明如何在Twisted的主循环之外实现这个工作线程。
我开始的例子是chatserver.py,它使用了service.Application和internet.TCPServer对象。如果我在创建TCPServer服务之前启动自己的线程,它会运行几次,但之后就停止了,再也不运行了。我不确定为什么会这样,但可能是因为我没有正确使用Twisted的线程。
你有什么建议可以实现一个独立的工作线程并保持Twisted吗?你有没有其他架构的想法?
3 个回答
在Twisted中使用单独的线程来解决阻塞调用的问题,可能不是最划算的选择,但有时候,最简单的解决办法就是最好的选择。这里有一个链接,可以教你如何在Twisted中使用线程:
http://twistedmatrix.com/documents/10.1.0/core/howto/threading.html
有时候,简单易行的解决方案比花几个小时甚至几天去研究复杂的东西要快得多,而这些研究可能最后都没用。
你基本上是在考虑为你的消息服务器写一个临时的扩展,这个扩展的工作就是提供你所要求的可靠性保证。
不过,也许你应该考虑把原本打算用来运行这个新代理的硬件,直接用来运行另一个消息队列节点。这个新节点可以负责保存和转发你发送给它的消息,特别是在其他节点忙不过来或者离线的时候。