【问题标题】:How to properly daemonize celerybeat with django?如何用 django 正确地守护 celerybeat?
【发布时间】:2016-02-25 21:46:01
【问题描述】:

有几个问题与此类似,但都没有正确的解决方案,也没有描述完全相同的问题。

如果我自己从命令行启动 celery,定期任务可以很好地配合我的配置,如下所示:

celery --app=proj.mycelery worker -B

问题是当我尝试守护 celery 时。 关注this tutorial 后,我启动服务:

sudo /etc/init.d/celerybeat start

它似乎开始正常,但设置为每 5 秒执行一次的周期性任务没有发生。

这些是我在 Django 的 settings.py 中的 celery 设置

BROKER_URL = 'amqp://guest:guest@localhost//'
CELERY_ACCEPT_CONTENT = ['json']
CELERY_TASK_SERIALIZER = 'json'
CELERY_RESULT_SERIALIZER = 'json'

这是我的 /etc/default/celerybeat 配置:

# Absolute or relative path to the 'celery' command:
CELERY_BIN="/home/burzum/.pyenv/versions/old_django/bin/celery"

# App instance to use
CELERY_APP="proj.mycelery"

# Where to chdir at start.
CELERYBEAT_CHDIR="/home/burzum/repos/proj/"

# Extra arguments to celerybeat
CELERYBEAT_OPTS="--schedule=/var/run/celery/celerybeat-schedule"

export DJANGO_SETTINGS_MODULE="proj.settings"

CELERYD_CHDIR="/home/burzum/repos/proj"

/etc/init.d/celerybeat 文件与教程 (this one) 中的相同。我只是在开头添加了以下行:

export PYTHONPATH='/home/burzum/repos'

/var/log/celery/beat.log的输出为:

[2015-11-23 09:15:18,304: INFO/MainProcess] beat: Starting...
[2015-11-23 09:15:23,307: INFO/MainProcess] Scheduler: Sending due task reports.tasks.test_periodic_task (reports.tasks.test_periodic_task)
[2015-11-23 09:15:28,310: INFO/MainProcess] Scheduler: Sending due task reports.tasks.test_periodic_task (reports.tasks.test_periodic_task)

所以,看起来周期性任务正在被调用,但没有发生任何事情。

sudo /etc/init.d/celerybeat status的输出是:

celery init v10.1.
Using configuration: , /etc/default/celerybeat
celerybeat (pid 11696) is up...

使用sudo sh -x /etc/init.d/celerybeat start启动服务的输出是:

+ VERSION=10.1
+ export PYTHONPATH=/home/burzum/repos
+ echo celery init v10.1.
celery init v10.1.
+ id -u
+ [ 0 -ne 0 ]
+ [ -L /etc/init.d/celerybeat ]
+ SCRIPT_FILE=/etc/init.d/celerybeat
+ basename /etc/init.d/celerybeat
+ SCRIPT_NAME=celerybeat
+ scripts=
+ test -f /etc/default/celeryd
+ EXTRA_CONFIG=/etc/default/celerybeat
+ test -f /etc/default/celerybeat
+ scripts=, /etc/default/celerybeat
+ _config_sanity /etc/default/celerybeat
+ local path=/etc/default/celerybeat
+ ls -ld /etc/default/celerybeat
+ awk {print $3}
+ local owner=root
+ ls -ld /etc/default/celerybeat+ 
cut -b 6
+ local iwgrp=-
+ ls -ld+  /etc/default/celerybeat
cut -b 9
+ local iwoth=-
+ id -u root
+ [ 0 != 0 ]
+ [ - != - ]
+ [ - != - ]
+ . /etc/default/celerybeat
+ CELERY_BIN=/home/burzum/.pyenv/versions/old_django/bin/celery
+ CELERY_APP=proj.mycelery
+ CELERYBEAT_CHDIR=/home/burzum/repos/proj/
+ CELERYBEAT_OPTS=--schedule=/var/run/celery/celerybeat-schedule
+ export DJANGO_SETTINGS_MODULE=proj.settings
+ CELERYD_CHDIR=/home/burzum/repos/proj
+ echo Using configuration: , /etc/default/celerybeat
Using configuration: , /etc/default/celerybeat
+ CELERY_BIN=/home/burzum/.pyenv/versions/old_django/bin/celery
+ DEFAULT_USER=celery
+ DEFAULT_PID_FILE=/var/run/celery/beat.pid
+ DEFAULT_LOG_FILE=/var/log/celery/beat.log
+ DEFAULT_LOG_LEVEL=INFO
+ DEFAULT_CELERYBEAT=/home/burzum/.pyenv/versions/old_django/bin/celery beat
+ CELERYBEAT=/home/burzum/.pyenv/versions/old_django/bin/celery beat
+ CELERYBEAT_LOG_LEVEL=INFO
+ CELERY_APP_ARG=
+ [ ! -z proj.mycelery ]
+ CELERY_APP_ARG=--app=proj.mycelery
+ CELERYBEAT_USER=celery
+ CELERY_CREATE_DIRS=0
+ CELERY_CREATE_RUNDIR=0
+ CELERY_CREATE_LOGDIR=0
+ [ -z  ]
+ CELERYBEAT_PID_FILE=/var/run/celery/beat.pid
+ CELERY_CREATE_RUNDIR=1
+ [ -z  ]
+ CELERYBEAT_LOG_FILE=/var/log/celery/beat.log
+ CELERY_CREATE_LOGDIR=1
+ export CELERY_LOADER
+ CELERYBEAT_OPTS=--schedule=/var/run/celery/celerybeat-schedule -f /var/log/celery/beat.log -l INFO
+ [ -n  ]
+ dirname /var/log/celery/beat.log
+ CELERYBEAT_LOG_DIR=/var/log/celery
+ dirname /var/run/celery/beat.pid
+ CELERYBEAT_PID_DIR=/var/run/celery
+ CELERYBEAT_CHDIR=/home/burzum/repos/proj/
+ [ -n /home/burzum/repos/proj/ ]
+ DAEMON_OPTS= --workdir=/home/burzum/repos/proj/
+ export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/sbin:/sbin
+ check_dev_null
+ [ ! -c /dev/null ]
+ check_paths
+ [ 1 -eq 1 ]
+ create_default_dir /var/log/celery
+ [ ! -d /var/log/celery ]
+ [ 1 -eq 1 ]
+ create_default_dir /var/run/celery
+ [ ! -d /var/run/celery ]
+ start_beat
+ echo Starting celerybeat...
Starting celerybeat...
+ _chuid --app=proj.mycelery --schedule=/var/run/celery/celerybeat-schedule -f /var/log/celery/beat.log -l INFO --workdir=/home/burzum/repos/proj/ --detach --pidfile=/var/run/celery/beat.pid
+ su celery -c /home/burzum/.pyenv/versions/old_django/bin/celery beat --app=proj.mycelery --schedule=/var/run/celery/celerybeat-schedule -f /var/log/celery/beat.log -l INFO --workdir=/home/burzum/repos/proj/ --detach --pidfile=/var/run/celery/beat.pid
+ exit 0

