celery

项目地址:GitHub - celery/celery: Distributed Task Queue (development branch)

文档地址:(3.1)入门 — Celery 3.1.7 文档

                   (5.1) Celery - Distributed Task Queue — Celery 5.3.1 documentation

celery不建议在windows下使用,Celery在4.0版本之后不再支持windows系统,如果要在windows下使用只能安装4.0以前的版本,并且需要安装geventlet或eventlet协程模块

什么是celery

celery是一个简单、灵活、可靠的,可以处理大量消息的分布式系统,专注于实时处理异步任务队列,同时也支持任务调度

 Task

        任务(Task) 就是你要做的事情,例如一个注册流程里面有很多任务,给用户发验证邮件、发送短信验证码等

Broker

        Broker中文意思是经纪人,他介于生产者和消费者之间,相当于数据结构中的队列,Celery本身不提供队列服务,一般使用Redis或者RabbitMQ来扮演Broker

Worker

        Worker就是在后台一直去执行任务的人,也称为任务的消费者,它会实时地监控队列中有没有任务[轮询],如果有就立即取出来执行

Beat

        Beat是一个定时任务调度器,它会根据配置定时将任务发送给Broker,等待Worker来消费

Backend

        Backend用户保存任务的执行结果,每个任务都会有返回值,比如发送邮件会返回是否成功,这个结果存储在Backend中

使用场景

        celery是一个强大的分布式任务队列异步处理框架,它可以让任务脱离主程序执行,甚至可以分配到其他主机上执行,通常使用celery处理异步任务或者定时任务

异步任务 : 将耗时操作的任务交给celery,如发送邮件、短信、消息推送、音视频处理等

定时任务 : 定时执行某件事情,比如每天统计数据

celery运行原理

        原理 : 就是django写的任务(Task)推送到Broker(任务队列)中,启动celery(Worker)不断对broker进行轮询,处理任务的结果存储到backend中,之后客户端视图会从结果队列把结果拿出来

客户端 : django代码写的task任务

broker : 任务队列(redis、rabbitMQ)

worker : celery提供进程

backend : 结果队列(redis、rabbitMQ)

 一个celery系统可以包含很多的worker和broker

Celery本身不提供消息队列功能,但是可以很方便地和第三方提供的消息中间件进行集成,包括Redis、RabbitMQ、RocketMQ等

安装

        pip install -U celery -i Simple Index

使用

 celery单独使用

  

run.py文件内容

from celery import Celery

# 通过使用本机redis且没有密码,使用远程redis有密码格式为
# 'redis://:密码@ip:6379/1'
broker = 'redis://127.0.0.1:6379/1'  # 任务储存
backend = 'redis://127.0.0.1:6379/2'  # 结果存储,执行完之后结果放在这

# 创建出app对象
app = Celery(__name__, broker=broker, backend=backend)

# 任务通过装饰器@app.task进行装饰
@app.task
def add(x, y):
    return x + y

task.py

# celery的任务必须写在tasks.py的文件中,别的文件名称不识别!!!
from mycelery.main import app
import time

import logging
log = logging.getLogger("django")

@app.task  # name表示设置任务的名称,如果不填写,则默认使用函数名做为任务名
def send_sms(mobile):
    """发送短信"""
    print("向手机号%s发送短信成功!"%mobile)
    time.sleep(5)

    return "send_sms OK"

@app.task  # name表示设置任务的名称,如果不填写,则默认使用函数名做为任务名
def send_sms2(mobile):
    print("向手机号%s发送短信成功!" % mobile)
    time.sleep(5)

    return "send_sms2 OK"

@app.task(name="send_sms3")
def send_sms3(x,y):
    """有结果的异步任务"""
    print('任务:send_sms3执行了...')
    return x+y

main.py

import os
from celery import Celery

# 实例化celery应用,第一个参数是自定义的一个实例名称,按变量名的命名规范来定义
app = Celery("test")

# 把celery和django进行组合,识别和加载django的配置文件
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'celeryPros.settings.dev')


# 通过app实例对象加载配置
app.config_from_object("mycelery.setting")


# 注册异步任务, 自动搜索并加载任务
# 参数必须必须是一个列表,里面的每一个任务都是任务的路径名称
# app.autodiscover_tasks(["任务1","任务2",....])
# 会自动识别到tasks.py中的异步任务
app.autodiscover_tasks(["mycelery.sms","mycelery.mail"])

