记- 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)

posted @ 2023-03-07 22:54  十年如一..bj  阅读(385)  评论(0编辑  收藏  举报