我有五个不同的Django项目都在一个盒子上运行,一个RabbitMQ安装。我用芹菜做各种任务。每个项目似乎都在接收其他项目的任务。
每个代码库都有自己的虚拟环境,运行以下内容:
./manage.py celeryd --concurrency=2 --queues=high_priority
每个settings.py中的参数如下所示:
CELERY_SEND_EVENTS = True
CELERY_TASK_RESULT_EXPIRES = 10
CELERY_RESULT_BACKEND = 'amqp'
CELERYBEAT_SCHEDULER = "djcelery.schedulers.DatabaseScheduler"
CELERY_TIMEZONE = 'UTC'
BROKER_URL = 'amqp://guest@127.0.0.1:5672//'
BROKER_VHOST = 'specific_app_name'
我看到追溯让我觉得应用程序在不应该收到对方的消息时会收到:
Traceback (most recent call last):
File "/home/.../.virtualenvs/.../local/lib/python2.7/site-packages/kombu/messaging.py", line 556, in _receive_callback
decoded = None if on_m else message.decode()
File "/home/.../.virtualenvs/.../local/lib/python2.7/site-packages/kombu/transport/base.py", line 147, in decode
self.content_encoding, accept=self.accept)
File "/home/.../.virtualenvs/.../local/lib/python2.7/site-packages/kombu/serialization.py", line 187, in decode
return decode(data)
File "/home/.../.virtualenvs/.../local/lib/python2.7/site-packages/kombu/serialization.py", line 74, in pickle_loads
return load(BytesIO(s))
ImportError: No module named emails.models
这种情况下的emails.models
模块出现在一个项目中,但不出现在其他项目中。然而其他人正在展示这种追溯。
我没有看过多个节点名称或类似的东西。这样的事情会解决这个问题吗?
答案 0 :(得分:1)
celeryconfig.py
中的AMQP设置错误。您正在使用:
BROKER_URL = 'amqp://guest@127.0.0.1:5672//'
BROKER_VHOST = 'specific_app_name'
BROKER_VHOST
参数被忽略,因为BROKER_URL
存在(也不推荐使用)。如果您想使用虚拟主机(这是解决您提出的问题的首选方式),您应该为每个应用程序创建一个虚拟主机,并在每个应用程序设置中使用以下内容:
BROKER_URL = 'amqp://guest@127.0.0.1:5672//specific_app_name'
编辑:修复缺失/
答案 1 :(得分:0)
您应为每个项目指定不同的队列设置。例如:
CELERY_QUEUES = {
"celery": {
"exchange": "project1_celery",
"binding_key": "project1_celery"},
}
CELERY_DEFAULT_QUEUE = "celery"
对于第二个项目,您将exchange和binding_key指定为project2_celery
,依此类推。
我发布的代码是Celery< 3.0。如果您使用的是较新的版本,它可能会如下所示(我还没有使用过新版本,所以我不确定):
from kombu import Exchange, Queue
CELERY_DEFAULT_QUEUE = 'celery'
CELERY_QUEUES = (
Queue('celery', Exchange('project1_celery'), routing_key='project1_celery'),
)
您可以在芹菜文档中阅读更多内容:http://docs.celeryproject.org/en/latest/userguide/routing.html
答案 2 :(得分:0)
如果多个django项目共享同一个框,则需要为每个项目显式“命名”@tasks。错误msg返回了“emails.models”的命名空间,这对任何一个项目都不是唯一的。
例如,如果一个项目名为“project1”,另一个项目名为“project2”,则只需将“name =”参数添加到@task装饰器:
# project1
# emails.py
@tasks(name=project1.emails.my_email_function, queue=high_priority)
def my_email_function(user_id):
return [x of x in user_id if spam()]
# project2
# tasks.py
@tasks(name=project2.tasks.my_task_function, queue=high_priority)
def my_task_function(user_id):
return [x of x in user_id if blahblah()]