定期任务
我们经常需要在django项目中定期运行任务,在此芹菜可以通过芹菜节拍满足我们的需求,芹菜节拍不过是一个调度程序,该调度程序定期执行目标,并且可以隐式和显式定义。
请确保一次运行一个计划程序,否则一次将导致重复的任务
根据您所在的时区,在settings.py中设置时区,我们已经在本教程的前面进行了设置。
timezone = ‘Europe/London’
现在,我们可以通过两种方式创建定期任务,或者通过在celery.py中手动添加调度程序的代码,或者通过安装django-celery-beat软件包来使我们可以在Django Admin中创建调度程序。
1.手动编写计划程序
在celery.py文件中添加以下计划配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
celery_project/celery.py app.conf.beat_schedule = { #name of the scheduler 'add-every-2-seconds': { # task name which we have created in tasks.py 'task': 'add_2_numbers', # set the period of running 'schedule': 2.0, # set the args 'args': (16, 16) }, #name of the scheduler 'print-name-every-5-seconds': { # task name which we have created in tasks.py 'task': 'print_msg_with_name', # set the period of running 'schedule': 5.0, # set the args 'args': ("DjangoPY", ) }, } |
打开NEW终端并运行以下命令
1 |
$ celery -A <project name> beat -l info |
确保您在单独的终端中运行工作进程
1 |
celery -A <your project name> worker -l info |
您将在开始celery beat过程的终端中获得输出
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
celery beat v4.1.0 (latentcall) is starting. __ - ... __ - _ LocalTime -> 2018-02-17 09:56:30 Configuration -> . broker -> redis://localhost:6379// . loader -> celery.loaders.app.AppLoader . scheduler -> celery.beat.PersistentScheduler . db -> celerybeat-schedule . logfile -> [stderr]@%INFO . maxinterval -> 5.00 minutes (300s) [2018-02-17 09:56:30,268: INFO/MainProcess] beat: Starting... [2018-02-17 09:56:36,365: INFO/MainProcess] Scheduler: Sending due task add-every-2-seconds (add_2_numbers) [2018-02-17 09:56:38,365: INFO/MainProcess] Scheduler: Sending due task add-every-2-seconds (add_2_numbers) [2018-02-17 09:56:39,367: INFO/MainProcess] Scheduler: Sending due task print-name-every-5-seconds (print_msg_with_name) [2018-02-17 09:56:40,365: INFO/MainProcess] Scheduler: Sending due task add-every-2-seconds (add_2_numbers) [2018-02-17 09:56:42,365: INFO/MainProcess] Scheduler: Sending due task add-every-2-seconds (add_2_numbers) ... |
现在,如果您查看工作进程终端,您会发现任务正在定期运行!
1 2 3 4 5 6 7 8 |
[2018-02-17 09:56:36,371: WARNING/ForkPoolWorker-1] Add function has been called!! with params 16, 16 [2018-02-17 09:56:36,464: INFO/ForkPoolWorker-1] Task add_2_numbers[7e9f9ff5-4b01-42d3-b301-99a3b078484b] succeeded in 0.09404212199842732s: 32 [2018-02-17 09:56:38,368: INFO/MainProcess] Received task: add_2_numbers[097e8b56-7090-4561-9686-77d7aae6e2d6] [2018-02-17 09:56:38,369: WARNING/ForkPoolWorker-2] Add function has been called!! with params 16, 16 [2018-02-17 09:56:38,453: INFO/ForkPoolWorker-2] Task add_2_numbers[097e8b56-7090-4561-9686-77d7aae6e2d6] succeeded in 0.08399435899991659s: 32 [2018-02-17 09:56:39,371: INFO/MainProcess] Received task: print_msg_with_name[2b56d4a2-a358-4186-b849-66342d7635dc] [2018-02-17 09:56:39,372: WARNING/ForkPoolWorker-1] Celery is working!! DjangoPY have implemented it correctly. [2018-02-17 09:56:39,456: INFO/ForkPoolWorker-1] Task print_msg_with_name[2b56d4a2-a358-4186-b849-66342d7635dc] succeeded in 0.08378831899972283s: None |
2.使用django-celery-beat
现在让我们用django-celery-beat做同样的事情
1.安装django-celery-beat
1 |
$ pip install django-celery-beat |
2.添加到已安装的应用程序中
将django_celery_beat模块添加到Django项目的settings.py中的INSTALLED_APPS中:
1 2 3 4 |
INSTALLED_APPS = [ ... 'django_celery_beat', ] |
3. Run the django migrations
1 |
$ python manage.py migrate |
注意:与时区相关的设置更改时,数据库调度程序不会重置,因此您必须手动执行此操作:
1 2 3 |
$ python manage.py shell >>> from django_celery_beat.models import PeriodicTask >>> PeriodicTask.objects.update(last_run_at=None) |
现在转到Django Admin并创建一个“定期任务”,如下所示
选择任何名称,然后选择已创建的任务,并根据需要创建一个Crontab。 请从此处参考指南或Crontab的一些示例。
使用–scheduler在新终端中运行celery过程.
1 |
$ celery -A <project name> beat -l info --scheduler django_celery_beat.schedulers:DatabaseScheduler |
确保您在带有django服务器和celery beat进程的单独终端中运行了工作进程
1 |
celery -A <your project name> worker -l info |
在两个终端中检查输出日志,并在各个终端中检查日志
在生产上运行
现在,celery 在本地运行良好,最后我们需要照顾生产。 这里出现一个问题,因为我们需要同时运行流程(节拍和工作程序)以保持celery 正常工作,因此我们如何在生产服务器中始终一起运行这些流程终端。
因此,Supervisor在这里派上用场,可帮助分别运行两个实例。
Supervisor是一个客户端/服务器系统,允许其用户控制并使其保持在任何类似Unix的操作系统中的进程。 因此,我们可以将其用于运行celery 过程。
这是Supervisor的文档(http://supervisord.org/)