Python分布式任务队列Celery出现失败任务,是怎么回事?

  • flask 项目

celery = Celery(name, broker=CELERY_BROKER, include=CELERY_IMPORTS)

只用了个 broker 没有用 backend ,broker 是用的 redis

上面是用 Flower 的观察结果,大概是 每创建 3 次任务,只有一次任务成功。

求解怎么回事?


Python分布式任务队列Celery出现失败任务,是怎么回事?

10 回复

贴日志出来


Celery任务失败通常有几个常见原因,直接看代码最直接。

1. 任务代码本身有Bug 这是最常见的。比如访问了不存在的属性、数据库连接失败、第三方API调用异常等。任务里的异常没被捕获就会导致失败。

# 错误示例:任务里直接调用了可能失败的操作
@app.task
def process_data(data_id):
    obj = DataModel.objects.get(id=data_id)  # 可能DataModel不存在
    obj.do_something()

# 正确做法:增加异常处理或使用get_object_or_404等安全方法
@app.task
def process_data(data_id):
    try:
        obj = DataModel.objects.get(id=data_id)
        obj.do_something()
    except DataModel.DoesNotExist:
        logger.error(f"DataModel {data_id} not found")
        # 可以选择重试或直接记录失败

2. 序列化问题 任务参数需要序列化传输,如果传了不支持的对象(比如数据库连接对象、文件句柄)就会失败。

# 错误示例:传递了不可序列化的对象
@app.task
def bad_task(db_connection):  # db_connection是连接对象,无法序列化
    db_connection.query(...)

# 正确做法:传递可序列化的参数(如ID),在任务内部重建对象
@app.task
def good_task(connection_params):  # 传字典参数
    conn = create_connection(connection_params)
    conn.query(...)

3. 超时设置问题 任务执行时间超过task_time_limittask_soft_time_limit会被强制终止。

# 在Celery配置中调整
app.conf.update(
    task_time_limit=300,  # 硬超时300秒
    task_soft_time_limit=250,  # 软超时250秒
)

# 对于特别耗时的任务,可以单独设置
@app.task(time_limit=600)
def long_running_task():
    time.sleep(500)  # 这个任务需要更长时间

4. 依赖服务不可用 比如Redis/Broker宕机、数据库连接失败、网络问题等。检查Broker和Backend的连接状态。

快速排查步骤:

  1. 查看Celery日志:celery -A proj worker --loglevel=info
  2. 检查失败任务的异常信息:result = task.delay(); result.get(propagate=False)
  3. 确认Broker(Redis/RabbitMQ)和Backend运行正常

总结建议:先看任务本身的异常堆栈,八成是代码问题。

兄弟你这不贴错误日志和报错,别人怎么帮你。



日记无任何错误,找到原因了,supervisor stop 关闭不了 celery 进程,然后用手动启动了个,所以一会成功,一会失败。

前面两个任务,有错误没有处理好啊
不要用 one(), 如果数据库有做约束,那就 first()
或者简单点 one_or_none()

请问你这个后面是怎么解决的?我现在遇到个类似问题,就是任务有时候会注册不成功,redis 中返回结果是 “result”: {
“exc_type”: “NotRegistered”,
“exc_message”: “‘tasks.excel.excel_to_db’”
},请问知道是哪里出了问题吗?

我也遇到这个问题,您解决了没

我也是使用的 supervisor 启动 celery,任务有时候能执行有时候报 NotRegistered。。您是怎么解决的呢

请问解决了么。。。

解决了,检查自己的任务函数,发现点问题,换了种方式,然后就正常了。

回到顶部