Python + Flask 执行异步任务

在使用Flask开发python的web应用时,可能会遇到需要较长时间处理的任务,此时就需要使用异步的方式来实现,让长时间任务在后台运行,先将本次请求的响应状态返回给前端,不然前端界面"卡顿",当异步任务处理好后,如果需要返回状态,再将状态返回。

下面介绍两种常用的方式

(1)使用线程的方式

当要执行耗时任务时,直接开启一个新的线程来执行任务,这种方式最为简单快速。

通过ThreadPoolExecutor来实现

asyn_request_demo.py

# -*- coding: UTF-8 -*-
"""
# rs
"""
from logzero import logger
import time
from flask import Flask
from flask_restful import Api
from flask import jsonify
from flask import make_response
from concurrent.futures import ThreadPoolExecutor

executor = ThreadPoolExecutor()
# executor = ThreadPoolExecutor(10) 里面的数字是线程池所能同时进行的最大数量 
 
app = Flask(__name__)
api = Api(app)
 

def run(name, age):
    """
    # 异步任务
    """
    time.sleep(3)
    logger.info("name: %s, age: %s." % (name, age))
    logger.info("耗时任务执行结束")
 
 
@app.route('/test')
def test():
    # 传递多个参数
    args = ["rongsong", "28"]
    # 交给线程去处理耗时任务, 异步执行
    executor.submit(lambda p: run(*p), args)
    
    # 直接返回结果
    result = {
        "code": "200",
        "message": "success",
        "data": "green"
    }
    return make_response(jsonify(result))

 
if __name__ == "__main__":
    # 启动一个HTTP服务
    app.run(host="0.0.0.0", port=8800, debug=True)
  • 使用pip3安装相应的库(不再赘述)。
  • 使用python3  asyn_request_demo.py运行启动即可(启动端口8800,可修改)。
  • 然后访问http://{执行机器所在IP}:8800/test观察。
  • 预期可以看到:接口直接返回result结果(同步),后台日志等待5s左右打印日志"耗时任务执行结束"(异步)。

当要执行一些比较简单的耗时任务时可以使用这种方式,如发邮件、发送短信验证码等。

当这种方式有个很明显的问题,就是我们无法得到任务的执行状态

如果想要随时得到任务的执行状态,就需要设计一些逻辑,比如奖任务执行状态存储到Redis中,通过唯一的任务id进行标识,然后再写一个接口通过任务id去获取任务的状态,然后让前端定时的去请求该接口,从而获得任务状态信息。

是不是有点复杂,如果让我们自己实现的话,哈哈哈,别慌,Celery框架刚好实现了这样的逻辑,比较成熟,一般我们遇到问题时都可以先看看有没有现成的框架和方法,毕竟站在巨人的肩膀上我们可以看的更远。

(2)使用Celery的方式

Celery是定时任务处理和调度的分布式任务队列,常用于web异步任务、定时任务等。

猜你喜欢

转载自blog.csdn.net/sinat_33718563/article/details/119546096
今日推荐