Python 通过web应用程序处理作业:实时状态更新和后端消息传递

Python 通过web应用程序处理作业:实时状态更新和后端消息传递,python,web-applications,websocket,messaging,zeromq,Python,Web Applications,Websocket,Messaging,Zeromq,我想实现一个(开源)web应用程序,用户通过浏览器向Python web应用程序发送某种请求。请求数据用于定义和提交某种繁重的计算任务。计算作业外包给“工作后端”(也称为Python)。在作业处理过程中,作业会随着时间的推移经历不同的阶段(从中间状态的“提交”到理想的“完成”)。我想完成的是实时向用户显示当前作业状态。这意味着工作后端必须将作业状态传回web应用程序。然后,web应用程序必须将信息推送到用户的浏览器。我为您带来了一张图片,示意性地描述了基本思想: 红色圆圈中的数字表示事件的时间

我想实现一个(开源)web应用程序,用户通过浏览器向Python web应用程序发送某种请求。请求数据用于定义和提交某种繁重的计算任务。计算作业外包给“工作后端”(也称为Python)。在作业处理过程中,作业会随着时间的推移经历不同的阶段(从中间状态的“提交”到理想的“完成”)。我想完成的是实时向用户显示当前作业状态。这意味着工作后端必须将作业状态传回web应用程序。然后,web应用程序必须将信息推送到用户的浏览器。我为您带来了一张图片,示意性地描述了基本思想:

红色圆圈中的数字表示事件的时间顺序。“web应用”和“worker后端”仍在设计中。现在,如果您能帮助我做出一些技术决策,我将不胜感激

我的问题,特别是:

  • 我应该在web应用程序和worker后端之间应用哪种消息传递技术? 当worker后端发出关于某个作业的信号(某种消息)时,它必须触发web应用程序中的某个事件。因此,我需要某种回调,它与最初请求提交作业的客户机关联。我想我需要一些发布/订阅机制,在这里工作后端发布,web应用订阅。当web应用程序收到消息时,它会通过向客户端发送状态更新来对消息作出反应。我希望worker后端具有可扩展性,并且与web应用程序强解耦。因此,我考虑使用Redis或ZeroMQ来完成此任务。你怎么认为?我的整个方法有点太复杂了吗

  • 我应该使用哪种技术将信息推送到浏览器? 出于完美主义,我想要实时更新。我不想以高频率投票。我希望在工作后端发出消息时立即推送到客户端:-)。此外,我不需要最大限度的浏览器支持。这个项目首先或多或少是我自己的一个技术演示。我应该选择HTML5服务器发送的事件/WebSocket吗?或者你会提出其他建议吗


  • 非常感谢您提前提出的建议。

    既然您正在谈论python web应用程序,我建议您研究一下:

    我应该在web应用程序和worker后端之间应用哪种消息传递技术?

    -将作业分解为较小的任务,这些任务返回需要向客户显示的结果

    我应该使用哪种技术将信息推送到浏览器?

    在服务器端JS框架或

    如果您不太喜欢python,请查看


    基于,从服务器到web客户端实时更新进度的其他方法可能包括将进度状态写入redis数据库,或使用基于异步结果的方法(两者都基于),其中一个选项是使用WebSocket。如果你走这条路,你可能会去看看,其中包括Python(Twisted)的客户端和服务器,以及WebSocket之上的RPC+PubSub协议(带有Python、JavaScript和Android的libs)。使用RPC+PubSub订阅可以保护重要的工作,并且可能适合您的需要(作业提交=>RPC,作业工作更新=>PubSub)

    AutobahnPython在Twisted上运行,Twisted还可以充当WSGI容器,从而可以运行Flask(或其他基于WSGI的Web框架)。您可以在1个端口/服务器上运行所有操作。GitHub Autobahn存储库中有一个示例,用于后者

    免责声明:我是《高速公路》的原作者,为塔文多工作

    详细信息: 我假设你的员工做CPU密集型和/或阻塞型的工作

    首先,您的工作人员是纯Python还是外部程序

    如果是后者,您可以使用Twisted进程协议实例,这些实例通过stdio管道(以非阻塞方式)从主Twisted线程进行通信。如果是前者,则可以使用Twisted后台线程池和Twisted deferToThread(请参阅:)

    高速公路在主螺旋反应堆螺纹上运行。如果您的工作人员也这样做(请参见前面的注释),那么您可以直接调用WebSocket/WAMP工厂/协议实例上的方法。如果不是(工作线程在后台线程上运行),则应通过callFromThread调用这些方法


    如果您使用WAMP,主要的事情是为每个工作人员获取WampServerFactory的引用。然后,工作者可以通过调用适当的工厂方法将PubSub事件分派给所有订阅者。

    为了便于使用,您的web应用程序将拥有一个数据库。我将在该数据库中创建一个专门用于这些作业的表。每项工作都有一个“状态”

    这简化了您的系统,因为您只需发送启动作业的请求并将其移交给后端工作人员即可(对于此IMO,zmq是一个很好的解决方案)。因为您使用python作为后端,所以让您的辅助作业更新数据库中当前的工作作业或者让另一个“更新程序”更新数据库中的字段是非常简单的(保持逻辑独立将有助于获得更好的解决方案,如果您正在进行大量更新,则可以启动多个“更新程序”)

    然后对于你的前端,因为你不想轮询服务器,我会做一些类似的事情。你基本上做的是轮询服务器,但服务器在你感兴趣的数据发生变化之前不会真正“响应”。一旦发生变化,你就响应请求。在前端,你让你的JS重新生成在收到最新更新后立即恢复e连接。只要您