Python "任务服务器
我的问题是:我应该用哪个Python框架来搭建我的服务器?
注意事项:
- 这个服务器和客户端之间通过HTTP进行交流:使用GET和POST(通过pyAMF)
- 客户端会“提交”一些“任务”进行处理,然后过一段时间再获取相关的“任务结果”
- 提交和获取之间可能相隔几天——这会用到不同的HTTP连接
- “任务”是一个XML文件,描述了需要解决的问题,而“任务结果”也是一个XML文件,描述了答案。
- 当服务器收到一个“任务”时,它会把这个任务放到一个队列里等待处理
- 服务器管理这个队列,当任务到达队列的顶部时,会安排处理这些任务。
- 处理任务的是一个长时间运行的外部程序(大约15分钟?),它通过子进程来执行,接收任务的XML,并生成一个“任务结果”的XML,服务器会把这个结果拿到并存储起来(以便客户端后续获取)。
- 服务器还提供几个基本的HTML页面,用于显示队列和处理状态(仅供管理员使用)
我尝试过使用twisted.web,数据库用的是SQLite,并且用线程来处理长时间运行的进程。
但我总觉得我可能错过了更简单的解决方案。是这样吗?如果你面临这个问题,你会选择什么技术组合呢?
5 个回答
我建议你这样做。(因为我们就是这么做的。)
可以使用一个简单的WSGI服务器,比如wsgiref或者werkzeug。当HTTP请求进来的时候,它们自然会排成一队。你不需要再额外排队。你收到一个请求,就启动一个子进程来处理它,然后等这个子进程完成。其实只需要一个简单的子进程列表就够了。
我对
一个简单的SQLite数据库可以用来跟踪请求的状态。其实这可能有点多余,因为你的XML输入和结果也可以直接保存在文件系统里。
就这样。排队和线程其实并不需要。一个长时间运行的外部进程太复杂了,协调起来麻烦。最简单的方式是每个请求都用一个独立的子进程来处理。
如果你收到大量请求,可能需要一个简单的管理器来防止创建成千上万的子进程。这个管理器可以是一个简单的队列,用列表的append()和pop()方法来实现。每个请求都会进入队列,但只有符合“最大子进程数量”限制的请求才能被处理。
我建议使用Twisted,但你已经看过这个了。不过,我还是坚持我的看法。虽然我不知道你具体遇到的困难,但我可以分享一些让我在处理多个依赖、阻塞操作时,减少麻烦的经验。
内联回调(在这里有简单的文档说明:http://twistedmatrix.com/documents/8.2.0/api/twisted.internet.defer.html)可以让你写的代码看起来更简洁,像是一条直线的代码,而不是复杂的回调链。这方面有个很好的例子可以参考:http://blog.mekk.waw.pl/archives/14-Twisted-inlineCallbacks-and-deferredGenerator.html
你不一定要让大规模处理和Twisted完美结合。有时候,把程序的一大部分拆分成一个独立的、容易测试和调整的命令行工具,然后让Twisted在另一个进程中调用这个工具,会更简单。Twisted的ProcessProtocol
提供了一种灵活的方式来启动和与外部辅助程序互动。此外,如果你突然想要把应用程序“云化”,使用ProcessProtocol
在远程服务器上(比如随机的EC2实例)通过ssh
运行你的大规模处理也不是很难,只要你已经设置好密钥。
我建议你使用现成的消息队列。市面上有很多种选择(见下文),它们在复杂性和稳定性上各有不同。
另外,尽量避免使用线程:让你的处理任务在不同的进程中运行(为什么非得在web服务器里运行呢?)
通过使用现成的消息队列,你只需要关注在你的web服务器上生成消息,以及在长时间运行的任务中消费这些消息。随着系统的扩展,你只需增加web服务器和消费者,就能轻松扩展,而不用太担心你的队列基础设施。
一些流行的Python消息队列实现: