• django 异步任务实现及Celery beat实现定时/轮询任务


    Celery定时任务

    requirements

    celery==3.1.25  异步任务
    django-celery==3.2.2  定时任务管理包
    redis==2.10.6
    django-redis-cache==1.7.1 方便配置Redis缓存

    配置

    1、工程主APP下的__init__.py文件里添加:

    from .celery import app as celery_app
    
    __all__ = ['celery_app']
    

    2、工程主APP新建个celery.py文件:

    from __future__ import absolute_import
    import os
    from celery import Celery
    
    # set the default Django settings module for the 'celery' program.
    os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'dts.settings')
    
    from django.conf import settings  # noqa
    
    app = Celery('dts')
    
    # Using a string here means the worker will not have to
    # pickle the object when using Windows.
    app.config_from_object('django.conf:settings')
    app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)
    
    
    @app.task(bind=True)
    def debug_task(self):
        print('Request: {0!r}'.format(self.request))
    

      

    启用Celery的定时任务需要设置CELERYBEAT_SCHEDULE 。 
    这里写图片描述 

    说明:

    CELERY_RESULT_SERIALIZER = 'json'为了避免错误:# Refusing to deserialize untrusted content of type pickle (application/x-python-serialize)
    CELERY_RESULT_BACKEND: 就是把异步任务放到指定地方,方便后续操作。比如后续取出任务判断是否完成

    Celery的定时任务都由celery beat来进行调度。celery beat默认按照settings.py之中的时区时间来调度定时任务。

    创建定时任务

    一种创建定时任务的方式是配置CELERYBEAT_SCHEDULE:

    #每30秒调用task.add
    from datetime import timedelta
    from celery.schedules import crontab #为了避免该行报错,在该文件添加绝对包含、from __future__ import absolute_import
    CELERYBEAT_SCHEDULE = { 'add-every-30-seconds': { 'task': 'tasks.add', 'schedule': timedelta(seconds=30), 'args': (16, 16) },
        'sys_check_unpaid': {
    'task': 'dashboard.tasks.mdata_schedule',
    'schedule': crontab(minute=0, hour=8, day_of_month=11),
    },
    }
     1 #crontab任务
     2 #每周一7:30调用task.add
     3 from celery.schedules import crontab
     4 
     5 CELERYBEAT_SCHEDULE = {
     6     # Executes every Monday morning at 7:30 A.M
     7     'add-every-monday-morning': {
     8         'task': 'tasks.add',
     9         'schedule': crontab(hour=7, minute=30, day_of_week=1),
    10         'args': (16, 16),
    11     },
    12 }

    使用数据库存储定时任务

    使用数据库存储定时任务需要设置CELERYBEAT_SCHEDULE如下:

    这里写图片描述

     1 import datetime
     2 import json
     3 from djcelery import models as celery_models
     4 from django.utils import timezone
     5 #创建任务
     6 def create_task(name, task, task_args, crontab_time):
     7     '''
     8     name # 任务名字
     9     task # 执行的任务 "myapp.tasks.add"
    10     task_args # 任务参数 {"x":1, "Y":1}
    11 
    12     crontab_time # 定时任务时间 格式:
    13     {
    14         'month_of_year': 9 # 月份
    15         'day_of_month': 5 # 日期
    16         'hour': 01 # 小时
    17         'minute':05 # 分钟
    18     }
    19     '''
    20 
    21     # task任务, created是否定时创建
    22     task, created = celery_models.PeriodicTask.objects.
    23                             get_or_create(name=name,task=task)
    24     # 获取 crontab
    25     crontab = celery_models.CrontabSchedule.objects.
    26                             filter(**crontab_time).first()
    27     if crontab is None:
    28     # 如果没有就创建,有的话就继续复用之前的crontab
    29         crontab = celery_models.CrontabSchedule.objects.
    30                             create(**crontab_time)
    31     task.crontab = crontab # 设置crontab
    32     task.enabled = True # 开启task
    33     task.kwargs = json.dumps(task_args) # 传入task参数
    34     expiration = timezone.now() + datetime.timedelta(day=1)
    35     task.expires = expiration # 设置任务过期时间为现在时间的一天以后
    36     task.save()
    37     return True
    38 #关闭任务
    39 def disable_task(name):
    40 '''
    41 关闭任务
    42 '''
    43     try:
    44         task = celery_models.PeriodicTask.objects.get(name=name)
    45         task.enabled = False # 设置关闭
    46         task.save()
    47         return True
    48     except celery_models.PeriodicTask.DoesNotExist:
    49         return True

    启动beat

    执行定时任务时, Celery会通过celery beat进程来完成。Celery beat会保持运行, 一旦到了某一定时任务需要执行时, Celery beat便将其加入到queue中. 不像worker进程, Celery beat只需要一个即可。而且为了避免有重复的任务被发送出去,所以Celery beat仅能有一个。

    启动:

    python manage.py celery beat --loglevel=info

    其实还有一种简单的启动方式worker和beat一起启动:

    python manage.py celery worker --loglevel=info --beat

    定时删除

    由于很多任务都是一次执行完就不需要,留在数据库里就是垃圾数据了有没有办法清除。方法肯定有因为django-celery本身就有定时任务功能我们加个任务就解决了。好我们看代码:在django app目录中打开taske.py加入如下代码

    from djcelery import models as celery_models
    from django.utils import timezone
    @task()
    def delete():
        '''
        删除任务
        从models中过滤出过期时间小于现在的时间然后删除
        '''
        return celery_models.PeriodicTask.objects.filter(
                                expires__lt=timezone.now()).delete()

    创建任务脚本里设置了 expires 1天以后过期,这样在filter的时候就能当做条件把过期的任务找到并且删除。

  • 相关阅读:
    报错:require_once cannot allocate memory----php,以前自己弄的稍微有点特殊的开发环境
    wget下载整个网站---比较实用--比如抓取Smarty的document
    Linux必须会的命令---也是以前记录的,ctrl+z fg 啥的 jobs 比较实用
    最全的ORACLE-SQL笔记
    UML十四图打油诗记忆法
    Spring整合Hibernate总结
    MyEclipse6.5优化
    windows XP 各个文件夹详细介绍
    hibernate所需jar包
    struts2所需的jar包
  • 原文地址:https://www.cnblogs.com/wangwei916797941/p/7595394.html
Copyright © 2020-2023  润新知