BullMQ NestJS外部进程配置问题:并发失效与锁缺失错误求助
解决方案
一、修复外部进程Processor不生效问题
因为是外部进程,不能直接在BullModule.registerQueue中指定processor,需要单独启动Worker进程处理队列任务,步骤如下:
- 创建独立Worker文件(如
compute.worker.ts):
import { Worker } from 'bullmq'; // 初始化Worker,配置Redis连接与并发数 const computeWorker = new Worker('compute', async (job) => { // 编写任务处理逻辑 console.log(`处理任务 ${job.id}:`, job.data); return '任务执行完成'; }, { connection: { host: process.env.REDIS_HOST, port: parseInt(process.env.REDIS_PORT), }, concurrency: 2, // 这里设置并发数 }); // 监听Worker事件 computeWorker.on('completed', (job) => { console.log(`任务 ${job.id} 执行完成`); }); computeWorker.on('failed', (job, err) => { console.error(`任务 ${job.id} 失败:`, err.message); });
- 主应用中仅注册队列,不指定processor:
import { BullModule } from '@nestjs/bullmq'; @Module({ imports: [ BullModule.registerQueue({ name: 'compute', connection: { host: process.env.REDIS_HOST, port: parseInt(process.env.REDIS_PORT), }, // 此处不要添加processor配置 }), ], }) export class AppModule {}
- 单独启动Worker进程:
在package.json中添加启动脚本:
{ "scripts": { "start:worker:compute": "ts-node src/compute.worker.ts" } }
执行npm run start:worker:compute启动外部Worker。
二、解决"Missing lock for job X failed"报错
该错误是因为任务执行时间超过默认lockDuration(默认30秒),导致任务锁过期,BullMQ判定任务失败。需在Worker配置中增大锁时长,同时可开启自动续期:
修改compute.worker.ts的Worker配置:
const computeWorker = new Worker('compute', async (job) => { // 任务逻辑 }, { connection: { host: process.env.REDIS_HOST, port: parseInt(process.env.REDIS_PORT), }, concurrency: 2, lockDuration: 300000, // 设为5分钟,根据任务实际耗时调整 lockRenewTime: 60000, // 每分钟自动续期一次锁 });
若需针对单个任务单独配置锁时长,可在发送任务时设置:
import { InjectQueue } from '@nestjs/bullmq'; import { Queue } from 'bullmq'; @Injectable() export class ComputeService { constructor(@InjectQueue('compute') private computeQueue: Queue) {} async addJob(data: any) { await this.computeQueue.add('compute-job', data, { lockDuration: 300000, // 单个任务的锁时长 }); } }
关键注意事项
- 外部Worker与主应用必须连接同一Redis实例,否则队列无法互通。
lockDuration需设置为比任务最长执行时间更长的数值,避免锁提前过期。- 任务执行时间不确定时,启用
lockRenewTime可自动续期锁,防止中途失效。
内容的提问来源于stack exchange,提问作者Vico
相关产品推荐
相关产品推荐

