13

我有以下设置:

  • 具有 100 个工人的通用工人池
  • 具有 50 个工人的高优先级工人池
  • 我使用了这么大的数字,因为我的任务大部分时间都花在等待 I/O 上,而且超时时间很长(执行 HTTP 请求可能需要 20 秒才能响应)
  • 使用 RabbitMQ 作为代理
  • 我已经使用 celery'd github 中的 init.d脚本将 celeryd 设置为守护进程,并具有以下参数: CELERYD_OPTS="--time-limit=600 -c:low_p 100 -c:high_p 50 -Q:low_p low_priority_queue_name -Q:high_p high_priority_queue_name"

我的问题是,有时队列似乎“备份”......也就是说它会停止消费任务。似乎有这种情况:

  • 代理中“未确认”消息的缓慢积累,尽管celery inspect active会显示并非所有工作人员都已用完 - 也就是说,我只会看到一些活动任务
  • 队列将停止消耗新任务,而不会增加。
  • 当处于“死”状态时,strace在工作进程上使用不会返回任何内容......工作人员的活动完全为零

我将不胜感激有关以下方面的任何信息或指示:

  • 我如何调试它。我可以strace用来查看工作进程正在做什么,但到目前为止,这对于告诉我工作人员正在挂起很有用
  • 我如何监控这一点,并可能进行自动恢复。管理 celery 的工具有很多(flowerevents它们都具有出色的实时性——但没有任何自动监控/报警功能)。我最好用supervisord编写自己的监控工具吗?

另外,我从 django-celery 开始我的任务

4

3 回答 3

4

一个非常基本的队列看门狗可以通过 cron 每分钟运行的单个脚本来实现。首先,它触发一个任务,当执行时(在工作人员中),会触及一个预定义的文件,例如:

with open('/var/run/celery-heartbeat', 'w'):
    pass

然后脚本检查该文件上的修改时间戳,如果超过一分钟(或 2 分钟,或其他),则发送警报和/或重新启动工作人员和/或代理。

如果您有多台机器,它会变得有点棘手,但同样的想法也适用。

于 2014-02-20T21:25:37.600 回答
3

@goro,如果您正在向外部服务发出请求,您应该尝试gevent 或 eventlet池实现,而不是产生 100500 个工人。我也有问题,当 celery 工人停止消费任务时,这是由celery+gevent+sentry(raven)组合的错误引起的。

关于 Celery,我发现的一件事是,如果一切正常,它可以在没有任何监控的情况下正常工作(目前我每天要执行超过 5000 万个任务),但如果不是这样,监控不会对你有太大帮助。Celery 中的“灾难恢复”有点棘手,并非所有事情都会按您的预期工作:(

您应该在较小的和平上打破您的解决方案,可能会在不同队列之间分离一些任务。在某些时候,您会发现导致问题的代码片段。

于 2013-07-09T08:25:35.260 回答
3

我认为这是因为工人预取任务。如果这仍然是一个问题,您可以将 celery 更新到 3.1 并使用-Ofairworker 选项。我之前尝试使用的配置选项-OfairCELERYD_PREFETCH_MULTIPLIER. 然而,设置CELERYD_PREFETCH_MULTIPLIER = 1(它的最低值)并没有帮助,因为工作人员仍然会提前预取一项任务。

请参阅http://docs.celeryproject.org/en/latest/whatsnew-3.1.html#prefork-pool-improvements ,尤其是http://docs.celeryproject.org/en/latest/whatsnew-3.1.html#caveats

于 2014-02-13T08:47:21.497 回答