查看: 66|回复: 0

Node.js 轻量任务队列:数据库表与失败重试设计

[复制链接]
发表于 1 小时前 | 显示全部楼层 |阅读模式
独立产品接入 AI、导出 PDF、发送邮件或同步文件后,后台任务很快会出现。早期不一定需要复杂队列系统,可以用数据库表加 worker 起步。这个方案不追求时髦,重点是把任务状态、失败重试、幂等和可观察性写清楚,让系统可理解、可修复、可迁移。

一、任务状态机不要只用一个 done 字段

后台任务至少要区分 pending、running、succeeded、failed、retrying、canceled。状态清楚后,界面能告诉用户任务处于什么阶段,开发者也便于定位问题。原文给出的状态流转是:pending 进入 running;running 可到 succeeded、retrying 或 failed;retrying 再回到 running;pending 也可被取消为 canceled;succeeded 和 failed 为结束状态。导出任务尤其需要这种状态表达:用户点击导出后,可能经历模型整理、渲染、上传文件等阶段,只显示转圈不够稳定,显示“正在生成”“正在上传”“可下载”会更清楚。

二、用 jobs 表承载早期队列

早期可用一张 jobs 表承载任务,关键是通过加锁领取任务,避免多个 worker 同时处理同一条记录。原文表结构如下:
  1. CREATE TABLE jobs (
  2. id TEXT PRIMARY KEY,
  3. type TEXT NOT NULL,
  4. payload JSONB NOT NULL,
  5. status TEXT NOT NULL,
  6. attempts INTEGER NOT NULL DEFAULT 0,
  7. run_after TIMESTAMP NOT NULL DEFAULT now(),
  8. locked_at TIMESTAMP,
  9. last_error TEXT,
  10. created_at TIMESTAMP NOT NULL DEFAULT now(),
  11. updated_at TIMESTAMP NOT NULL DEFAULT now()
  12. );
复制代码
Worker 轮询时只取 pending 或到期 retrying。数据库支持 FOR UPDATE SKIP LOCKED 时,可以用它更安全地并发领取。小系统也要认真处理并发,否则上线后可能出现重复导出、重复扣额度、重复发邮件。

三、失败重试要有上限和退避

AI 调用、对象存储、邮件服务都可能临时失败,重试必要但不能无限。指数退避和最大次数是最低要求。原文示例:
  1. function nextRunAfter(attempts: number) {
  2. const seconds = Math.min(60 * 10, Math.pow(2, attempts) * 10);
  3. return new Date(Date.now() + seconds * 1000);
  4. }
  5. function shouldRetry(error: Error) {
  6. return !error.message.includes("invalid_api_key");
  7. }
复制代码
不是所有错误都适合重试。参数错误、权限错误、额度不足应快速失败,并给用户可理解提示;网络超时、第三方 5xx、临时限流才适合退避重试。示例中 invalid_api_key 被排除在重试之外。

四、幂等比队列技术更重要

后台任务容易被忽略的是幂等。任务可能因超时重试,也可能 worker 崩溃后重新执行。导出重复跑只是浪费资源,支付或扣额度重复执行就是事故。原文给出按任务定义幂等键的思路:
  1. idempotency_rules:
  2. export_markdown:
  3. key: project_id + export_format + content_version
  4. duplicate_behavior: return_existing_file
  5. ai_generation:
  6. key: request_id
  7. duplicate_behavior: return_previous_result
  8. billing_charge:
  9. key: provider_event_id
  10. duplicate_behavior: ignore_duplicate
复制代码
每类任务都应定义幂等键,队列可以简单,但幂等策略不能空白,这是小产品从“能跑”走向“可靠”的分界线。

五、适用场景与小结构价值

原文场景包括独立产品接入 AI、导出 PDF、发送邮件、同步文件。用数据库表、worker、状态机、退避重试和幂等键,可以支撑不少早期后台任务。表结构中的 attempts、locked_at、last_error 等字段也为排查提供抓手。相比一开始引入重型队列,先把失败处理写清楚更重要。系统越小,每个边界越要让人看得懂;逻辑集中在表结构和 worker 中,也更便于后续修复与迁移。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

指导单位

江苏省公安厅

江苏省通信管理局

浙江省台州刑侦支队

DEFCON GROUP 86025

Hacking Group 021A

旗下站点

态势感知中心

应急响应中心

红盟安全

联系我们

官方QQ群:112851260

官方邮箱:security#ihonker.org(#改成@)

官方核心成员

关注微信公众号

Archiver|手机版|小黑屋| ( 沪ICP备2021026908号 )

GMT+8, 2026-10-26 16:24 , Processed in 0.027517 second(s), 28 queries , Gzip On.

Powered by ihonker.com

Copyright © 2015-现在.

  • 返回顶部