我有几个通过节拍执行的芹菜任务。在开发中,我使用了一个命令来设置它,例如:
celery worker -A my_tasks -n XXXXX@%h -Q for_mytasks -c 1 -E -l INFO -B -s ./config/celerybeat-schedule --pidfile ./config/celerybeat.pid
在迁移到生产环境时,我将其插入到激活我的 venv 的脚本中,设置 PYTHONPATH,删除旧的节拍文件,cd 到正确的目录,然后运行芹菜。这绝对没问题。但是,在生产中,我想将工作线程与节拍调度程序分开,例如:
celery worker -A my_tasks -n XXXXX@%h -Q for_mytasks -c 1 -E -l INFO -f ./logs/celeryworker.log
celery beat -A my_tasks -s ./config/celerybeat-schedule --pidfile ./config/celerybeat.pid -l INFO -f ./logs/celerybeat.log
现在,当放入相关的bash脚本中时,这一切都可以正常工作。但是,我需要在服务器启动时运行这些。我遇到了几个问题:
1(在crontab -e中@reboot my_script
不起作用。我必须插入一个延迟以允许 rabbitmq 完全启动,即@reboot sleep 60 && my_script
.现在这对我来说似乎有点"混乱",但我可以忍受它。
2(celery worker
需要几秒钟才能完成celery beat
才能正常运行。我尝试了各种 cron 指令来完成在 worker 成功执行但无法运行节拍后运行的节拍。我目前在 crontab 中的解决方案是这样的:
@reboot sleep 60 && my_script_worker
@reboot sleep 120 && my_script_beat
所以基本上,ubuntu 启动,等待 60 秒并运行芹菜工人,然后再等待 60 秒,然后再运行芹菜节拍。这工作正常,但对我来说似乎更"混乱"。在理想的世界中,我想标记 rabbitmq 何时准备好运行 worker 时,然后在 worker 成功执行时标记,以便我可以运行 beat。
我的问题是:有没有人遇到过这个问题,如果是这样,他们是否有更优雅的方式来启动芹菜工人并在服务器重新启动时击败?
编辑: 24/09/2019 感谢DejanLekic和Greenev
我花了一些时间从 cron 转换为 systemd。是的,我完全同意这是一个更强大的解决方案。我的芹菜工人和节拍现在由 systemd 在重新启动时作为服务启动。
对于尝试此操作的人,我有一个提示,芹菜文档中未提及。模板节拍命令将在您的工作目录中创建一个名为celerybeat-schedule
的"芹菜节拍数据库"文件。如果重新启动 beat 服务,此文件将导致生成似乎不符合实际芹菜计划的虚假芹菜任务。解决方案是每次启动 beat 服务时删除此文件。如果 pid 文件存在,我也会删除它。我通过在节拍服务中添加 2 个 ExecStartPre 和一个 -s 选项来做到这一点:
ExecStartPre=/bin/sh -c 'rm -f ${CELERYBEAT_DB_FILE}'
ExecStartPre=/bin/sh -c 'rm -f ${CELERYBEAT_PID_FILE}'
ExecStart=/bin/sh -c '${CELERY_BIN} beat
-A ${CELERY_APP} --pidfile=${CELERYBEAT_PID_FILE}
-s ${CELERYBEAT_DB_FILE}
--logfile=${CELERYBEAT_LOG_FILE} --loglevel=${CELERYD_LOG_LEVEL}'
谢谢大家。
为了守护芹菜工作程序,我们正在使用systemd
,因此工作线程和节拍可以作为单独的服务运行,并配置为在服务器重新启动时启动,只需将这些服务enabled
您真正想要的是将 Celery 节拍进程作为 systemd 或 SysV 服务运行。Celery 文档的守护程序部分对此进行了深入描述。事实上,工作进程也是如此。
为什么? - 与涉及带有@reboot行的 crontab 的解决方案不同,例如 systemd 可以检查服务的运行状况并在需要时重新启动它。Linux 机器上的所有 Linux 服务都是以这种方式启动的,因为它是为这个特定目的而制作的。