如何使用Celery autoretry_for实现带参数变更的任务自动重试?
解决方案
要实现触发ZeroDivisionError后自动用新参数(42和0.5)重试并返回84,你需要结合autoretry_for装饰器配置和任务内的重试参数重写,具体修改如下:
1. 核心修改逻辑
autoretry_for用于指定Celery自动重试的异常类型,但默认会使用原参数重试。要更换重试参数,需在任务内捕获目标异常后,通过self.retry()指定新参数,同时保留autoretry_for来管理重试的核心流程(如最大重试次数)。
2. 修改后的完整代码
from celery import Celery # 初始化Celery实例,根据你的消息中间件/结果后端配置调整 app = Celery('tasks', broker='redis://localhost:6379/0', backend='redis://localhost:6379/0') @app.task( autoretry_for=(ZeroDivisionError,), # 指定触发自动重试的异常类型 retry_kwargs={'max_retries': 1}, # 仅重试1次(换参数后即可成功) retry_backoff=False # 关闭指数退避,立即执行重试 ) def divide(a, b): try: return a / b except ZeroDivisionError as exc: # 触发重试,传入新的计算参数42和0.5 raise self.retry(args=(42, 0.5), exc=exc)
3. 关键配置说明
autoretry_for=(ZeroDivisionError,):告知Celery,当任务抛出该异常时自动启动重试流程。retry_kwargs={'max_retries': 1}:限制仅重试1次,避免无意义的循环重试。self.retry(args=(42, 0.5), exc=exc):捕获异常后,传递新的执行参数,同时将原异常回传给Celery的重试机制,确保符合autoretry_for的触发规则。- 关闭
retry_backoff是因为我们不需要等待延迟,直接用新参数重试即可得到正确结果。
4. 效果验证
当你通过API访问http://localhost:5001/divide/1/0或调用divide.delay(1, 0)时:
- 首次执行触发
ZeroDivisionError。 - Celery自动启动重试,使用参数42和0.5执行任务。
- 任务成功计算出
42 / 0.5 = 84,最终状态为SUCCESS。
内容的提问来源于stack exchange,提问作者Jacob Quisenberry
相关产品推荐
相关产品推荐

