简介
Flask 是 Python 中有名的轻量级同步 web 框架,在一些开发中,可能会遇到需要长时间处理的任务,此时就需要使用异步的方式来实现,让长时间任务在后台运行,先将本次请求的响应状态返回给前端,不让前端界面「卡顿」,当异步任务处理好后,如果需要返回状态,再将状态返回。
Python资源共享群:626017123
怎么实现呢?
使用线程的方式
当要执行耗时任务时,直接开启一个新的线程来执行任务,这种方式最为简单快速。
通过 ThreadPoolExecutor 来实现
from flask import Flask from time import sleep from concurrent.futures import ThreadPoolExecutor # DOCS https://docs.python.org/3/library/concurrent.futures.html#concurrent.futures.ThreadPoolExecutor # 创建线程池执行器 executor = ThreadPoolExecutor ( 2 ) app = Flask (__name__) @app .route( '/jobs' ) def run_jobs(): # 交由线程去执行耗时任务 executor.submit(long_task, 'hello' , 123 ) return 'long task running.' # 耗时任务 def long_task(arg1, arg2): print ( "args: %s %s!" % (arg1, arg2)) sleep( 5 ) print ( "Task is done!" ) if __name__ == '__main__' : app.run()
当要执行一些比较简单的耗时任务时就可以使用这种方式,如发邮件、发短信验证码等。
但这种方式有个问题,就是前端无法得知任务执行状态。
如果想要前端知道,就需要设计一些逻辑,比如将任务执行状态存储到 redis 中,通过唯一的任务 id 进行标识,然后再写一个接口,通过任务 id 去获取任务的状态,然后让前端定时去请求该接口,从而获得任务状态信息。
全部自己实现就显得有些麻烦了,而 Celery 刚好实现了这样的逻辑,来使用一下。
使用 Celery
为了满足前端可以获得任务状态的需求,可以使用 Celery。
Celery 是实时任务处理与调度的分布式任务队列,它常用于 web 异步任务、定时任务等,后面单独写一篇文章描述 Celery 的架构,这里不深入讨论。
现在我想让前端可以通过一个进度条来判断后端任务的执行情况。使用 Celery 就很容易实现,首先通过 pip 安装 Celery 与 redis,之所以要安装 redis,是因为让 Celery 选择 redis 作为「消息代理 / 消息中间件」。
pip install celery pip install redis
在 Flask 中使用 Celery 其实很简单,这里先简单的过一下 Flask 中使用 Celery 的整体流程,然后再去实现具体的项目
- 1. 在 Flask 中初始化 Celery
from flask import Flask from celery import Celery app = Flask (__name__) # 配置 # 配置消息代理的路径,如果是在远程服务器上,则配置远程服务器中redis的URL app.config[ 'CELERY_BROKER_URL' ] = 'redis://localhost:6379/0' # 要存储 Celery 任务的状态或运行结果时就必须要配置 app.config[ 'CELERY_RESULT_BACKEND' ] = 'redis://l