Django-celery 和 RabbitMQ 不执行任务
Posted
技术标签:
【中文标题】Django-celery 和 RabbitMQ 不执行任务【英文标题】:Django-celery and RabbitMQ not executing tasks 【发布时间】:2014-01-18 09:52:19 【问题描述】:我们有一个带有 django-celery 2.5.5 的 Django 1.3 应用程序,该应用程序在生产中运行了一个月,但突然之间出现了一个 celery任务现在无法执行。
RabbitMQ 代理和 Celery 工作器在单独的机器上运行,并且 celeryconfig.py 被配置为使用特定的 RabbitMQ 实例作为后端。
在应用服务器上,我尝试通过 python manage.py shell
手动启动 celery 任务。
实际的任务是这样调用的:
>>> result = tasks.runCodeGeneration.delay(code_generation, None)
>>> result
<AsyncResult: 853daa7b-8be5-4a25-a1d0-1552b38a0d21>
>>> result.state
'PENDING'
它按预期返回AsyncResult
,但其状态永远是'PENDING'
。
要查看 RabbitMQ 代理是否收到消息,我运行了以下命令:
$ rabbitmqctl list_queues name messages messages_ready messages_unacknowledged | grep 853daa
853daa7b8be54a25a1d01552b38a0d21 0 0 0
我不确定这意味着什么,RabbitMQ 似乎确实收到了某种请求,否则如何为 id 为 853daa7b8be54a25a1d01552b38a0d21 的任务创建队列。它似乎没有任何消息?
我已尝试重新启动 Celery 和 RabbitMQ,但问题仍然存在。
Celery 是这样运行的:$ python /home/[project]/console/manage.py celeryd -B -c2 --loglevel=INFO
请注意,celerybeat/scheduled 任务似乎运行良好。
[编辑]:
没有 RabbitMQ 配置,因为它被 init.d 脚本内联:
/usr/lib/erlang/erts-5.8.5/bin/beam.smp -W w -K true -A30 -P 1048576 -- -root /usr/lib/erlang -progname erl -- -home /var/lib/rabbitmq -- -noshell -noinput -sname rabbit@hostname -boot /var/lib/rabbitmq/mnesia/rabbit@hostname-plugins-expand/rabbit -kernel inet_default_connect_options [nodelay,true] -sasl errlog_type error -sasl sasl_error_logger false -rabbit error_logger file,"/var/log/rabbitmq/rabbit@hostname.log" -rabbit sasl_error_logger file,"/var/log/rabbitmq/rabbit@hostname-sasl.log" -os_mon start_cpu_sup true -os_mon start_disksup false -os_mon start_memsup false -mnesia dir "/var/lib/rabbitmq/mnesia/rabbit@hostname"
[编辑2]: 这是我们用于工人的 celeryconfig。生产者使用相同的配置,当然 localhost 更改为带有 RabbitMQ 代理的框。
from datetime import timedelta
BROKER_HOST = "localhost"
BROKER_PORT = 5672
BROKER_USER = "console"
BROKER_PASSWORD = "console"
BROKER_VHOST = "console"
BROKER_URL = "amqp://guest:guest@localhost:5672//"
CELERY_RESULT_BACKEND = "amqp"
CELERY_IMPORTS = ("tasks", )
CELERYD_HIJACK_ROOT_LOGGER = True
CELERYD_LOG_FORMAT = "[%(asctime)s: %(levelname)s/%(processName)s/%(name)s] %(message)s"
CELERYBEAT_SCHEDULE =
"runs-every-60-seconds":
"task": "tasks.runMapReduceQueries",
"schedule": timedelta(seconds=60),
"args": ()
,
[编辑3]: 我们的基础设施设置如下图 2:
【问题讨论】:
如果我对您的理解正确,您只有一项任务没有执行,而其他所有任务都可以正常工作?如果是这种情况,可能是任务被安排在一个从未被消耗的队列上? 没错。有没有办法可以验证您所说的是否正在发生?我能做些什么来解决它? 如果应该检查并可能在此处共享 2 个 celeryconfig,一个在工作人员正在运行的服务器上,另一个是您在调度任务时从控制台使用的一个。当您使用 django-celery 时,celeryconfig 就是 Django 设置本身。您可以做的另一件事是检查rabbitmq 管理Web 控制台是否有始终在增长且从未消耗的队列,您甚至可以检查订阅队列的所有消费者。 rabbitmq.com/management.html 感谢您的帮助。但是,使用管理 Web 控制台,我们可以看到一个队列已创建并处于“活动”状态,但其中没有任何消息... 可能是消息立即被消费,但这应该从其他统计数据中显而易见。如果您真的需要帮助,我建议您粘贴设置,当然不要使用真实 IP 和密码 :-) 【参考方案1】:我们解决了这个问题。
有一个长时间运行的 celerybeat 任务(约 430 秒),计划每 60 秒运行一次。这将所有工作人员排成一队。
【讨论】:
以上是关于Django-celery 和 RabbitMQ 不执行任务的主要内容,如果未能解决你的问题,请参考以下文章
第一次更改主机名后,rabbitmq-server 无法启动
django-celery crontab 日程表的日期和月份
如何修改django-celery web界面进行周期性调度