如何在Python的后台运行长时间运行的作业

2024-04-19 09:07:32 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个web服务,它运行长时间运行的作业(大约几个小时)。我正在用烧瓶,古尼康,和nginx开发这个。

我想做的是拥有一条需要很长时间才能完成的路径,调用一个创建线程的函数。然后,函数将返回一个guid到路由,路由将返回一个url(使用guid),用户可以使用该url来检查进度。我正在使线程成为守护进程(thread.daemon=True),以便在调用代码(意外)退出时线程退出。

这是正确的使用方法吗?它是有效的,但这并不意味着它是正确的。

my_thread = threading.Thread(target=self._run_audit, args=())
my_thread.daemon = True
my_thread.start()

Tags: 函数路径webtrueurl路由烧瓶my
3条回答

处理此类问题的更常见方法是从基本应用程序中提取操作并在外部调用它,使用诸如Celery这样的任务管理器系统。

使用this教程,您可以创建任务并从web应用程序触发它。

from flask import Flask

app = Flask(__name__)
app.config.update(
    CELERY_BROKER_URL='redis://localhost:6379',
    CELERY_RESULT_BACKEND='redis://localhost:6379'
)
celery = make_celery(app)


@celery.task()
def add_together(a, b):
    return a + b

然后您可以运行:

>>> result = add_together.delay(23, 42)
>>> result.wait()
65

请记住,您需要单独运行worker:

celery -A your_application worker

好吧,虽然你的方法不正确,但基本上它可能会导致你的程序没有可用的线程。如Ali所述,一般的方法是使用像RQCelery这样的作业队列。但是,您不需要提取函数来使用这些库。对于烧瓶,我建议您使用Flask-RQ。一开始很简单:

RQ公司

pip install flask-rq

记住在你的Flask应用中使用Redis之前先安装它。

只需在烧瓶函数中使用@Job Decorator:

from flask.ext.rq import job


@job
def process(i):
    #  Long stuff to process


process.delay(3)

最后,您需要rqworker来启动工作进程:

rqworker

有关详细信息,请参见RQ docs。为简单的长时间运行过程而设计的RQ。

芹菜

芹菜更复杂,有大量的功能列表,如果您是新的作业队列和分布式处理方法,则不推荐使用芹菜。

绿叶

绿叶有开关。让您在长时间运行的进程之间切换。 您可以使用greenlet来运行进程。这样做的好处是,您不需要Redis和其他worker,而是必须重新设计功能,使其兼容:

from greenlet import greenlet

def test1():
    print 12
    gr2.switch()
    print 34

def test2():
    print 56
    gr1.switch()
    print 78

gr1 = greenlet(test1)
gr2 = greenlet(test2)
gr1.switch()

芹菜和RQ对于简单任务来说太过工程化了。 看看这个文档-https://docs.python.org/3/library/concurrent.futures.html

还要检查示例,如何在Flask app-https://stackoverflow.com/a/39008301/5569578的后台运行长时间运行的作业

相关问题 更多 >