【问题标题】:Django Celery Scheduling a manage.py commandDjango Celery 调度 manage.py 命令
【发布时间】:2013-07-13 21:40:54
【问题描述】:

我需要使用以下命令按计划更新 solr 索引:

(env)$ ./manage.py update_index

我查看了 Celery 文档并找到了有关调度的信息,但无法找到一种方法来按计划和在 virtualenv 中运行 django 管理命令。这会更好地在普通的 cron 上运行吗?如果是这样,我将如何在 virtualenv 中运行它?有人有这方面的经验吗?

感谢您的帮助!

【问题讨论】:

    标签: django celery django-celery celerybeat


    【解决方案1】:

    Django Celery 任务调度 项目结构

    [appname]/
    ├── [appname]/
    │   ├── __init__.py
    │   ├── settings.py
    │   ├── urls.py
    │   ├── celery.py
    │   └── wsgi.py
    ├── [project1]/
    │   ├── __init__.py
    │   ├── tasks.py
    │   
    └── manage.py
    

    settings.py 文件中添加以下配置:

    STATIC_URL = '/static/'
    BROKER_URL = 'redis://localhost:6379/0'
    CELERY_ACCEPT_CONTENT = ['application/json']
    CELERY_TASK_SERIALIZER = 'json'
    CELERY_RESULT_SERIALIZER = 'json'
    CELERY_RESULT_BACKEND = 'redis'
    from celery.schedules import crontab
    CELERY_TIMEZONE = 'UTC'
    

    celery.py:保存 celery 任务调度器

    from __future__ import absolute_import, unicode_literals
    import os
    from celery import Celery
    import django
    # set the default Django settings module for the 'celery' program.
    os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'appname.settings')
    from django.conf import settings
    app = Celery('appname')
    app.config_from_object('django.conf:settings')
    app.autodiscover_tasks()
    @app.task(bind=True)
    def debug_task(self):
        print('Request: {0!r}'.format(self.request))
    **#scheduler**
    app.conf.beat_schedule = {
        'add-every-30-seconds': {
            'task': 'project1.tasks.cleanup',
            'schedule': 30.0,
            'args': ()
        },
    }
    app.conf.timezone = 'UTC'
    

    init.py

    from __future__ import absolute_import, unicode_literals
    
    # This will make sure the app is always imported when
    # Django starts so that shared_task will use this app.
    from .celery import app as celery_app
    
    __all__ = ['celery_app']
    

    tasks.py 来自 project1

    from celery import shared_task
    import celery
    import time
    from django.core import management
    @celery.task#(name='cleanup')
    def cleanup():
        try:
            print ("in celery module")
            """Cleanup expired sessions by using Django management command."""
            management.call_command("clearsessions", verbosity=0)
            #PUT MANAGEMENT COMMAND HERE
            return "success"
        except:
            print(e)
    

    任务将在每 30 秒后运行一次

    windows 要求:

    1. redis 服务器应该正在运行
    2. celery worker 和 celery beat 应该正在运行 在不同的终端上运行以下每个命令

      celery -A appname worker -l info

      celery -A appname beat -l info

    对 Linux 的要求:

    1. redis 服务器应该正在运行
    2. celery worker 和 celery beat 应该正在运行 celery beat 和 worker 可以在同一台服务器上启动

      celery -A appname worker -l info -B

    @tzenderman 如果我遗漏了什么,请告诉我。 对我来说,这很好用

    【讨论】:

      【解决方案2】:

      要从 cron 作业定期运行命令,只需将命令包装在加载 virtualenv 的 bash 脚本中。例如,下面是我们运行 manage.py 命令的方法:

      django_cmd.sh:

      #!/bin/bash
      
      cd /var/www/website/
      source venv/bin/activate
      /var/www/website/manage.py $1 --settings=$2
      

      Crontab:

      MAILTO=webmaster@website.com
      SETTINGSMODULE=website.settings_prod
      5 * * * * /var/www/website/django_cmd.sh update_index $SETTINGSMODULE >> /dev/null
      0 10 * * * /var/www/website/django_cmd.sh update_accounts $SETTINGSMODULE 
      

      【讨论】:

      • 我最终这样做了,因为我无法让面料 + 芹菜很好地发挥作用。谢谢!
      【解决方案3】:

      我实际上找到了一种使用织物+芹菜的好方法,我现在正在努力:

      在 app/tasks.py 中,使用你需要的 manage.py 命令创建一个 fabric 函数,然后用 @periodic_task 装饰它,将它添加到你的 celery 日程表中,应该可以了。

      更新:我无法实际使用 Fabric + Celery,因为在模块中使用 fabric 导致它被识别为结构文件,并且文件中的 celery 调用不起作用。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-05-21
        • 1970-01-01
        • 2015-04-11
        • 2011-05-13
        • 2014-01-17
        • 2019-06-11
        • 2019-06-17
        • 2020-09-16
        相关资源
        最近更新 更多