【问题标题】:How to pass broker_url from Django settings.py to a Celery service如何将 Django settings.py 中的 broker_url 传递给 Celery 服务
【发布时间】:2021-12-16 20:49:54
【问题描述】:

我在 Ubuntu 20.04 上将 Celery 作为服务运行,并使用 RabbitMQ 作为代理。

Celery 反复重启,因为它无法访问 RabbitMQ url (RABBITMQ_BROKER),这是一个保存在 Django 根目录 outside 中的变量。

如果我尝试通过命令行启动 celery,也会发生同样的情况。

我已确认可以在 Django 中通过 views.py 打印语句访问该变量。

如果我将 RABBITMQ_BROKER 变量放在 Django 根芹菜的 settings.py 中。

我的问题是,当变量 RABBITMQ_BROKER 放在 /etc/opt/mydjangoproject/settings.py 中时,如何让 celery 识别它?

我的 celery.py 文件:

import os
from celery import Celery

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'mydjangoproject.settings')

app = Celery('mydjangoproject')

default_config = 'mydjangoproject.celery_config'

app.config_from_object(default_config)
app.autodiscover_tasks()

我的 celery_config.py 文件:

from django.conf import settings

broker_url = settings.RABBITMQ_BROKER
etc...

/etc/opt/mydjangoproject/ 中的 settings.py(不相关的东西已删除):

from mydangoproject.settings import *

RABBITMQ_BROKER = 'amqp://rabbitadmin:somepassword@somepassword@webserver:5672/mydangoproject'
etc...

我的 /etc/systemd/system/celery.service 文件:

[Unit]
Description=Celery Service
After=network.target

[Service]
Type=forking
User=DJANGO_USER
Group=DJANGO_USER
EnvironmentFile=/etc/conf.d/celery
WorkingDirectory=/opt/mydjangoproject

ExecStart=/bin/sh -c '${CELERY_BIN} -A $CELERY_APP multi start $CELERYD_NODES \
   --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} --loglevel="${CELERYD_LOG_LEVEL}"'
ExecReload=/bin/sh -c '${CELERY_BIN} -A $CELERY_APP multi restart $CELERYD_NODES \
    --pidfile=${CELERYD_PID_FILE} --logfile=${CELERYD_LOG_FILE} \
    --loglevel="${CELERYD_LOG_LEVEL}" $CELERYD_OPTS'
Restart=always

[Install]
WantedBy=multi-user.target

我的 /etc/conf.d/celery 文件:

CELERYD_NODES="worker"
CELERY_BIN="/opt/mydjangoproject/venv/bin/celery"
CELERY_APP="mydjangoproject"
CELERYD_CHDIR="/opt/mydjangoproject/"
CELERYD_MULTI="multi"
CELERYD_OPTS="--time-limit=300 --without-heartbeat --without-gossip --without-mingle"
CELERYD_PID_FILE="/run/celery/%n.pid"
CELERYD_LOG_FILE="/var/log/celery/%n%I.log"
CELERYD_LOG_LEVEL="INFO"

【问题讨论】:

    标签: django celery


    【解决方案1】:

    将以下行添加到/etc/opt/mydjangoproject/settings.py 的末尾,让 celery 获取正确的代理 url(大小写可能因您使用的 celery 版本而异):

    BROKER_URL = broker_url = RABBITMQ_BROKER
    

    这会将配置放在一个可以通过调用 celery 的 config_from_object 函数读取的位置。

    接下来,您还必须为您的 systemd 单元添加一个环境变量。由于您以mydjangoproject.settings 的身份访问设置,因此您必须使mydjangoproject 目录的父目录可以在PYTHONPATH 中访问:

    Environment=PYTHONPATH=/etc/opt
    

    PYTHONPATH 为 python 提供了尝试导入时尝试的目录列表。但是,因为我们有两个同名的不同目录作为一个包使用,we also have to add the following lines to /etc/opt/mydjangoproject/__init__.py and /opt/mydjangoproject/__init__.py:

    import pkgutil
    __path__ = pkgutil.extend_path(__path__, __name__)
    

    【讨论】:

    • 非常感谢 2ps,我已经进行了更改,但似乎不起作用。我已将更改包含在我的原始帖子中,您能否检查一下我是否按照您的预期完成了所有操作?
    【解决方案2】:

    我通过将以下内容添加到 /etc/systemd/system/celery.service 解决了这个问题

    Environment="PYTHONPATH=/etc/opt/mydjangoproject:/opt/mydjangoproject"
    Environment="DJANGO_SETTINGS_MODULE=settings"
    

    【讨论】:

      猜你喜欢
      • 2018-10-01
      • 2019-11-13
      • 2016-02-28
      • 2014-09-12
      • 2018-10-07
      • 2018-10-19
      • 2011-04-28
      • 2012-04-30
      • 2012-03-22
      相关资源
      最近更新 更多