DEBUG.WIKI
IPPeak:从目标地区访问网页,住宅代理、SEO 监测、广告验证
京东云;让 AI 进入真实业务;零售 · 物流 · 客服 · 硬件;查看方案 →
丽萨主机;为跨境业务选好 IP;原生 / 住宅 IP · 按套餐选择;查看 IP →

Celery 5.6.3 结果重连报 get_connection 缺少 command_name

Celery 5.6.3 的 Redis 结果后端重连会无参获取连接,旧 redis-py 仍要求命令名。核对客户端接口与兼容锁定,分别验证首次连接和无订阅重连。

Celery 刚启动时能提交任务、读取结果,Redis 连接断开后却在结果订阅重连里报:

TypeError: ConnectionPool.get_connection() missing 1 required positional argument: 'command_name'

Celery 5.6.3 配合 redis-py 4.6.0 出现过这个组合。这里的 redis 版本是 Python 客户端版本,不是 Redis 服务端版本;升级 Redis 容器本身不会改变 Python 方法的参数。

失败的是结果后端的一条重连分支

Celery 5.6.3 的 Redis 结果消费者重建 PubSub 时,如果当前没有待订阅频道,会直接调用连接池的 get_connection(),不传命令名。

redis-py 4.6.0 的这个方法仍要求 command_name,因此会在 Python 参数检查阶段抛出 TypeError。redis-py 5.3.0 的正式接口已把它改为可选参数,并允许无参调用。

这一分支解释了“正常运行一段时间后才出现”:首次订阅与重连时没有待订阅频道的路径不完全相同。它不表示所有 Celery Redis 错误都由这个依赖组合引起。保存完整调用栈,确认出现的是 celery.backends.redis 的 PubSub 重连,而不是业务代码自己调用了另一种连接池。

Redis 在此作为结果后端。任务 broker 可以是 Redis,也可以是别的产品;修改 broker 的消息可见性超时,并不能修复这个客户端方法签名。

调整结果消费者实际使用的客户端依赖

项目可以升级 redis-py 时,选择支持无参 get_connection()、同时满足 Celery、Kombu、Python 及 Redis 服务端要求的正式版本。5.3.0 是这里可以明确核到接口变化的版本边界,不是要求所有项目永久停在这个历史版本,也不是要求直接跨到最新主版本。

在项目的锁定环境中检查 Celery、Kombu、redis-py 和 Python 的实际版本与安装位置。Celery 5.6.3 的 Redis extra 依赖范围较宽,仅满足声明的下界不保证覆盖这条重连分支。只改 requirements 文本、却没有重新生成并部署相应环境,也不会改变正在运行的消费者。

保留连接目标、认证、TLS、Sentinel 和超时设置;本次需要调整的是兼容客户端组合,不应为套用示例换掉结果数据库。确认依赖产物后,按原部署流程重启真正持有结果连接的进程,别只重启生产者。

不要在业务代码里临时给 Celery 私有重连函数补一个任意命令名,也不要在生产 Redis 上强制踢连接来验证。重连恢复和已有任务的处理状态应在隔离结果后端、受控断连条件下观察。

验收同时覆盖首次读取结果、已有订阅时断连、没有待订阅频道时断连,以及连接恢复后新的结果读取。任务成功执行与调用方成功收到结果是两件事;结果等待失败时,先按 task ID 查询业务状态,不能直接重派有副作用的任务。

截至 2026 年 10 月 24 日,正式 Celery 5.6.3 仍保留上述无参调用。后续版本号、里程碑或问题关闭状态,不能代替对正式实现的核对。回退依赖也应恢复完整兼容锁定,并保留未完成结果等待与任务状态记录。