将Python Twisted与多进程结合?
我需要用Python写一个像代理一样的程序,这个程序的工作流程和网络代理很像。它会在客户端和服务器之间运行,拦截客户端发给服务器的请求,处理这些请求,然后再把它们发送到原来的服务器。当然,这里用的协议是一个私有协议,基于TCP。
为了减少工作量,我想用Python的Twisted库来处理请求的接收(这部分像服务器)和重新发送(这部分像客户端)。
为了提高性能,我想用Python的多进程(因为线程有GIL限制)把程序分成三个部分(进程)。第一个进程运行Twisted来接收请求,把请求放到一个队列里,并立即向原来的客户端返回成功的消息。第二个进程从队列中取出请求,进一步处理这些请求,然后把它们放到另一个队列里。第三个进程从第二个队列中取出请求,并把它们发送到原来的服务器。
我刚开始接触Python Twisted,我知道它是基于事件驱动的,我也听说最好不要把Twisted和线程或多进程混在一起。所以我不确定这种方法是否合适,或者有没有更优雅的方式只用Twisted来实现?
3 个回答
你可以试试“协作式多任务”这种技术,具体内容可以在这里找到:http://us.pycon.org/2010/conference/schedule/event/73/。这个方法和Glyph提到的技术很相似,值得一试。
你也可以尝试把ZeroMQ和Twisted一起用,不过现在这真的很难,而且还处于实验阶段哦 :)
Twisted有自己的一套事件驱动的方法来运行子进程,我觉得这比multiprocessing
模块要好。它的核心功能是spawnProcess,而像ampoule这样的工具则提供了更高级的封装。
如果你使用spawnProcess
,你就可以像处理Twisted中的其他事件一样处理子进程的输出;但如果你用multiprocessing
,你就得自己想办法通过队列把子进程的输出传回Twisted的主循环,因为普通的callFromThread
接口在另一个进程中是不能用的。根据你调用的方式,它要么会试图把反应器序列化,要么就会在子进程中使用一个不同的、无法工作的反应器;不管怎样,你的调用都会永远丢失。