【问题标题】:What to do when Celery broker is down?芹菜经纪人倒闭时该怎么办?
【发布时间】:2015-09-23 15:16:00
【问题描述】:

我有一个带有 RabbitMQ 代理的 Celery 服务器。我用它在我的 Django 项目中运行后台任务。

在我的一个观点中,触发了一个信号,然后像这样调用一个 celery 任务:

create_something.delay(pk)

任务定义如下:

@task
def create_something(donation_pk):
    # do something

一切都很好,但是:

如果在我调用任务时 RabbitMQ 已关闭,则在 create_something.delay(pk) 调用期间不会引发错误。但是视图抛出了这个错误:

[Errno 111] Connection refused

(堆栈跟踪有点没用,我认为这是因为使用了信号)

现在的问题是:我怎样才能防止这个错误?当 broker 宕机时,是否有可能重试 create_something.delay(pk)?

提前感谢您的任何提示!

【问题讨论】:

    标签: django rabbitmq celery


    【解决方案1】:

    Celery 任务有一个 .run() 方法,它将执行任务,因为它是正常代码流的一部分。

    create_something.run(pk)
    

    如果需要,您可以捕获异常并执行.run()

    【讨论】:

    • 嗨!感谢您的回答,但我的 create_something.delay(pk) 没有任何异常...
    • 也许这可以帮助你*.com/questions/13037121/…
    【解决方案2】:

    是否有可能在代理关闭时重试 create_something.delay(pk)?

    调用.delay()方法时抛出的异常无法连接,可以像任何其他异常一样被捕获:

    try:
        foo.delay()
    except <whatever exception is actually thrown>:
        # recover
    

    您可以围绕它建立一个循环来重试,但您应该注意不要让请求保持很长时间。例如,如果您的连接问题需要一整秒才能得到解决,那么您不希望将请求搁置一整秒。这里的一个选项可能是快速中止,但使用日志基础设施,以便将电子邮件发送给站点管理员。一旦我确定了导致连接问题的原因并且我确定它无济于事,重试循环将是我要做的最后件事。在大多数情况下,它可以得到帮助,而重试循环确实是一个创可贴的解决方案。

    如何防止此错误?

    通过确保您的经纪人不会倒闭。要获得更准确的答案,您必须在问题中提供更多诊断信息。

    顺便说一句,Celery 有一个 retrying tasks 的概念,但这是在代理已经知道任务的情况下使用的。它不适用于您无法联系经纪人的情况。

    【讨论】: