对于这样的任务:
from celery.decorators import task
@task()
def add(x, y):
if not x or not y:
raise Exception("test error")
return self.wait_until_server_responds(
如果它抛出异常并且我想从守护进程端重试它,那么如何应用指数退避算法,即在2^2, 2^3,2^4
秒之后?
同样是从服务器端维护重试,这样如果工作人员碰巧被杀,那么下一个产生的工人将接受重试任务?
答案 0 :(得分:116)
task.request.retries
属性包含到目前为止的尝试次数,
所以你可以用它来实现指数后退:
from celery.task import task
@task(bind=True, max_retries=3)
def update_status(self, auth, status):
try:
Twitter(auth).update_status(status)
except Twitter.WhaleFail as exc:
self.retry(exc=exc, countdown=2 ** self.request.retries)
要防止Thundering Herd Problem,您可以考虑在指数退避时添加随机抖动:
import random
self.retry(exc=exc, countdown=int(random.uniform(2, 4) ** self.request.retries))
答案 1 :(得分:21)
从Celery 4.2开始,您可以将任务配置为自动使用指数退避:http://docs.celeryproject.org/en/master/userguide/tasks.html#automatic-retry-for-known-exceptions
@app.task(autoretry_for=(Exception,), retry_backoff=2)
def add(x, y):
...
(这已经在Celery 4.1的文档中,但实际上还没有发布,请参阅merge request)