You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js中Bull队列结合cron定时任务生产环境仅触发单个作业问题

根因分析
  1. queue.add是异步方法,你当前在cron的onTick回调中没有等待两个add操作完成,生产环境Redis网络延迟高于本地,极易出现第二个任务还没成功写入Redis,tick事件执行上下文就被销毁,导致任务漏发。
  2. 队列配置已经开启了removeOnComplete: true,Bull会自动删除执行完成的任务,你在completed事件中额外加了一遍手动删除逻辑,高并发场景下会出现未执行的任务被误删的问题。
  3. 你代码中queue.process传入的concurrency变量如果未显式赋值,Bull默认并发数为1,同一时间只能处理1个任务,再加上生产环境的异常逻辑干扰,就会出现两个任务只执行一个的情况。
  4. 你没有对add操作做异常捕获,无法判断生产环境是否存在第二个任务写入队列时报错的情况。
解决方案

1. 改造cron的onTick逻辑,等待任务全部入队

将onTick改为异步函数,用Promise.all等待两个任务都成功写入Redis再结束回调,同时添加异常捕获:

const cron = new CronJob({
  cronTime: '* * * * *',
  onTick: async function() {
    workerLogger.info('Pushing test to queue...');
    try {
      await Promise.all([
        queue.add('test'),
        queue.add('healthCheckPing', { jobName: 'test' })
      ]);
    } catch (err) {
      workerLogger.error('Add job failed: ', err);
    }
  },
  start: true,
  timeZone: 'Africa/Lagos',
});

2. 移除completed事件中的冗余删除逻辑

删除completed回调中手动删任务的代码,避免误删未执行的任务,修改后回调逻辑如下:

.on('completed', async(job, result) => {
  workerLogger.info(`Job ID: ${job.id}, Result: ${result}`);
})

3. 显式设置合理的并发数

确认concurrency变量的赋值≥2,或者直接显式传入数值:

// 并发数设为2可同时处理2个任务,可根据实际需求调大
queue.process('healthCheckPing', 2, function(job, done) {
  jobs.healthCheckPing(job.data, done);
});

queue.process('test', 2, function(job, done) {
  jobs.test(job.data, done);
});

4. 确认生产环境配置

  • 检查Redis连接是否稳定,有没有超时、限流规则拦截写入请求
  • 确认CronJob只初始化了一次,避免重复实例化导致的逻辑冲突
  • 检查PM2日志,确认没有未捕获的异常导致进程重启、任务丢失

内容的提问来源于stack exchange,提问作者nipek

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 21:36:02