2012-03-16 83 views
50

重试芹菜任务,对于这样一个任务:与指数退避

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等秒?

也是从服务器端维护的重试,以便如果工作人员碰巧遇害,那么下一个产生的工作人员将采取重试任务?

回答

96

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)) 
+0

你知道这是服务器端重试还是客户端要等待吗?如果客户不停地等待,那就很糟糕。 – 2012-03-18 05:18:36

+2

据我所知,倒数属性为MQ后端的任务设置了一个eta(例如RabbitMQ)。所以它不是在客户端设置的。 – idanzalz 2012-11-28 13:24:25

+0

客户端不会一直等待,除非您执行'result.get()'这是一个明确的请求来等待结果准备就绪,但还有一个超时参数并且存在重试状态,因此您可以检查该任务是否为正在重试(以及重试的原因是什么) – asksol 2012-11-30 12:12:43