Skip to content

[Bug] 定时日志清理任务在 Bull 队列中执行失败:Missing process handler for job type auto-cleanup #1450

Closed

Description

@sususu98

问题描述

当在系统设置中开启自动日志清理功能(enableAutoCleanup: true)后,每天定时触发的日志清理任务会 100% 执行失败,导致历史过期日志无法按预期自动清理并在数据库中持续堆积。

错误日志

在 Redis 的 bull:log-cleanup:failed 失败任务列表中记录如下堆栈:

failedReason: Missing process handler for job type auto-cleanup
stacktrace: [
  "Error: Missing process handler for job type auto-cleanup\n    at Queue.processJob (/app/node_modules/bull/lib/queue.js:1207:7)\n    at process.processTicksAndRejections (node:internal/process/task_queues:104:5)"
]

根因分析

问题出在 src/lib/log-cleanup/cleanup-queue.ts 中的任务注册与处理器声明不匹配:

  1. 任务添加时指定了名称(第 150 行附近):

    await queue.add(
      "auto-cleanup",
      {
        retentionDays,
        conditions: {},
        batchSize: settings.cleanupBatchSize ?? 10000,
      },
      {
        repeat: {
          cron: settings.cleanupSchedule ?? "0 2 * * *",
        },
      }
    );
  2. 处理器注册时使用了默认匿名处理器(第 68 行附近):

    function setupQueueProcessor(queue: Queue.Queue): void {
      queue.process(async (job: Job) => {
        // ...
      });
    }
  3. Bull 队列机制:
    在 Bull.js 中,通过 queue.add('jobName', data) 添加的命名任务,必须通过 queue.process('jobName', handler) 或 queue.process('*', handler) 注册对应的处理器。使用匿名的 queue.process(handler) 只会处理未命名的默认任务,当处理名为 auto-cleanup 的任务时会直接抛出 Missing process handler for job type auto-cleanup。

建议修复

将 src/lib/log-cleanup/cleanup-queue.ts 中的 setupQueueProcessor 修改为支持通配或显式指定 job name:

--- a/src/lib/log-cleanup/cleanup-queue.ts
+++ b/src/lib/log-cleanup/cleanup-queue.ts
@@ -68,7 +68,7 @@ function setupQueueProcessor(queue: Queue.Queue): void {
   /**
    * 处理清理任务
    */
-  queue.process(async (job: Job) => {
+  queue.process("*", async (job: Job) => {
     const retentionDays: number = job.data.retentionDays ?? 30;
     const beforeDate = new Date();
     beforeDate.setDate(beforeDate.getDate() - retentionDays);

Activity

  1. github-actions commented on Aug 25, 2026

    @github-actions
    Contributor

    感谢你提交这份问题报告。经过对代码库和 Bull 4.16.5 源码的核查,你的根因分析完全正确,以下是验证结果:

    分析确认

    1. 处理器注册与任务名称不匹配(已确认)

    • src/lib/log-cleanup/cleanup-queue.ts:150-151 — 定时任务以命名方式添加:queue.add("auto-cleanup", { ... }, { repeat: { cron: ... } })
    • src/lib/log-cleanup/cleanup-queue.ts:71 — 处理器以匿名方式注册:queue.process(async (job: Job) => { ... })

    2. Bull 库行为(基于 bull 4.16.5 源码验证,与 package.json 中 "bull": "^4.16.5" 一致)

    • lib/queue.js 的 Queue.prototype.process:单函数签名 process(handler) 会把处理器注册到 Job.DEFAULT_JOB_NAME(即 '__default__',见 lib/job.js:11)之下,而不是任意任务名

    • lib/queue.js:1203-1209 的 processJob 处理器查找逻辑:

      const handler = this.handlers[job.name] || this.handlers['*'];
      if (!handler) {
        return handleFailed(new Error('Missing process handler for job type ' + job.name));
      }

      抛错位置正好是 queue.js:1207,与你提供的堆栈 /app/node_modules/bull/lib/queue.js:1207:7 完全吻合。

    3. 影响范围

    • 该问题自功能引入时(commit d669bbfa,"feat: 添加货币显示配置和日志自动清理功能")即存在:任务一直以 auto-cleanup 名称添加,处理器一直是匿名注册。也就是说开启 enableAutoCleanup 后,定时清理路径从未成功执行过
    • 队列配置 attempts: 3(cleanup-queue.ts:46,指数退避首次延迟 60s),每次 cron 触发会重试 3 次后全部失败进入 failed 列表(removeOnFail: 50),与你在 bull:log-cleanup:failed 中观察到的记录一致
    • 手动清理不受影响:POST /api/admin/log-cleanup/manual(src/app/api/admin/log-cleanup/manual/route.ts:85)直接调用 cleanupLogs,不经过队列
    • 其他两个 Bull 队列不受此问题影响:notification-queue 的任务均为未命名添加(数据对象作为 add 的第一个参数),与匿名处理器匹配;reset-queue 使用了正确的命名注册方式

    建议修复方案验证

    你提议的 queue.process("*", handler) 是有效的:

    • 运行时:this.handlers[job.name] || this.handlers['*'] 中的 '*' 通配符分支(queue.js:1203)会匹配命名任务
    • 类型:bull 的类型声明(index.d.ts:652-653)提供了 process(name: string, callback) 重载,在 TypeScript 下合法

    另一种等价写法是显式指定任务名,代码库中已有正确示例可参考:

    • src/lib/user-statistics-reset/reset-queue.ts:143 — resetQueue.process(RESET_JOB_NAME, processUserStatisticsReset),与其 queue.add(RESET_JOB_NAME, ...)(第 363、390 行)严格匹配

    由于该队列中只存在 auto-cleanup 一种任务名,两种写法均可行。另外需要注意:处理器注册发生在 getCleanupQueue() 首次创建队列实例时(单例,cleanup-queue.ts:20-62),因此修复部署后需要重启应用才会生效。


    Automated response from Claude AI

  2. github-actions commented on Sep 26, 2026

    @github-actions
    Contributor

    This issue has been automatically marked as stale because it has not had any activity in the last 30 days.

    If this issue is still relevant:

    • Please comment to keep it open
    • Add any new information that might help resolve it

    This issue will be automatically closed in 14 days if there is no further activity.

  3. github-actions commented on Oct 13, 2026

    @github-actions
    Contributor

    This issue has been automatically closed due to inactivity.

    If you believe this issue is still relevant, please feel free to reopen it with additional information.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:corebugSomething isn't workingstaleIssue has had no activity for 30+ days

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions