【问题标题】:Celery/RabbitMQ unacked messages blocking queue?Celery/RabbitMQ 未确认消息阻塞队列?
【发布时间】:2015-06-14 13:41:57
【问题描述】:

我已经调用了一个任务,该任务使用 urllib2 远程获取一些信息数千次。这些任务是用随机的 eta(一周内)安排的,因此它们不会同时到达服务器。有时我得到 404,有时没有。我正在处理错误以防万一。

在 RabbitMQ 控制台中,我可以看到 16 条未确认的消息:

我停止了 celery,清除了队列并重新启动它。 16 条未确认的消息仍然存在。

我还有其他任务进入同一个队列,但也没有一个任务被执行。清除后,我尝试提交另一个任务,它的状态仍然是ready

有什么想法可以找出为什么消息仍未被确认?

版本:

celery==3.1.4
{rabbit,"RabbitMQ","3.5.3"}

celeryapp.py

CELERYBEAT_SCHEDULE = {
    'social_grabber': {
        'task': '<django app>.tasks.task_social_grabber',
        'schedule': crontab(hour=5, minute=0, day_of_week='sunday'),
    },
}

tasks.py

@app.task
def task_social_grabber():
    for user in users:
        eta = randint(0, 60 * 60 * 24 * 7) #week in seconds
        task_social_grabber_single.apply_async((user), countdown=eta)

此任务没有定义路由,因此它进入默认队列:celery。有一个工作人员在处理这个队列。

supervisord.conf:

[program:celery]
autostart = true
autorestart = true
command = celery worker -A <django app>.celeryapp:app --concurrency=3 -l INFO -n celery

【问题讨论】:

  • 您能发布您的 celery 配置、celery 版本和 RabbitMQ 版本吗?
  • 完成。如果您还需要什么,请告诉我。

标签: python rabbitmq celery urllib2


【解决方案1】:

RabbitMQ 在 3.3 版中破坏了 QoS 设置。您需要将 celery 升级到至少 3.1.11 (changelog) 并将 kombu 升级到至少 3.0.15 (changelog)。您应该使用最新版本。

在 3.3 发布时,我遇到了完全相同的行为。 RabbitMQ 翻转了 prefetch_count 标志的默认行为。在此之前,如果消费者在 eta 的消息中达到 CELERYD_PREFETCH_MULTIPLIER 限制,则工作人员将提高此限制以获取更多消息。更改打破了此行为,因为新的默认行为拒绝了此功能。

【讨论】:

  • 嗨@Eric,我遇到了同样的问题(16 个作业卡在未确认状态的队列中)。没有 eta 的任务,只有一个调度程序进程和 3 个工作进程,没有路由。我的队列每隔几个小时就会卡住一次,解除卡住的唯一方法是重新启动这两种进程类型。我在heroku,版本kombu==3.0.26和celery==3.1.17。我还有什么其他办法可以解决这个问题吗?
  • @Flevour 您找到解决问题的方法了吗?
【解决方案2】:

我有类似的症状。到达 MQ 的消息(在图表中可见)但没有被工作人员拾取。

这让我假设我的 Django 应用程序正确设置了 Celery 应用程序,但我错过了an import ensuring Celery would be configured during Django startup

from __future__ import absolute_import

# This will make sure the app is always imported when
# Django starts so that shared_task will use this app.
from .celery import app as celery_app  # noqa

这是一个愚蠢的错误,但是到达代理的消息返回了 AsyncResult,让我偏离了轨道,让我找错了地方。然后我注意到设置CELERY_ALWAYS_EAGER = True 没有做蹲,事件然后任务根本没有执行。

PS:这可能不是对@kev 问题的回答,但由于我来过这里几次,在寻找我的问题的解决方案时,我把它贴在这里给任何有类似情况的人。

【讨论】: