记- django通过celery beat results实现定时任务
1. 实验环境
python版本:3.7.8
django版本:3.2.15
celery版本:5.2.7
django-celery版本:3.2.1
django-celery-beat版本:2.4.0
django-celery-results版本:2.4.0
django-redis版本:5.2.0
eventlet版本:0.33.3 (这个在windows下测试使用)
2. 根据以上安装模块,主要安装:
django-celery-beat模块:用于定时任务
django-celery-results模块:用于保存结果数据
3. django配置
假设我的项目名称为:ManagerCenter, 应用名称为:task_app
- 创建文件:ManagerCenter / ManagerCenter / celery.py
import os from celery import Celery from django.conf import settings # 设置celery的环境变量和django-celery的工作目录 os.environ.setdefault("DJANGO_SETTINGS_MODULE", "ManagerCenter.settings") # 实例化celery应用 app = Celery("ManagerCenter") # 加载celery配置 app.config_from_object(settings) # 如果在项目中,创建了task.py,那么celery就会沿着app去查找task.py来生成任务 app.autodiscover_tasks()
- 设置配置文件: ManagerCenter / ManagerCenter / settings.py
- INSTALLED_APPS = [
...... 'django_celery_results', # 用于生成定时和间隔任务 'django_celery_beat', # 用于将异步任务执行结果存储至关系型数据库,比如MySQL ]
# celery内容等消息的格式设置,默认json
CELERY_TASK_SERIALIZER = 'json'
CELERY_RESULT_SERIALIZER = 'json'
CELERY_ACCEPT_CONTENT=['json',] # 可选'application/json'
CELERY_TIMEZONE = 'Asia/Shanghai'
CELERY_ENABLE_UTC = True
BROKER_URL = 'redis://172.172.172.188:6379/1' # Broker配置,使用Redis作为消息中间件
# CELERY_RESULT_BACKEND = 'redis://172.172.172.188:6379/2' # Backend设置,使用redis作为后端结果存储
# 支持数据库django-db和缓存django-cache存储任务状态及结果
# 建议选django-db
CELERY_RESULT_BACKEND = 'django-db' # Backend设置,使用mysql作为后端结果存储
# admin 添加周期性任务
CELERYBEAT_SCHEDULER = 'django_celery_beat.schedulers:DatabaseScheduler'
CELERY_WORKER_MAX_TASKS_PER_CHILD = 5 # 每个worker最多执行的任务数, 可防止内存泄漏
CELERY_TASK_TIME_LIMIT = 15 * 60 # 任务超时时间# 为任务设置超时时间,单位秒。超时即中止,执行下个任务。建议设置
CELERY_TASK_TIME_LIMIT = 5
# 为存储结果设置过期日期,默认1天过期。如果beat开启,Celery每天会自动清除。
# 设为0,存储结果永不过期
CELERY_RESULT_EXPIRES = xx
# 任务限流CELERY_TASK_ANNOTATIONS = {'tasks.add': {'rate_limit': '10/s'}}
# Worker并发数量,一般默认CPU核数,可以不设置
CELERY_WORKER_CONCURRENCY = 2
- 编辑文件: ManagerCenter / ManagerCenter / __init__.py
from .celery import app as celery_app __all__ = ['celery_app']
- 创建任务文件:task_app / tasks.py
from __future__ import absolute_import, unicode_literals from ManagerCenter.celery import app @app.task() def add(): HttpResponseprint('11111111') return 1 + 2
# 这里解释一下:shared_task 和app.task的区别以及实例
#专属于某个celery实例化项目的task可以使用@app.task装饰器定义。 其他各app目录下复用的task建议使用 @shared_task定义。
# myproject/tasks.py
# 专属于myproject项目的任务
app = Celery('myproject')
@ app.task
def test():
pass
# app/tasks.py, 可以复用的task
from celery import shared_task
import time
@shared_task
def add(x, y):
time.sleep(2)
return x + y
4. 启动运行django服务,我是使用pycharm开发测试,直接启动完成
5. 将他们的模型迁移生成数据表,进入到ManagerCenter目录下,打开doc窗口,运行如下:
- python.exe .\manage.py migrate django_celery_beat
- python.exe .\manage.py migrate django_celery_results
执行完成后,会在数据库中生成: beat和result的相关表
6. 登录django的管理控制台: http://127.0.0.1:8000/admin ,会看到:CELERY RESULTS(这个是收集结果)标签块和PERIODIC TASKS标签块(这个是存放定时任务)
创建一个定时任务:
新建:“crontabs”,在 minutes:设置 */1 (表示每分钟执行一次),保存。
新建:“periodjc tasks”,
name : 自定义, Task (registered): 选择 task_app.tasks.add, Crontab Schedule: 选择上一步创建的, 最后保存即可。
7. 启动celery,进入到ManagerCenter目录下
- 首先启动worker异步任务:
windows: celery.exe -A ManagerCenter worker -l info -P eventlet
linux: celery.exe -A ManagerCenter worker -l info
- 然后启动beat任务调度器:
celery -A ManagerCenter beat -l info
等1分钟就能看到beat窗口出现发送任务队列。 worker窗口出现任务结果数据。
结尾:以上可以实现一个定时任务的测试
如何监控任务执行状态,请安装flower插件
pip install flower # 我当前安装的是flower-1.2.0
启动:
celery flower -A proj --address=127.0.0.1 --port=5555
启动后,可以通过游览器访问: http://127.0.0.1:5555 查看任务队列
另注意事项:
如果你变换了时区timezone,比如从'UTC'变成了'Asia/Shanghai',需重置周期性任务,这非常重要。
# 调整timezone后重置任务 $ python manage.py shell >>> from django_celery_beat.models import PeriodicTask >>> PeriodicTask.objects.update(last_run_at=None)
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步