首页 文章

Django - 设置预定的工作?

提问于
浏览
438

我一直在使用Django开发一个Web应用程序,我很好奇是否有办法安排作业定期运行 .

基本上我只想运行数据库并自动定期进行一些计算/更新,但我似乎无法找到任何关于这样做的文档 .

有谁知道如何设置它?

澄清:我知道我可以设置一个 cron 工作来完成这项工作,但我希望人们能够自己部署这个应用程序,而无需进行太多配置(最好是零) .

我已经考虑通过简单地检查自上次将请求发送到网站后是否应该运行作业来“追溯”触发这些操作,但我希望有一些更清洁的东西 .

21 回答

  • 1

    一个更现代的解决方案(与Celery相比)是Django Q:https://django-q.readthedocs.io/en/latest/index.html

    它有很好的文档,很容易理解 . Windows支持缺乏,因为Windows不支持进程分支 . 但是如果使用Windows for Linux子系统创建开发环境,它可以正常工作 .

  • 9

    今天我和你的问题有类似的东西 .

    我不想让它由服务器trhough cron处理(并且大多数libs最终只是cron帮助程序) .

    所以我创建了一个调度模块并将其附加到 init .

    这不是最好的方法,但它帮助我将所有代码放在一个地方,并使其执行与主应用程序相关 .

  • 124

    你一定要看看django-q!它不需要额外的配置,并且很可能需要处理商业项目中的任何 生产环境 问题 .

    它积极开发并与django,django ORM,mongo,redis很好地集成 . 这是我的配置:

    # django-q
    # -------------------------------------------------------------------------
    # See: http://django-q.readthedocs.io/en/latest/configure.html
    Q_CLUSTER = {
        # Match recommended settings from docs.
        'name': 'DjangoORM',
        'workers': 4,
        'queue_limit': 50,
        'bulk': 10,
        'orm': 'default',
    
    # Custom Settings
    # ---------------
    # Limit the amount of successful tasks saved to Django.
    'save_limit': 10000,
    
    # See https://github.com/Koed00/django-q/issues/110.
    'catch_up': False,
    
    # Number of seconds a worker can spend on a task before it's terminated.
    'timeout': 60 * 5,
    
    # Number of seconds a broker will wait for a cluster to finish a task before presenting it again. This needs to be
    # longer than `timeout`, otherwise the same task will be processed multiple times.
    'retry': 60 * 6,
    
    # Whether to force all async() calls to be run with sync=True (making them synchronous).
    'sync': False,
    
    # Redirect worker exceptions directly to Sentry error reporter.
    'error_reporter': {
        'sentry': RAVEN_CONFIG,
    },
    }
    
  • 32

    看看Django Poor Man的Cron,它是一个Django应用程序,它使用spambots,搜索引擎索引机器人等,以大约定期的间隔运行计划任务

    见:http://code.google.com/p/django-poormanscron/

  • 6

    将以下内容放在cron.py文件的顶部:

    #!/usr/bin/python
    import os, sys
    sys.path.append('/path/to/') # the parent directory of the project
    sys.path.append('/path/to/project') # these lines only needed if not on path
    os.environ['DJANGO_SETTINGS_MODULE'] = 'myproj.settings'
    
    # imports and code below
    
  • 2

    我只是想到了这个相当简单的解决方案:

    • 定义视图函数 do_work(req, param) 就像使用任何其他视图一样,使用URL映射,返回HttpResponse等等 .

    • 使用您的计时首选项(或使用Windows中的AT或计划任务)设置一个cron作业,该作业运行 curl http://localhost/your/mapped/url?param=value .

    您可以添加参数,但只需向URL添加参数即可 .

    告诉我你们的想法 .

    [Update] 我现在使用django-extensions而不是curl的runjob命令 .

    我的cron看起来像这样:

    @hourly python /path/to/project/manage.py runjobs hourly
    

    ......等等每日,每月等等 . 您也可以将其设置为运行特定作业 .

    我发现它更容易管理,更清洁 . 不需要将URL映射到视图 . 只需定义你的工作类和crontab就可以了 .

  • 9

    我前一段时间有完全相同的要求,最后用APSchedulerUser Guide)解决了它

    它使调度作业变得非常简单,并使其与基于请求的某些代码的执行保持独立 . 以下是我在代码中使用的一个简单示例 .

    from apscheduler.schedulers.background import BackgroundScheduler
    
    scheduler = BackgroundScheduler()
    job = None
    
    def tick():
        print('One tick!')\
    
    def start_job():
        global job
        job = scheduler.add_job(tick, 'interval', seconds=3600)
        try:
            scheduler.start()
        except:
            pass
    

    希望这有助于某人!

  • 6

    我不确定这对任何人都有用,因为我必须提供系统的其他用户来安排作业,而不让他们访问实际的服务器(windows)任务计划程序,我创建了这个可重用的应用程序 .

    请注意,用户可以访问服务器上的一个共享文件夹,在该文件夹中可以创建所需的命令/任务/ .bat文件 . 然后可以使用此应用程序安排此任务 .

    应用名称是Django_Windows_Scheduler

    截图:

  • 43

    Celery是一个基于AMQP(RabbitMQ)构建的分布式任务队列 . 它还以类似cron的方式处理周期性任务(参见periodic tasks) . 根据您的应用程序,它可能值得一个雄鹅 .

    使用django(docs)很容易设置Celery,并且在停机的情况下,定期任务实际上会跳过错过的任务 . Celery还具有内置的重试机制,以防任务失败 .

  • 1

    RabbitMQ和Celery比Cron具有更多的功能和任务处理能力 . 如果任务失败不是问题,并且您认为您将在下一次调用中处理损坏的任务,那么Cron就足够了 .

    Celery&AMQP将允许您处理损坏的任务,它将由另一个工作人员再次执行(Celery工作人员监听下一个要处理的任务),直到达到任务的 max_retries 属性 . 您甚至可以在失败时调用任务,例如记录失败,或者在达到 max_retries 后向管理员发送电子邮件 .

    当您需要扩展应用程序时,您可以分发Celery和AMQP服务器 .

  • 22

    有趣的新插件Django应用程序:django-chronograph

    你只需添加一个作为计时器的cron条目,你就可以在脚本中运行一个非常好的Django管理界面 .

  • 1

    虽然不是Django的一部分,Airflow是一个更新的项目(截至2016年),对任务管理很有用 .

    Airflow是一个工作流程自动化和调度系统,可用于创作和管理数据管道 . 基于Web的UI为开发人员提供了一系列用于管理和查看这些管道的选项 .

    Airflow是用Python编写的,使用Flask构建 .

    Airflow由Airbnb的Maxime Beauchemin创建,并于2015年 Spring 季开源 . 它于2016年冬季加入了Apache Software Foundation的孵化计划 . 这是Git project page和一些background information .

  • 14

    我采用的一个解决方案是这样做:

    1)创建custom management command,例如

    python manage.py my_cool_command
    

    2)使用 cron (在Linux上)或 at (在Windows上)在所需的时间运行我的命令 .

    这是一个简单的解决方案,不需要安装繁重的AMQP堆栈 . 然而,使用像其他答案中提到的Celery这样的东西有很好的优势 . 特别是,使用Celery,不必将应用程序逻辑扩展到crontab文件中 . 然而,对于中小型应用程序而言,cron解决方案非常适用,并且您不需要很多外部依赖项 .

    编辑:

    在Windows的更高版本中,对于Windows 8,Server 2012及更高版本,不推荐使用 at 命令 . 您可以使用 schtasks.exe 进行相同的使用 .

  • 314

    Brian Neal 's suggestion of running management commands via cron works well, but if you'正在寻找一些更强大的东西(但不像芹菜那么精致)我会调查像Kronos这样的库:

    # app/cron.py
    
    import kronos
    
    @kronos.register('0 * * * *')
    def task():
        pass
    
  • 0

    如果您想要比Celery更多 reliable ,请尝试 TaskHawk ,它 Build 在 AWS SQS/SNS 之上 .

    参考:http://taskhawk.readthedocs.io

  • 6

    如果您使用的是标准POSIX OS,则使用cron .

    如果您使用的是Windows,则使用at .

    写一个Django管理命令

    • 找出他们所处的平台 .

    • 为用户执行相应的"AT"命令, or 为您的用户更新crontab .

  • 1

    我用芹菜来创造我的周期性任务 . 首先,您需要按如下方式安装它:

    pip install django-celery
    

    不要忘记在你的设置中注册 django-celery 然后你可以做这样的事情:

    from celery import task
    from celery.decorators import periodic_task
    from celery.task.schedules import crontab
    from celery.utils.log import get_task_logger
    @periodic_task(run_every=crontab(minute="0", hour="23"))
    def do_every_midnight():
     #your code
    
  • 2

    我们开源了我认为的结构化应用程序 . 上面Brian的解决方案也提到了 . 会喜欢任何/所有反馈!

    https://github.com/tivix/django-cron

    它带有一个管理命令:

    ./manage.py runcrons
    

    这样做了 . 每个cron都被建模为一个类(所以它的所有OO),每个cron以不同的频率运行,我们确保相同的cron类型不会并行运行(如果crons本身需要比它们的频率更长的运行时间!)

    谢谢!

  • 4

    我个人使用cron,但django-extensionsJobs Scheduling部分看起来很有趣 .

  • 8

    是的,上面的方法太棒了 . 我尝试了其中一些 . 最后,我发现了一个这样的方法:

    from threading import Timer
    
        def sync():
    
            do something...
    
            sync_timer = Timer(self.interval, sync, ())
            sync_timer.start()
    

    就像 Recursive 一样 .

    好的,我希望这种方法能满足您的要求 . :)

  • 6

    在代码的一部分之后,我可以编写任何类似于我的views.py :)

    #######################################
    import os,sys
    sys.path.append('/home/administrator/development/store')
    os.environ['DJANGO_SETTINGS_MODULE']='store.settings'
    from django.core.management impor setup_environ
    from store import settings
    setup_environ(settings)
    #######################################
    

    来自http://www.cotellese.net/2007/09/27/running-external-scripts-against-django-models/

相关问题