看起来我的芹菜工作程序在mymachine.domain.com:port上启动并正确连接,rabbit mq驻留在一个单独的docker容器中。
然而,当我从web应用程序调用函数apply_async时,它会尝试在localhost:port上连接,尽管它应该再次使用相同的django-src/settings.py文件,该文件也将是mymachine.domain.com: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'
我将打印语句添加到以下已安装的文件文件中:站点包/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。这解释了为什么在主机模式下它可以工作,因为localhost:5672对于rabbitmq和web容器是相同的。但是在桥接模式下,您无法使用localhost访问主机,这就是为什么我在configs中指定主机名的原因。我不知道为什么这会被覆盖回localhost。
同样仅供参考,当我运行芹菜工人时,它来自同一台机器,具有相同的配置文件,但我添加的打印语句显示了正确的主机。
我似乎也需要在tasks.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加载时,在我添加配置之前,没有引用它,所以它使用默认的localhost。