我有一台带有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)的重试?
提前感谢任何提示!
答案 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的概念,但是当代理已知已经时,它就是这个概念。它不适用于您无法联系经纪人的情况。