Celery

Celery

1.介绍

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

​ Celery的架构由三部分组成:

​ 消息中间件(message broker),通俗理解就是工会的任务墙

​ 任务执行单元(worker),通俗理解就是冒险家来执行任务,独立执行

​ 任务执行结果存储(backend)组成,通俗理解就是执行任务的结果

​ Celery没有自己的中间件,要借助于第三方提供的消息中间件,包括,RabbitMQ, Redis等等

​ 也没有自己的存储介质,可以借助于Redis,Mysql等等

2.功能

  • 异步任务:解决耗时任务
  • 定时任务:解决延迟任务
  • 延迟任务:解决周期(周期)任务

注意:Celery 启动起来是一个服务,如果和django一起

3.简单使用,使用异步

1.安装
直接安装
pip install celery
注意,官方说了不支持windows
还要装一个第三方模块
pip install eventlet

2.新建一个文件夹,新建一个main.py文件 这个名字随意的
from celery import Celery
# 提交的异步任务,放在里面
broker = 'redis://127.0.0.1:6379/2'
# 执行完的结果,放在这里
backend = 'redis://127.0.0.1:6379/3'

a = Celery('name', broker=broker, backend=backend) #实例化对象

@a.task   # 装饰器修饰
def add(a,b):
    import time
    time.sleep(3)
    print(a+b)
    return a+b

3.另外建立一个Py文件,其实就是相当于其他程序来提交任务,而不是在celery页面中自己提交任务
from main import add

res = add.delay(10,11)
print(res)

>>> 执行后得到一串ID,这个就是任务的ID号,此时,任务还没有执行,只是提交到了消息中间件存着,可以自己打开redis的库看看

4.启动worker
要去命令行启动(开启后就一直会挂着运行了)
	win:
       -4.x之前版本
		celery worker -A main -l info -P eventlet
       -4.x之后
    	celery  -A main  worker -l info -P eventlet
	mac:
       celery  -A main  worker -l info

worker执行后,结果存放在backend配置的库中,这里就是放在了redis的库中

5.只要来了任务,worker就执行,执行后存放结果

6.查看结果
新建一个py文件,指定要查询的任务id号,指定要查询的celery对象
from main import a  # 导入celery对象

from celery.result import AsyncResult


id = '5388bf11-f7b1-41da-a33d-b8aff016f73d'

if __name__ == '__main__':
    b = AsyncResult(id=id,app=a)
    if b.successful():
        result = b.get()
        print(result)
    elif b.failed():
        print('mission failed')
    elif b.status == 'PENDING':
        print('任务等待被执行')
    elif b.status == 'RETRY':
        print('任务正在重新尝试')
    elif b.status == 'STARTED':
        print('任务已经开始执行,但是还没有结束')

4.包结构使用

​ 任务不应该写在celery对象产生文件中,应该分开来

1.建立一个包,名字随意
2.包中建立一个py文件,名字必须是celery,用来生成celery对象,但是多了一个参数,用来注册任务
from celery import Celery
broker = 'redis://127.0.0.1:6379/3'
backend = 'redis://127.0.0.1:6379/4'

# 注册一下任务
a = Celery('test',broker=broker,backend=backend,include=['celery_one.user_task','celery_one.order_task']) #实例化一个对象出来

3.包中建立任务py文件
from .celery import a
import time

@a.task
def send_sms(phone, code):
    print(f'给{phone}发了短信,短信内容是:您本次验证码为{code},将在五分钟内有效')
    time.sleep(3)

    return True



4.建立添加任务的py文件,不要建立在包中,意思就是其他程序提交任务

from celery_one.user_task import send_sms

# res = send_sms('17688888888','6666')
#
# print(res)

res = send_sms.delay('17688888888','6666')
print(res)


5.命令行启动worker
一定要去到包所在的目录下,不要进入包,执行,A后面跟的就是包名
celery -A celery_one  worker -l info -P eventlet

6.建立取得结果的Py文件
from celery_one.celery import a  # 导入celery对象

from celery.result import AsyncResult

 
id = '1c869c76-d515-4872-99d6-858674cf6174'  #拿着ID号去要结果

if __name__ == '__main__':
    b = AsyncResult(id=id,app=a)
    if b.successful():
        result = b.get()
        print(result)
    elif b.failed():
        print('mission failed')
    elif b.status == 'PENDING':
        print('任务等待被执行')
    elif b.status == 'RETRY':
        print('任务正在重新尝试')
    elif b.status == 'STARTED':
        print('任务已经开始执行,但是还没有结束')

5.延迟任务

​ 这个用的很少,就是提交任务后,worker延缓一些时间再执行

​ django默认使用世界标准时,如果要改我们中国东八区,要去改一下

from datetime import datetime,timedelta

time = datetime.utcnow() + timedelta(seconds=10)  # 要进行时间的运算,需要使用timedelta
res = send_sms.apply_async(args=['17678985653','8888'],eta=time)
print(res)

>>>worker收到了隔10秒才会执行

6.定时任务

​ 定时提交任务是由另外一个程序来提交,相当于中间人,这个东西的配置在celery中写,这个程序叫做beat

1.在celery的py文件中写入,改时区
app.conf.timezone = 'Asia/Shanghai'
app.conf.enable_utc = False
2.beat的配置
app.conf.beat_schedule = {
            'send_sms': {
                'task': 'celery_one.user_task.send_sms',
                # 'schedule': timedelta(seconds=3),  # 时间对象
                # 'schedule': cro	ntab(hour=8, day_of_week=1),  # 每周一早八点
                #crontab 需要导入,from celery.schedules import crontab
                'schedule': crontab(hour=9, minute=43),  # 每天9点43
                'args': ('18888888', '6666'),
            },
        }
3.命令行,开启beat
我这里直接用os.system一并开启了
import os
os.system('celery -A  celery_one beat -l info')

4.这样beat这个进程就会按照配置来提交任务,而worker只要接到了就执行(因为对于worker而言不是延迟任务)

7.django中使用celery

-1 把咱们写的包,复制到项目目录下
-luffy_api
 -celery_task #celery的包路径
   celery.py  # 一定不要忘了一句话给celery中
import os
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'luffy_api.settings.dev')
-luffy_api  #源代码路径

-2 在使用提交异步任务的位置,导入使用即可
-视图函数中使用,导入任务
-任务.delay()  # 提交任务


-3 启动worker,如果有定时任务,启动beat

-4 等待任务被worker执行

-5 在视图函数中,查询任务执行的结果



# 重点:celery中使用djagno,有时候,任务中会使用django的orm,缓存,表模型。。。。一定要加
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'luffy_api.settings.dev')

一个秒杀页面

整理一下

注意

1.当我们在某个文件执行命令时,这个文件的上一层的路径会被自动加入到环境变量中去
import sys
def add(a,b):
    return a+b

print(add(1,2))

print(sys.path)  # 会发现这一个文件的上一级在环境变量的第一位
2.提交任务后返回的是一个对象,虽然直接打印就是id,但是如果不是打印的时候,要点出来才是id的值
3.axios.xx().then(状态码200走这个).catch(状态码不是200走这个)

补充

1.如果在公司中,只是做定时任务,还有一个更简单的框架
APSchedule:https://blog.csdn.net/qq_41341757/article/details/118759836
posted @   yiwufish  阅读(44)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示