基于 redis 使用 celery 实现异步任务函数

834 阅读3分钟

一、前言 Flask 作为常见的 web 应用框架,需要经常使用到异步执行任务,先返回响应给前端,异步任务同时进行。今天我将介绍一下 Celery 基本组成和常见的使用场景,再通过一个简单的代码实现异步任务的执行。

二、Celery 基本组成 celery 主要是由 3 个部分组成,第一个部分就是消息队列,用来存储异步任务的,一般用 redis 或者 rabbit mq 做为消息队列,异步任务插入消息队列里面,拿到对应的 task_id,等待 worker 取走任务。第二个部分就是任务执行单元,也就是进行异步任务执行的 worker,使用 worker 配置文件启动多个 worker ,之后worker 就会连接到对应的消息队列并进行监听,一旦有消息任务进来队列,就取出任务给 worker 执行。第三个部分就是任务结果存储。异步任务执行后的结果保留的位置,可以存储在 redis 数据库,之后可以根据 task_id 查询对应的结果。

三、celery 的使用场景

  1. 短信验证码,前端触发发送验证码之后服务器响应已发送,接着服务器再去调用响应的发短信服务。
  2. 爬虫任务调起,爬虫任务也是需要长时间执行,前端发起任务之后不可能长时间等待,所以需要通过异步任务发起爬虫
  3. 定时任务,celery beat 配置文件可以定时任务,需要多运行一个 celery beat 服务,感觉不如 linux 自带的 crontab 好用

四、celery 代码实践

  • celery_task_conf.py (celery worker 配置文件)
# celery worker 配置文件,相当于消费者

from celery import Celery
import time

# 1. 实例化 celery 实例
# 2. 创建 celery 任务

backend = "redis://127.0.0.1:6379/1"
broker = "redis://127.0.0.1:6379/2"
cute_celery = Celery("cute_celery ", backend=backend, broker=broker)

@cute_celery .task()
def hello_world():
    '''这是一个长时间任务'''
    time.sleep(10)
    print("hello world")

上面就是一个基本的 celery worker 配置文件了, broker 就是 worker 需要连接和监听的消息队列了。选用 redis 2 号数据库作为消息队列。backend 就是任务结果存储,celery 任务执行成功或失败都在 backend 这个数据库里。 有了这个配置文件之后,我们来启动一下消费者, 也就是 worker

# -A 指定配置文件名
celery worker -A celery_task_conf -l INFO

启动之后,我们可以看到对应的 hello_word 任务已经被扫描进来了

celery_start.png

然后我们新建一个文件,利用 delay 方法调用一下对应 hello_world 异步任务,这样异步任务就会存储到 redis 2 号数据库里面,一般就是函数名和对应的函数参数。而刚刚上面启动的 celery worker 监控到任务的到来,就会执行对应的函数。

from celery_task import hello_world
# 通过 .delay 方法实现调用,为什么会有 delay 方法呢,这是因为加了 @cute_celery .task() 装饰器
hello_world.delay()

我们来看看 celery worker 收到任务之后执行情况

celery_task_finish.png

至此我们就完成了 celery 做为异步任务的功能了,而 celery 的功能还有失败重试、成功\失败回调,还有串行任务链,这个也是在使用过程中经常用到的。