# 启动Celery的终端命令
# 强烈建议切换目录到项目的根目录下启动celery!!
# celery -A mycelery.main worker --loglevel=info
 

setting.py

# 任务队列的链接地址
broker_url = 'redis://127.0.0.1:6379/14'
#
# # 结果队列的链接地址
result_backend = 'redis://127.0.0.1:6379/15'

produce.py

from mycelery.sms.tasks import send_sms2, send_sms3
# from mycelery.sms.tasks import send_sms, send_sms3
from datetime import datetime
import time


# delay(*arg, **kwargs)
# apply_async((arg,), {'kwarg': value}, countdown=60, expires=120)

# delay 表示马上按顺序来执行异步任务,在celrey的worker工作进程有空闲的就立刻执行
# 可以通过delay异步调用任务,可以没有参数
# delay(*arg, **kwargs)

# apply_async 让任务在后面指定时间后执行,时间单位:秒/s
# 任务名.apply_async(args=(参数1,参数2), countdown=定时时间)
# apply_async((arg,), {'kwarg': value}, countdown=60, expires=120)

# 根据返回结果,不管delay,还是apply_async的返回结果都一样的。

# result = send_sms2.delay(13894000789)
# print(result.id) # 返回一个UUID格式的任务唯一标志符,78fb827e-66f0-40fb-a81e-5faa4dbb3505
# time.sleep(5)
# print(result.status) # 查看当前任务的状态 SUCCESS表示成功!

ctime = datetime.now()
# 默认用utc时间
utc_ctime = datetime.utcfromtimestamp(ctime.timestamp())
from datetime import timedelta
time_delay = timedelta(seconds=10)
task_time = utc_ctime + time_delay

# 使用apply_async并设定时间
result = send_sms2.apply_async(args=["120"], eta=task_time)
print(result)

result2 = send_sms3.delay(3,3)
print(result2)


# 查看任务执行状态,执行完成(不管是否发生异常还是正常执行)返回True,未执行返回False
print(result2.ready())

# 如果任务出现异常,可以通过以下命令进行回溯
result2.traceback


from mycelery.main import app
from celery.result import AsyncResult

asy = AsyncResult(id=result, app=app)
# 是否正常执行完成,正常执行成功返回True,否则返回False
print(asy.successful())

# 执行成功打印结果
print(asy.get())

# 是否正常执行失败,失败返回True,否则返回False
print(asy.failed())
# 查看任务状态
print(asy.status)
# 执行状态一般有三种PENDING、RETRY、STARTED

运行步骤

终端执行命令启动worker : celery -A mycelery.main worker --loglevel=info

执行peoduce_task.py , 查看终端,并查看结果队列

celery集成到django框架
启动mycelery项目,访问接口127.0.0.1:8080/test

终端命令 : celery -A mycelery.main worker --loglevel=info

view.py

from django.shortcuts import render

# Create your views here.


from django.shortcuts import render,HttpResponse
from mycelery.mail.tasks import send_mail,send_mail2
from datetime import timedelta

from datetime import datetime
def test(request):

    ################################# 异步任务

    # 1. 声明一个和celery一模一样的任务函数,但是我们可以导包来解决

    # send_mail.delay("110qq.com")
    # send_mail2.delay("119qq.com")
    # send_sms.delay() 如果调用的任务函数没有参数,则不需要填写任何内容


    ################################# 定时任务

    ctime = datetime.now()
    # 默认用utc时间
    utc_ctime = datetime.utcfromtimestamp(ctime.timestamp())
    time_delay = timedelta(seconds=10)
    task_time = utc_ctime + time_delay
    result = send_mail.apply_async(["911", ], eta=task_time)
    print("xiaofeizhe",result.id)

    return HttpResponse('ok')

celery异步任务调用方法
delay(*args, **kwargs)

apply_async((*args,),{**kwargs:value}, countdown=60, expires=120)

delay:表示马上按照顺序执行异步任务(task.py),在celery的worker有空闲就会立刻执行

apply_async 让任务在后面指定时间后执行,时间单位:秒/s

任务名.apply_async(args=(参数1,参数2), countdown=定时时间)

出现错误情况

list模式 :当消息丢失或者消费失败,只能在消费之前把数据备份,之后配置base=class,class是一个类,类中写一些回调函数,on_failuer,on_success等,

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值