• Celery-周期性任务


    Celery(4.4)的当前稳定版本。
    官网文档:https://docs.celeryproject.org/en/latest/index.html

    周期性任务

    简介

    celery beat是一个调度程序;它定期启动任务,然后由集群中的可用工作程序节点执行任务。

    默认情况下,条目是从beat_schedule设置中获取的,但也可以使用自定义存储,例如将条目存储在SQL数据库中。

    您必须确保一次只有一个调度程序针对一个调度程序运行,否则最终将导致重复的任务。使用集中式方法意味着时间表不必同步,并且服务可以在不使用锁的情况下运行。

    时区

    默认情况下,定期任务计划使用UTC时区,但是您可以使用该timezone 设置更改使用的时区。

    时区的示例可以是Europe / London:

    timezone = 'Europe/London'
    

    必须使用()直接对其进行配置,或者如果使用对其进行了设置,则必须将其添加到配置模块中,才能 将该设置添加到您的应用中。有关配置选项的更多信息,请参见配置app.conf.timezone = 'Europe/London'``app.config_from_object

    默认的调度程序(将调度程序存储在celerybeat-schedule 文件中)将自动检测到时区已更改,因此将重置调度程序本身,但是其他调度程序可能不那么聪明(例如Django数据库调度程序,请参见下文)。在这种情况下,您必须手动重置计划。

    Django用户

    Celery建议并与USE_TZDjango 1.4中引入的新设置兼容。

    对于Django用户,TIME_ZONE将使用设置中指定的时区,或者您可以使用timezone设置单独为Celery指定自定义时区。

    与时区相关的设置更改时,数据库调度程序不会重置,因此您必须手动执行此操作:

    $ python manage.py shell
    >>> from djcelery.models import PeriodicTask
    >>> PeriodicTask.objects.update(last_run_at=None)
    

    Django-Celery仅支持Celery 4.0及更低版本,对于Celery 4.0及更高版本,请执行以下操作:

    $ python manage.py shell
    >>> from django_celery_beat.models import PeriodicTask
    >>> PeriodicTask.objects.update(last_run_at=None)
    

    条目

    要定期调用任务,您必须在拍子时间表列表中添加一个条目。

    from celery import Celery
    from celery.schedules import crontab
    
    app = Celery()
    
    @app.on_after_configure.connect
    def setup_periodic_tasks(sender, **kwargs):
        # Calls test('hello') every 10 seconds.
        sender.add_periodic_task(10.0, test.s('hello'), name='add every 10')
    
        # Calls test('world') every 30 seconds
        sender.add_periodic_task(30.0, test.s('world'), expires=10)
    
        # Executes every Monday morning at 7:30 a.m.
        sender.add_periodic_task(
            crontab(hour=7, minute=30, day_of_week=1),
            test.s('Happy Mondays!'),
        )
    
    @app.task
    def test(arg):
        print(arg)
    

    on_after_configure处理程序中进行设置意味着使用时,我们不会在模块级别评估应用test.s()。请注意,该消息 on_after_configure是在设置应用程序后发送的,因此在声明应用程序的模块之外的任务(例如在位于的task.py文件中 celery.Celery.autodiscover_tasks())必须使用更高的信号,例如 on_after_finalize

    add_periodic_task()功能会将条目添加到beat_schedule幕后的 设置中,并且相同的设置还可用于手动设置定期任务:

    示例:每30秒运行task.add任务。

    app.conf.beat_schedule = {
        'add-every-30-seconds': {
            'task': 'tasks.add',
            'schedule': 30.0,
            'args': (16, 16)
        },
    }
    app.conf.timezone = 'UTC'
    

    注意

    如果您想知道这些设置应该去哪里,请参阅配置。您可以直接在应用程序上设置这些选项,也可以保留单独的模块进行配置。

    如果要对args使用单个项目元组,请不要忘记构造函数是逗号,而不是一对括号。

    timedelta对时间表使用a 表示任务将以30秒为间隔发送(第一个任务将在开始芹菜拍打 30秒后发送,然后在最后一次运行之后每30秒发送一次)。

    还存在类似Crontab的日程表,请参阅有关Crontab日程表的部分。

    cron一样,如果第一个任务在下一个任务之前没有完成,则这些任务可能会重叠。如果这是一个问题,则应该使用锁定策略来确保一次只能运行一个实例(例如, 确保确保一次仅执行一个任务)。

    可用字段

    • 任务

      要执行的任务的名称。

    • 时间表

      执行频率。

      这可以是整数,a timedelta或a 的秒数 crontab。您还可以通过扩展的界面来定义自己的自定义计划类型schedule

    • args

      位置参数(listtuple)。

    • 夸格

      关键字参数(dict)。

    • 选项

      执行选项(dict)。

      这可以是apply_async()– exchange,routing_key,expires等支持的任何参数 。

    • 相对的

      如果相对是真的,timedelta时间表是“按时”安排的。这意味着频率会根据的时间舍入到最接近的秒,分钟,小时或天 timedelta

      默认情况下,relative为false,频率不四舍五入,将与开始芹菜拍打的时间有关。

    Crontab时间表

    如果要对执行任务的时间(例如,一天中的特定时间或一周中的一天)进行更多控制,则可以使用crontab计划类型:

    from celery.schedules import crontab
    
    app.conf.beat_schedule = {
        # Executes every Monday morning at 7:30 a.m.
        'add-every-monday-morning': {
            'task': 'tasks.add',
            'schedule': crontab(hour=7, minute=30, day_of_week=1),
            'args': (16, 16),
        },
    }
    

    这些Crontab表达式的语法非常灵活。

    一些例子:

    含义
    crontab() 每分钟执行一次。
    crontab(minute=0, hour=0) 每天午夜执行。
    crontab(minute=0, hour='*/3') 每三个小时执行一次:午夜,3am,6am,9am,中午,3pm,6pm,9pm。
    crontab(minute=0,``hour='0,3,6,9,12,15,18,21') 和以前一样。
    crontab(minute='*/15') 每15分钟执行一次。
    crontab(day_of_week='sunday') 在星期日执行每一分钟(!)。
    crontab(minute='*',``hour='*', day_of_week='sun') 和以前一样。
    crontab(minute='*/10',``hour='3,17,22', day_of_week='thu,fri') 每十分钟执行一次,但仅在周四或周五的凌晨3-4点,下午5-6点以及晚上10-11点之间执行。
    crontab(minute=0, hour='*/2,*/3') 每隔一小时执行一次,每一小时被三整除。这意味着:每小时除外:1 am、5am、7am、11am、1pm、5pm、7pm、11pm
    crontab(minute=0, hour='*/5') 执行小时可被5整除。这意味着它在下午3点而不是下午5点被触发(因为3pm等于24小时制时钟值“ 15”,可被5整除)。
    crontab(minute=0, hour='*/3,8-17') 每小时执行一次可被3整除的时间,并在办公时间(上午8点至下午5点)每小时执行一次。
    crontab(0, 0, day_of_month='2') 在每个月的第二天执行。
    crontab(0, 0,``day_of_month='2-30/2') 在每个偶数天执行一次。
    crontab(0, 0,``day_of_month='1-7,15-21') 在每月的第一和第三周执行。
    crontab(0, 0, day_of_month='11',``month_of_year='5') 每年5月11日执行。
    crontab(0, 0,``month_of_year='*/3') 在每个季度的第一个月每天执行一次。

    请参阅celery.schedules.crontab以获取更多文档。

    太阳能时间表

    如果您有应根据日出,日落,黎明或黄昏执行的任务,则可以使用 solar计划类型:

    from celery.schedules import solar
    
    app.conf.beat_schedule = {
        # Executes at sunset in Melbourne
        'add-at-melbourne-sunset': {
            'task': 'tasks.add',
            'schedule': solar('sunset', -37.81753, 144.96715),
            'args': (16, 16),
        },
    }
    

    参数很简单: solar(event, latitude, longitude)

    确保对纬度和经度使用正确的符号:

    标志 争论 含义
    + latitude
    - latitude
    + longitude
    - longitude 西方

    可能的事件类型是:

    事件 含义
    dawn_astronomical 在天空不再完全黑暗的那一刻执行。这是当太阳低于地平线18度时。
    dawn_nautical 当有足够的阳光照亮地平线并区分一些物体时执行。正式地,当太阳低于地平线12度时。
    dawn_civil 当有足够的光线可辨别物体时执行,以便户外活动可以开始;正式地,当太阳在地平线以下6度时。
    sunrise 当早晨早晨太阳的上边缘出现在东部地平线上方时执行。
    solar_noon 当当天太阳最高到地平线以上时执行。
    sunset 当傍晚太阳的后缘在西方地平线上消失时执行。
    dusk_civil 当物体仍然可以区分并且可见一些恒星和行星时,在民航末尾执行。正式地,当太阳低于地平线6度时。
    dusk_nautical 当太阳低于地平线12度时执行。物体不再可分辨,并且肉眼不再看到地平线。
    dusk_astronomical 在天空完全变暗的那一刻执行;正式地,当太阳低于地平线18度时。

    所有太阳事件都是使用UTC计算的,因此不受时区设置的影响。

    在极地地区,太阳不一定每天都会升起或落下。调度程序能够处理这些情况(即,sunrise在太阳不升起的一天不会发生事件)。一个例外是solar_noon,正式定义为太阳经过天子午线的那一刻,即使太阳在地平线以下,它也会每天发生。

    暮光定义为黎明到日出之间的时间;在日落和黄昏之间。您可以使用上面列表中的适当事件,根据您对暮光的定义(民用,航海或天文),以及是否要在暮光的开始或结束时,根据“暮光”安排事件。 。

    请参阅celery.schedules.solar以获取更多文档。

    启动调度

    要启动celery beat服务:

    $ celery -A proj beat
    

    您也可以通过启用workers 选项将beat嵌入到worker中,-B如果您永远不会运行一个以上的worker节点,这很方便,但是它并不常用,因此不建议用于生产环境:

    $ celery -A proj worker -B
    

    Beat需要将任务的最后运行时间存储在本地数据库文件(默认情况下命名为celerybeat-schedule)中,因此它需要访问权限才能在当前目录中进行写操作,或者可以为此文件指定一个自定义位置:

    $ celery -A proj beat -s /home/celery/var/run/celerybeat-schedule
    

    注意

    要守护节拍,请参见守护进程

    使用自定义调度类

    可以在命令行(--scheduler参数)上指定自定义调度程序类 。

    默认调度程序是celery.beat.PersistentScheduler,它仅跟踪本地shelve 数据库文件中的最后运行时间。

    还有django-celery-beat扩展,可将日程表存储在Django数据库中,并提供一个方便的管理界面来在运行时管理定期任务。

    要安装和使用此扩展:

    1. 使用pip安装软件包:

      $ pip install django-celery-beat
      
    2. django_celery_beat模块添加到INSTALLED_APPSDjango项目中settings.py

      INSTALLED_APPS = (
          ...,
          'django_celery_beat',
      )
      

      请注意,模块名称中没有短划线,只有下划线。

    3. 应用Django数据库迁移,以便创建必要的表:

      $ python manage.py migrate
      
    4. 使用调度程序启动celery beat服务django_celery_beat.schedulers:DatabaseScheduler

      $ celery -A proj beat -l info --scheduler django_celery_beat.schedulers:DatabaseScheduler
      

      注意:您也可以beat_scheduler直接将其添加为设置。

    5. 访问Django-Admin界面以设置一些定期任务。

  • 相关阅读:
    1.在虚拟机中安装Linux中的CentOS7系统
    Mysql的跨服务器 关联查询--Federated引擎
    mysql 时间格式转换
    mysql 查询当天、本周,本月,上一个月的数据
    mybatis执行批量更新数据
    JSTL 递增序号
    mybaits 新增数据返回id
    第一部分软件测试综述——软件测试背景【软件测试】(美)Ron Patton中文电子版
    测试真的是一个无聊又没前途的岗位吗?是吗?不是吗?
    碎片化时间,偷偷变牛逼!2020全栈软件测试工程师修炼手册
  • 原文地址:https://www.cnblogs.com/remixnameless/p/13027836.html
Copyright © 2020-2023  润新知