当Celery经纪人关闭时该怎么办?

时间:2015-09-23 15:16:00

标签: django rabbitmq celery

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

在我的一个视图中,触发了一个信号,然后调用这样的芹菜任务:

create_something.delay(pk)

任务定义如下:

@task
def create_something(donation_pk):
    # do something

一切都很好,但是:

如果在调用任务时RabbitMQ关闭,则在create_something.delay(pk)调用期间不会抛出任何错误。但视图会抛出此错误:

[Errno 111] Connection refused

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

现在的问题是:如何防止此错误?当经纪人关闭时,是否有可能执行create_something.delay(pk)的重试?

提前感谢任何提示!

2 个答案:

答案 0 :(得分:0)

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

create_something.run(pk)

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

答案 1 :(得分:0)

  

当经纪人关闭时,是否有可能执行create_something.delay(pk)的重试?

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

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

您可以在此周围构建一个循环来重试,但是您应该注意不要长时间保持请求。例如,如果您的连接问题需要一秒钟才能得到解决,那么您不希望将请求暂停一整秒。此处的选项可能是快速中止,但使用日志记录基础结构,以便向站点管理员发送电子邮件。一旦我确定了导致连接问题的原因并且我已经确定它无法帮助,重试循环将是最后的事情。在大多数情况下,可以得到帮助,重试循环实际上是一个绑定解决方案。

  

如何防止此错误?

确保您的经纪人不会失败。要获得更精确的答案,您必须在问题中提供更多诊断信息。

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