【问题标题】:Python "Task Server"Python“任务服务器”
【发布时间】:2009-04-30 02:19:43
【问题描述】:

我的问题是:我应该使用哪个 python 框架来构建我的服务器?

注意事项:

  • 此服务器与其客户端进行 HTTP 通信:GET 和 POST(通过 pyAMF)
  • 客户端“提交”“任务”进行处理,然后在稍后检索关联的“task_result”
  • 提交和检索可能以天分隔 - 不同的 HTTP 连接
  • “任务”是描述要解决的问题的 XML 块,“task_result”是描述答案的 XML 块。
  • 当服务器获得“任务”时,它会将其排队等待处理
  • 服务器管理此队列,并在任务到达顶部时组织它们被处理。
  • 处理由一个长时间运行(15 分钟?)的外部程序(通过子进程)执行,该程序提供任务 XML 并产生一个“task_result”的 XML 块,服务器将提取并存储(供以后客户端检索) )。
  • 它提供几个基本的 HTML 页面,显示队列和处理状态(仅用于管理目的)

我已经尝试过 twisted.web,使用 SQLite 作为数据库和线程来处理长时间运行的进程。

但我不禁觉得我错过了一个更简单的解决方案。我是吗?如果您面临这种情况,您会使用哪种技术组合?

【问题讨论】:

    标签: python


    【解决方案1】:

    我建议使用现有的消息队列。有很多可供选择(见下文),它们的复杂性和稳健性各不相同。

    另外,避免线程:让您的处理任务在不同的进程中运行(为什么它们必须在网络服务器中运行?)

    通过使用现有的消息队列,您只需要担心生成消息(在您的网络服务器中)和使用它们(在您的长时间运行的任务中)。随着系统的增长,您只需添加网络服务器和消费者就可以扩大规模,而不必担心您的排队基础设施。

    消息队列的一些流行的python实现:

    【讨论】:

    • 您确实在寻找消息队列。我在 beanstalkd 上运气不错,我听说过 rabbitmq.comzeromq.org 的好消息,而且总是有 gearman:danga.com/gearman。听起来您对长时间运行的任务比高频调用更感兴趣,所以可能几乎任何队列都适合您。
    【解决方案2】:

    我建议以下。 (因为这是我们正在做的事情。)

    一个简单的 WSGI 服务器(wsgirefwerkzeug)。进来的 HTTP 请求自然会形成一个队列。无需进一步排队。您收到一个请求,将子进程作为子进程生成并等待它完成。一个简单的孩子名单就是你所需要的。

    我对@9​​87654324@ 中的“永久服务”主循环进行了修改,以定期轮询所有孩子,看看他们的表现如何。

    一个简单的 SQLite 数据库可以跟踪请求状态。即使这样也可能是多余的,因为您的 XML 输入和结果可能只是放在文件系统中。

    就是这样。队列和线程并没有真正进入它。单个长期运行的外部进程过于复杂而无法协调。如果每个请求都是一个单独的、独立的子进程,这是最简单的。

    如果您收到大量请求,您可能需要一个简单的调控器来防止创建数千个子节点。调控器可以是一个简单的队列,使用带有 append() 和 pop() 的列表构建。每个请求都会进入,但只有符合“最大子节点数”限制的请求才会被取出。

    【讨论】:

    • “单个长时间运行的外部进程太复杂而无法协调”?配合什么?实际上,拥有外部工作人员的想法是防止任何需要协调并能够轻松控制并行性。正如您所指出的,当您期望请求爆发时,生成进程确实是一个问题,然后您确实需要更多的协调。我通常在几台机器上设置几个worker,并使用supervisord(supervisord.org)监督他们
    • 您如何在这个长期运行的过程中完成工作?将工作作为子流程进行分叉似乎更简单,而不是通过另一个 IPC 练习来与这些外部工作人员进行协调。
    • 您使用队列框架为您管理这些技术细节(请参阅我的回答)。我同意子流程方法更简单,需要担心的基础设施更少,并且非常适合某些应用程序。但是对于我在生产中运行的任何东西,我更喜欢对并行性提供更多控制的东西,并且设置固定数量的外部工作人员正是这样做的。
    【解决方案3】:

    我的反应是推荐 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 提供了一种相当灵活的方式来启动外部帮助程序并与之交互。此外,如果您突然决定要cloudify您的应用程序,使用ProcessProtocol 来简单地在远程服务器上运行您的批量处理(也许是随机 EC2 实例)并不是什么大不了的事) 通过ssh,假设您已经设置了密钥。

    【讨论】:

    【解决方案4】:

    你可以看看芹菜

    【讨论】:

      【解决方案5】:

      似乎任何 python web 框架都可以满足您的需求。我每天都使用类似的系统,我可以告诉你,你的线程和 SQLite 用于队列存储的解决方案与你将得到的一样简单。

      假设队列中的顺序无关紧要,那么线程应该是可以接受的。确保您不会在队列中创建竞争条件,或者例如同时运行两个相同的作业类型,这一点很重要。如果是这种情况,我建议使用单线程应用程序来逐个处理队列中的项目。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-09-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-08-25
        • 2018-04-04
        • 1970-01-01
        相关资源
        最近更新 更多