NodeJS中Bull(Redis)进程停止消费新消息问题求助
问题:Bull队列在K8s/Docker环境运行数小时后停止消费任务
问题现象
- 基于Docker和K8s部署的Worker启动时初始化Bull进程,持续监听Redis队列中的消息
- 运行数小时后(无固定时长),Bull停止消费新消息,但Redis的等待队列仍存在未处理任务
- 重启Worker Pod后,会重新开始消费积压的任务
相关错误日志
at TCP.onStreamRead (internal/stream_base_commons.js:209:20) {
errno: -104,
code: 'ECONNRESET',
syscall: 'read'
}
初始化Bull的核心代码
Worker.jobQueue = new Bull(jobName, { prefix, redis: redisOptions, enableReadyCheck: false, settings: { maxStalledCount: 30 } }); Worker.jobQueue.process(flags.concurrency, async (job) => this.runJob(job), ); ... async runJob(job: Bull.Job): Promise<IBullJobResponse> { // 业务处理逻辑 return { success: true, }; }
使用版本信息
bull: ^4.10.2 ioredis: ^5.2.4 Nodejs: 14.15
可能的触发原因
- Redis连接异常未被处理:日志中的
ECONNRESET是TCP连接被重置的错误,大概率是Redis端主动断开了空闲连接,但Bull或ioredis未正确触发重连逻辑。即使没捕获到Bull的error事件,底层Redis客户端的连接异常可能没有被上层转发,导致消费进程因连接中断停滞。 - 关闭就绪检查的隐患:配置了
enableReadyCheck: false,会导致Bull无法感知Redis的连接状态变化,即使连接断开也不会触发重连或状态重置。 - 业务代码的静默异常:
runJob中的异步代码如果存在未捕获的Promise rejection,可能导致Worker进程内部状态异常,虽然进程不会崩溃,但会停止处理新任务。 - 停滞任务处理机制的问题:
maxStalledCount:30设置了停滞任务的重试次数,但如果任务处理出现死锁、长时间阻塞,会导致Worker进程无法继续处理后续任务。 - K8s网络波动:K8s环境中的网络间歇性中断,可能导致Worker与Redis的连接断开,若ioredis的重连配置不合理(比如重连次数、间隔设置不当),会导致无法恢复连接。
内容的提问来源于stack exchange,提问作者ShahtajK
相关产品推荐
相关产品推荐

