解决broker挂掉时celery卡死的问题

在一个项目中用到了celery,我们用rabbitmq来作为broker,但是发现当rabbitmq挂掉时,celery却无法发送任务,设计到apply_async和delay的代码会一直处在卡住的状态。

也尝试使用celery文档中的BROKER_CONNECTION_TIMEOUT参数,但不起效果,其实官方也说了:

1
The broker connection timeout only applies to a worker attempting to connect to the broker. It does not apply to producer sending a task, see broker_transport_options for how to provide a timeout for that situation.

这个参数仅对worker有用,对任务发送是无用的。很傲娇的是broker_transport_options这个链接中也未提供足够的帮助信息。

继续查找相关信息,在几个项目的issue页面看到些讨论,还是需要对broker_transport_options这个配置传入参数才行,例如:

1
BROKER_TRANSPORT_OPTIONS = {"max_retries": 3, "interval_start": 0, "interval_step": 0.2, "interval_max": 0.5}

这段配置意思为:

最多重试3次
从0秒开始重试
每次失败后等待0.2秒后再次进行尝试
总尝试时间不超过0.5秒

在项目中使用这个配置后发现确实解决了问题,代码在遇到rabbitmq挂掉的情况下不会再卡住了(因为都是用了kombu,估计对redis作为broker也有效果吧)。

github上的讨论的issue可见:https://github.com/celery/celery/issues/4627#issuecomment-396907957

使用示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# settings.py

CELERY_BROKER_TRANSPORT_OPTIONS = {
"max_retries": 5,
"interval_start": 0,
"interval_step": 1,
"interval_max": 5
}

# celery file

from celery import Celery
from celery import platforms
from django.conf import settings

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'smartant_backend.settings')

app = Celery('smartant_backend')
platforms.C_FORCE_ROOT = True

app.config_from_object('django.conf:settings', namespace='CELERY')
-------------本文结束感谢您的阅读-------------