【问题讨论】:

  • 您是否检查过您的 celery 实例是否真正侦听了正确的代理队列并接收到消息。即使代理不正确,任务也会正确加载。我会假设您的任务已加载,但消息没有通过。同一任务队列中存在多个 celery 实例可能是一个原因。
  • 您对如何检查 celery 实例是否正在侦听正确的代理有什么建议吗?我对此不是很有经验。
  • 你可以试试rabbitmq.com/management.html,它有一个漂亮的用户界面。另一种选择是使用 -l info 选项运行 celery 并检查日志是否收到消息。您还可以运行 celery 的非守护程序实例,它将所有日志记录打印到标准输出,即运行它的终端。如果您的非守护程序设置有效,您可以使用主管来守护程序(这在同一个教程中进一步描述)。这样您就可以使用与开发环境中相同的设置来运行它。我认为这将是首选设置。没有解决方案,只有想法。
  • 我会试试 supervisord,谢谢你,Falk。

标签: python django celery daemon celerybeat


【解决方案1】:

最后,这是一个可行的示例。

  1. 制作 celery_service.conf
  2. 制作 celery.service

例如,使用 Centos systemctl 运行服务。就是这样。

我添加了有用的脚本:

【讨论】:

    【解决方案2】:

    我对此也没有正确的答案,并阅读了大量复制和粘贴相同的教程:

    注意 -B 用于开发目的。生产环境需要单独启动celery beat。

    而且没有人真正展示如何实现这一目标的任何活生生的例子。 我认为选项

    CELERYD_NODES="节拍"

    会成功,但它不起作用。 因此,只有在您的“celeryd”配置中添加选项 -B 或 --beat 才能使这个单独的工作人员进入真正的节拍状态。

    CELERYD_OPTS="--beat --scheduler=django_celery_beat.scheduler:DatabaseScheduler"

    UPD:我发现这是一个文档问题,如下所述: https://github.com/celery/celery/issues/4304

    在这里您可以看到通过 systemd 正确实现节拍的示例: https://specialistoff.net/question/238

    我现在已经检查过了 - beat 查找并正常工作,无论如何需要一些时间进行测试。

    【讨论】:

      【解决方案3】:

      我猜你有一个带有 systemd 的 linux 服务器。使用 systemd,而不是“通用初始化脚本”。

      有 systemd 的文档,但它们低于旧的 init.d 方式:

      http://docs.celeryproject.org/en/master/userguide/daemonizing.html#usage-systemd

      引用文档:

      这是一个示例 systemd 文件:

      /etc/systemd/system/celery.service:

      [Unit]
      Description=Celery Service
      After=network.target
      
      [Service]
      Type=forking
      User=celery
      Group=celery
      EnvironmentFile=/etc/conf.d/celery
      WorkingDirectory=/opt/celery
      ExecStart=/bin/sh -c '${CELERY_BIN} multi start ${CELERYD_NODES} \
        -A ${CELERY_APP} --pidfile=${CELERYD_PID_FILE} \
        --logfile=${CELERYD_LOG_FILE} --loglevel=${CELERYD_LOG_LEVEL} ${CELERYD_OPTS}'
      ExecStop=/bin/sh -c '${CELERY_BIN} multi stopwait ${CELERYD_NODES} \
        --pidfile=${CELERYD_PID_FILE}'
      ExecReload=/bin/sh -c '${CELERY_BIN} multi restart ${CELERYD_NODES} \
        -A ${CELERY_APP} --pidfile=${CELERYD_PID_FILE} \
        --logfile=${CELERYD_LOG_FILE} --loglevel=${CELERYD_LOG_LEVEL} ${CELERYD_OPTS}'
      
      [Install]
      WantedBy=multi-user.target
      

      【讨论】:

        猜你喜欢
        • 2015-05-26
        • 2014-03-05
        • 2016-03-11
        • 2018-04-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-02-07
        相关资源
        最近更新 更多