DEBUG.WIKI
京东云;让 AI 进入真实业务;零售 · 物流 · 客服 · 硬件;查看方案 →
ZgoCloud:多地区部署,按需选节点;日本、美国、香港、德国
Evoxt;最高 6.0GHz CPU;高频云服务器 · 免费每周备份;查看配置 →

BullMQ Worker 报 maxRetriesPerRequest must be null

Worker传入已有ioredis需要符合后台重试规则。单独配置消费者连接,保留HTTP生产者有界等待、错误处理和共享连接关闭顺序。

把已有的 ioredis 实例传给 BullMQ Worker,启动时出现 BullMQ: Your redis options maxRetriesPerRequest must be null.。同一实例用于 Queue 添加任务可能正常,但 Worker 需要的连接行为不同,应检查 ioredis 创建时的选项,而不是只看 Redis 能否连接。

这个检查在 BullMQ 5.21.0 配合 ioredis 5.4.1 的已有实例路径中出现;当前 BullMQ 6.3.12 的 ioredis 连接规则仍区分后台消费者与请求内生产者。不要把它扩大成其他 Redis 客户端都具有同名配置。

给后台 Worker 建立符合要求的连接

以下示例保留应用已有的连接配置,只覆盖 Worker 所需的重试选项。workerRedisOptions 应来自项目的受控配置,包含实际目标、认证、TLS 和其他必要参数;processJob 是已有的业务处理函数:

import IORedis from 'ioredis';
import { Worker } from 'bullmq';

const workerConnection = new IORedis({
  ...workerRedisOptions,
  maxRetriesPerRequest: null,
});

const worker = new Worker('tasks', processJob, {
  connection: workerConnection,
});

不要给一个已经被其他调用方使用的连接实例临时修改选项,再期待所有内部连接同步改变。按应用生命周期创建正确实例,确认旧 Worker 已完成关闭,避免启动重复消费者。

Worker 还会为阻塞等待创建专用的重复连接。限制连接数量的托管服务中,不能把“复用了一个实例”理解成整个 Worker 只占一条连接。

HTTP 生产者不一定应该无限等待

maxRetriesPerRequest 是请求重试相关设置,不等同于网络连接永远不会断,也不替代重连策略、超时和业务错误处理。后台 Worker 通常需要在连接恢复后继续工作,因此采用 null;HTTP 接口中的 Queue 添加任务却可能需要较快返回失败。

为生产者保留有界重试与适当的离线队列策略,不要为了修复 Worker,把所有 Redis 连接全改为无限等待。用户请求已经超时,后台命令仍被排队执行时,还需要处理“调用方以为失败,任务后来却添加成功”的情况,避免重试造成重复业务。

若采用共享连接,先确认共享方的等待要求确实相同。两个需求不同的生产者和消费者,使用独立的配置与生命周期通常更容易保持边界。

启动通过后,还要核对任务和关闭流程

保留连接和 Worker 的错误处理,不把启动阶段异常吞掉后继续对外报告正常。按照实际入口检查 Worker 能否获取已添加的任务,以及短暂断线后是否按设计恢复;连接恢复并不证明被中断的业务一定未执行。

关闭时先让 Worker 按批准的流程完成关闭,再释放不再使用的共享连接。不要在活跃任务期间先强制断开底层连接。

错误消失但任务一直 waiting,应继续核对队列名称、目标数据库和 BullMQ prefix,例如 Queue 与 Worker 的 prefix 不一致。连接选项正确,只证明通过了这一项连接规则,不保证两端正在使用同一个队列。