【问题标题】:Flask long routines烧瓶长例程
【发布时间】:2012-09-01 07:28:30
【问题描述】:

我必须在我的 Flask 应用程序中做一些长时间的工作。我想异步进行。刚开始工作,然后从 javascript 检查状态。

我正在尝试做类似的事情:

@app.route('/sync')
def sync():
    p = Process(target=routine, args=('abc',))
    p.start()

    return "Working..."

但这会造成已不复存在的 gunicorn 工人。

如何解决?我应该使用像 Celery 这样的东西吗?

【问题讨论】:

    标签: python flask gunicorn long-running-processes


    【解决方案1】:

    有很多选择。您可以开发自己的解决方案,使用 Celery 或 Twisted(我敢肯定还有更多现成的选项,但这些是最常见的选项)。

    开发您的内部解决方案并不困难。可以使用 Python 标准库的multiprocessing 模块:

    • 当任务到达时,您在数据库中插入一行,其中包含任务 ID 和状态。
    • 然后启动一个进程来执行在完成时更新行状态的工作。
    • 你可以有一个视图来检查任务是否完成,实际上只是检查相应的状态。

    当然,您必须考虑要将计算结果存储在哪里以及错误会发生什么。

    搭配 Celery 也很简单。它看起来如下所示。 定义一个异步执行的函数:

    @celery.task
    def mytask(data):
    
        ... do a lot of work ...
    

    然后,不要像mytask(data) 那样直接调用任务,它会立即执行它,而是使用delay 方法:

    result = mytask.delay(mydata)
    

    最后,您可以使用ready检查结果是否可用:

    result.ready()
    

    但是,请记住,要使用 Celery,您必须运行外部 worker 进程。

    我从未看过 Twisted,所以我无法告诉你它是否比这更复杂(但也可以做你想做的事)。

    无论如何,这些解决方案中的任何一个都可以在 Flask 上正常工作。要检查结果,如果您使用 Javascript,则 根本 无关紧要。只需让检查状态的视图返回 JSON(您可以使用 Flask 的jsonify)。

    【讨论】:

    • 嗯,我真的有你所说的关于将结果存储在数据库中的一切。实施我自己的解决方案的主要问题是,当我使用 multiprocessing 时,它会导致 gunicorn 工作人员失效。
    • 糟糕,很抱歉我误读了您的问题。看起来您的问题是您的父进程在 return 语句之后终止,这有效地杀死了您刚刚创建的子进程。为避免这种情况,您只需在父级退出(即分离它)之前守护子级python-daemon
    • 我得到ValueError: I/O operation on closed file 与多处理一起使用时。看起来我需要使用 Popen。设置Process().daemon = True 也无济于事。
    • 是的,按documentationp.daemon = True是不够的。如果您在 *nix 平台上,我会使用 python-daemon 或使用此 snipped 直接调用 fork,而不是 multiprocessingPopen。如果你在 Windows 中,你必须创建一个 service 而不是一个守护进程。无论如何,最便携的解决方案是使用 Celery 或 Twisted。
    【解决方案2】:

    我会使用消息代理,例如rabbitmq 或activemq。烧瓶进程会将作业添加到消息队列中,而长时间运行的工作进程(或池或工作进程)将从队列中取出作业以完成它们。工作进程可以更新数据库以允许烧瓶服务器知道作业的当前状态并将此信息传递给客户端。

    使用芹菜似乎是一个不错的方法。

    【讨论】:

    • 您能否分享一个创建长时间运行的工作进程以从队列中读取的示例
    猜你喜欢
    • 1970-01-01
    • 2018-02-02
    • 2014-05-21
    • 1970-01-01
    • 2021-05-17
    • 2016-03-30
    • 1970-01-01
    • 2021-11-07
    • 1970-01-01
    相关资源
    最近更新 更多