本篇文章在介绍 celery 的重试策略,如果有问题或是错误,欢迎留言讨论!!
一、简介
稍微在网路上搜寻了一下,Celery 的 retry 大致上可以分为两种,第一种为调用任务时,可以设定参数,此参数主要在控制建立任务连线 (也就是派送任务时),第二种则是在任务执行的时候,任务本身发生错误所需要的 retry
二、发送任务的 retry
在调用任务时,可以设定的重试参数分别有
max_retries: 最大重试次数,预设为 3 次interval_start: 两次重试之间等待的秒数,预设为 0 秒,可接收浮点数interval_step: 两次重试之间等待的秒数会增加的秒数,ex interval_start = 2, interval_step = 3,则下次重试会于 5 秒后开始,下下次会于 8 秒后开始interval_max: 用于控制两次重试之间等待的最大秒数**请注意这个方法适用在,建立与 worker 连线的时候的重试,并不是任务本身运行过程发生错误会重试的设定
**
下面为程式码範例
from task import get_resultretry_policy = {'max_retries': 2, 'interval_start': 5}test_task = get_result.apply_async((10, 0), retry=True, retry_policy=retry_policy)
三、任务运行中碰到错误的 retry
若想要让任务本身运行碰到错误会进行 retry 则需要在任务内进行设定
(一)、建立任务
解释:
透过设定 bind=True 可以让我们访问 self,可以看到在建立任务的时候多了 self 参数透过设定 default_retry_delay 可以控制两次重试间的间隔透过设定 retry_kwargs 可以控制 retry 相关设定注意:
default_retry_delay 不能写进 retry_kwargs 内
from celery import Celeryfrom setting import broker_url, backend_urlfrom datetime import datetimeapp = Celery("celery_start", broker=broker_url, backend=backend_url)retry_kwargs = {"max_retries": 3, "retry_backoff": False}@app.task(bind=True, default_retry_delay=10, retry_kwargs=retry_kwargs)def get_result(self, x, y): print(datetime.now()) try: tmp = x / y return tmp except Exception as ex: self.retry(exc=ex)
下图中我们可以看到,celery 在收到任务后会先执行第一次,直到碰到错误后,开始进行重试
因此总共执行次数为 4 次
(二)、retry_kwargs 控制项 (根据 package 内说明所列)
args: 同 apply_async 送的参数kwargs: 同 apply_async 送的参数exc: 发生错误时,会回传的讯息throw: 为一个布林值,若设为 false 当任务发生错误,不会丢出错误讯息,只会将任务标记为 retry 直到 retry 次数用尽 or 成功eta: 同 apply_async 送的参数countdown: 同 apply_async 送的参数max_retries: 最大 retry 次数(三)、其他常用参数
autoretry_for当发生指定错误时,会自动进行 retry 不需要再撰写 self.retry()
from requests.exceptions import RequestException@app.task(autoretry_for=RequestException)
若想自动 retry 任何错误则
@app.task(autoretry_for=Exception)
retry_backoff功能同 retry 模组的 backoff 会以指数型态增加两次 retry 间隔
ex: backoff = 2 且两次 retry 间隔 1 秒,则第一次为 1 秒,第二次为 2 秒,第三次为 4 秒以此类推
@app.task(retry_backoff=2)
retry_backoff_max设定等待最大秒数上限,单位为秒,预设为 600 也就是 10 分钟
@app.task(retry_backoff_max=600)
四、参考文献
https://coderbook.com/@marcus/how-to-automatically-retry-failed-tasks-with-celery/