使用Celery,如何将Rabbitmq消息发布到另一个Docker容器?

时间:2018-07-11 21:51:34

标签: python django docker rabbitmq celery

我的芹菜工人似乎在mymachine.domain.com:port上正确启动并连接,兔子mq驻留在单独的docker容器中。

但是,当我从Web应用程序调用函数apply_async时,即使它应该使用相同的django src / settings.py文件,该文件也将再次是mymachine.domain.com:port,它仍尝试在localhost:port上进行连接。

我要使其正常工作的唯一方法是将docker network_mode设置为'host'。出于安全原因,这是不可接受的模式。

这是我的celery.py文件:

from celery import Celery
from celery.schedules import crontab

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

import django
django.setup()

from src.apps.main.tasks import cleanup, syncldap 

app = Celery('myappcelery', backend='amqp',
# Expected  next line isn't even used because line with 'django.conf:settings' will override it with the config settings.

broker='amqp://user@mymachine.domain.com:5672//',                          include=['src.apps.appname.tasks'])
app.config_from_object('django.conf:settings', 
app.autodiscover_tasks()

这是我的src.settings.py文件设置:

CELERY_BROKER_URL = 'amqp://user:password@mymachine.domain.com:5672//'
CELERY_RESULT_BACKEND = 'django-db'

CELERY_ACCEPT_CONTENT = ['json']
CELERY_TASK_SERIALIZER = 'json'
CELERY_RESULT_SERIALIZER = 'json'

CELERY_DEFAULT_QUEUE = 'celery'

我向以下已安装文件添加了打印语句: site-packages / kombu / connection.py

在函数中:

def default_channel(self):

我添加了以下打印声明:

print "Connection %s" % self.connect

在我的芹菜工人那里,我在日志中看到了这一点:

Connection <bound method Connection.connect of <Connection: amqp://<user>:**@mymachine.domain.com:5672// at 0x7fd1e3700450>>

但是当我尝试调用apply_async时,我看到以下消息,它只是挂起:

Connection <bound method Connection.connect of <Connection: amqp://<user>:**@localhost:5672// at 0x7fc01371bc50>>

其中localhost是Web应用程序的docker容器,将无法正确连接到位于主机上的Rabbit mq。这解释了为什么在主机模式下它可以工作,因为那时Rabbitmq和Web容器的localhost:5672是相同的。但是在桥接模式下,您无法使用localhost访问主机,这就是为什么我在配置中指定主机名的原因。我不确定为什么这会覆盖回本地主机。

仅供参考,当我运行芹菜工人时,它是来自同一台具有相同配置文件的机器,但是我添加的打印语句显示了正确的主机。

1 个答案:

答案 0 :(得分:0)

似乎我也需要在task.py文件中实例化应用。

之前

@task(name='func_name', bind=True)
def func_name(self, id)

之后

app = Celery('celery', backend='amqp',
             broker='amqp://user@mymachine.domain.com:5672//')
@app.task(name='func_name', bind=True)
def func_name(self, id)

将它们从autodiscover_tasks函数导入celery.py时,它会加载应用程序配置。但是,当从Web加载时,直到我将其添加之前,它才引用配置,因此它使用的是默认的本地主机。