我一直在使用Django开发一个Web应用程序,我很好奇是否有办法安排作业定期运行.
基本上我只是想通过数据库运行并自动定期进行一些计算/更新,但我似乎无法找到任何关于这样做的文档.
有谁知道如何设置它?
澄清:我知道我可以设置一个cron
工作来做这件事,但我很好奇Django中是否有一些提供此功能的功能.我希望人们能够自己部署这个应用程序而无需进行太多配置(最好是零).
我已经考虑通过简单地检查自上次将请求发送到网站后是否应该运行作业来"追溯"触发这些操作,但我希望有一些更清洁的东西.
我采用的一个解决方案是:
1)创建自定义管理命令,例如
python manage.py my_cool_command
2)使用cron
(在Linux上)或at
(在Windows上)在所需的时间运行我的命令.
这是一个简单的解决方案,不需要安装繁重的AMQP堆栈.然而,使用像其他答案中提到的Celery这样的东西有很好的优势.特别是,使用Celery,不必将应用程序逻辑扩展到crontab文件中.但是,cron解决方案适用于中小型应用程序,并且您不需要大量外部依赖项.
编辑:
在Windows的更高版本中,at
不推荐使用Windows 8,Server 2012及更高版本的命令.您可以使用schtasks.exe
相同的用途.
Celery是一个基于AMQP(RabbitMQ)的分布式任务队列.它还以类似cron的方式处理周期性任务(请参阅定期任务).根据您的应用程序,它可能值得一个雄鹅.
使用django(docs)很容易设置Celery ,并且在停机的情况下,定期任务实际上会跳过错过的任务.Celery还具有内置的重试机制,以防任务失败.
我们开源了我认为的结构化应用程序.上面Brian的解决方案也提到了.会喜欢任何/所有反馈!
https://github.com/tivix/django-cron
它带有一个管理命令:
./manage.py runcrons
这样做了.每个cron都被建模为一个类(因此它的所有OO),每个cron以不同的频率运行,我们确保相同的cron类型不会并行运行(如果crons本身需要比它们的频率更长的运行时间!)
谢谢!
如果您使用的是标准POSIX OS,则使用cron.
如果您使用的是Windows,则使用at.
写一个Django管理命令
找出他们所处的平台.
为您的用户执行适当的"AT"命令,或为您的用户更新crontab.
有趣的新插件Django app:django-计时码表
你只需添加一个作为计时器的cron条目,你就可以在脚本中运行一个非常好的Django管理界面.
看看Django Poor Man的Cron,这是一个Django应用程序,它使用spambots,搜索引擎索引机器人等,大约定期运行计划任务
请参阅:http://code.google.com/p/django-poormanscron/
Brian Neal关于通过cron运行管理命令的建议很有效,但是如果你正在寻找一些更强大的东西(但不像Celery那么精细),我会调查像Kronos这样的库:
# app/cron.py import kronos @kronos.register('0 * * * *') def task(): pass
RabbitMQ和Celery比Cron具有更多的功能和任务处理能力.如果任务失败不是问题,并且您认为您将在下一次调用中处理损坏的任务,那么Cron就足够了.
Celery和AMQP将允许您处理损坏的任务,并且它将由另一个工作人员(Celery工作人员监听下一个要处理的任务)再次执行,直到max_retries
达到任务的属性.您甚至可以在失败时调用任务,例如记录失败,或者一旦max_retries
到达就向管理员发送电子邮件.
当您需要扩展应用程序时,您可以分发Celery和AMQP服务器.
我个人使用cron,但是django-extensions的Jobs Scheduling部分看起来很有趣.
我刚才有完全相同的要求,最后用APScheduler解决了这个问题(用户指南)
它使调度作业变得非常简单,并使其与基于请求的某些代码执行保持独立.以下是我在代码中使用的一个简单示例.
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
希望这有助于某人!
虽然不是Django的一部分,但Airflow是一个更新的项目(截至2016年),对任务管理很有用.
Airflow是一个工作流程自动化和调度系统,可用于创建和管理数据管道.基于Web的UI为开发人员提供了一系列用于管理和查看这些管道的选项.
Airflow是用Python编写的,使用Flask构建.
Airflow由Airimeb的Maxime Beauchemin创建,并于2015年春季开源.它于2016年冬季加入了Apache Software Foundation的孵化计划.这是Git项目页面和一些附加背景信息.
将以下内容放在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
我只是想到了这个相当简单的解决方案:
像使用任何其他视图一样定义视图函数do_work(req,param),使用URL映射,返回HttpResponse等等.
使用您的计时首选项(或使用Windows中的AT或计划任务)设置一个cron作业,该计划运行curl http:// localhost/your/mapped/url?param = value.
您可以添加参数,但只需向URL添加参数即可.
告诉我你们的想法.
[更新]我现在使用django-extensions而不是curl的runjob命令.
我的cron看起来像这样:
@hourly python /path/to/project/manage.py runjobs hourly
......等等每日,每月等等.您也可以将其设置为运行特定作业.
我发现它更容易管理,更清洁.不需要将URL映射到视图.只需定义你的工作类和crontab就可以了.