Celery 是一个简单、灵活且可靠的,处理大量消息的分布式系统,专注于处理异步任务队列,同时也支持任务调度。一般耗时操作需要通过异步任务来执行
用户编写的代码脚本,用来定义要执行的任务,然后通过broker将任务发送到消息队列中
代理,通过消息队列在客户端和worker之间进行协调,celery本身不包含消息队列,但他支持以下的消息队列
数据库,用来存储任务返回的结果
用来执行broker分配的任务
celery文档地址:https://docs.celeryq.dev/en/stable/search.html?q=beat
# 以下命令安装celery的同时安装了redis
pip install celery[redis]
# 安装eventlet
pip install eventlet
编写一个celery应用
from celery import Celery
# 实例化应用
app = Celery("tasks",#任务名称
broker="redis://:xxx@xxxx/1",
backend='redis://:xxx@xxxx/2')
@app.task
def add(x,y):
print("x+y=",x+y)
return x+y
启动celery的命令:
celery -A tasks worker -l info -P eventlet
# tasks为执行的任务
调度任务:
任务函数名.delay(参数,参数),如以下
add.delay(1,2)
1.在项目目录下新建一个celery.py文件,文件中内容如下
import os
from celery import Celery
# 设置django的配置模块
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'xx.settings')
app = Celery("xx")
# 设置celery的配置,从diango项目配置文件中获取celery的配置
# 配置文件中以CELERY开头的配置会被读取
app.config_from_object('django.conf:settings',namespace="CELERY")
# # 调用自动发现任务的方法,注册所有已经在应用中定义的任务
app.autodiscover_tasks()
2.在项目的settings.py中配置以下内容
# 让celery的本身的log不起作用
CELERYD_WORKER_HIJACK_ROOT_LOGGER = False
# 时区
CELERY_TIMEZONE=TIME_ZONE
# 过期时间
CELERY_TIME_LIMIT=30*60
# BROKER配置
CELERY_BROKER_URL= "redis://:xxx@xxx/1",
# backend配置
CELERY_RESULT_BACKEND='redis://:xxx@xxxx/2'
3.celery日志配置
"celery": {
'level': 'INFO',
'class': 'logging.handlers.RotatingFileHandler',
'filename': os.path.join(BASE_DIR, 'logs/celery.log'),
'maxBytes': 30 * 1024 * 1024,
"backupCount": 10,
'formatter': 'verbose',
"encoding": "utf-8"
}
},
'loggers': {
"celery": {
'handlers': ['celery', 'console'],
'level': 'INFO',
'propagate': True,
}
},
}
4.在任务函数中加上装饰器@shared_task
from celery import shared_task
@shared_task
def add(x,y):
return x+y
5.启动celery
celery -A 项目名称 worker -l info -P eventlet
pip install django-celery-beat
celery beat是一个调度程序,他定期启动任务,然后由集群中的可用工作节点执行这些任务
周期任务调度默认的时区是UTC,可以设置时区,通过以下命令
timezone=‘Asia/Shanghai’
将上面的时区配置到应用程序中通过app.conf.timezone=“Asia/Shanghai”
要定期调用一个任务,必须要在调度列表中添加一个条目,代码如下
# 函数
@app.task
def add(x,y):
print("x+y=",x+y)
return x+y
@app.task
def hello():
print("hello world!")
from celery import Celery
from celery.schedules import crontab
@app.on_after_configure.connect
def setup_periodic_tasks(sender,**kwargs):
# 添加定时任务
sender.add_periodic_task(10,add.s(22,33),name="add every ten") sender.add_periodic_task(crontab(hour=12,minute=58,day_of_week=6), hello.s(22, 33), name="定时执行")
启动beat
celery -A ck15 beat -l info --scheduler django_celery_beat.schedulers:DatabaseScheduler
启动work
celery -A ck15 worker -l info -P eventlet