TypeScript 中的队列和后台任务:如何避免生产环境崩溃

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

引言:为什么你的服务器在应该工作时却“休眠”

\n\n

想象一下:用户点击“发送报告”按钮,页面卡顿 30 秒。服务器同步生成 PDF、压缩图片并发送电子邮件——所有操作都是同步的。熟悉吗?如果是,那么你就陷入了阻塞代码的陷阱。

\n\n

在本文中,我们将探讨 TypeScript 中的队列和后台任务 如何解决这个问题。您将学习如何将繁重的工作转移到后台进程,同时保持对错误和可扩展性的控制。本文面向已经熟悉 Node.js 并希望将项目提升到新水平的开发者。

\n\n

我们将讨论 Bull 和 BullMQ 库,涉及 RabbitMQ,并展示 TypeScript 中的真实代码示例。开始吧!

\n\n

什么是任务队列以及为什么需要它

\n\n

任务队列是一种将用户请求与其执行分离的机制。我们不是直接在 HTTP 处理器中处理操作,而是将任务发送到队列,后台工作进程会获取并异步执行它。

\n\n

典型使用场景

\n
    \n
  • 发送电子邮件和推送通知
  • \n
  • 生成 PDF、图像、视频
  • \n
  • 数据解析和网页抓取
  • \n
  • 在线商店订单处理
  • \n
  • 批量计算和报告
  • \n
\n\n

没有队列,您的应用程序可能会在高负载下崩溃。有了队列,您将获得 容错性(如果工作进程崩溃,任务不会丢失)和 可扩展性(可以运行 10 个工作进程而不是一个)。

\n\n

Bull 和 BullMQ:Node.js 的强大队列

\n\n

Bull 是 Node.js 生态系统中用于处理队列的最流行库。它基于 Redis,并原生支持 TypeScript。BullMQ 是其继任者,更现代,支持沙箱(隔离进程)和高级管理。

\n\n

安装和基本配置

\n
npm install bullmq ioredis\nnpm install -D @types/bull
\n\n

用 TypeScript 创建一个队列和工作进程:

\n\n
// queue.ts\nimport { Queue } from 'bullmq';\n\nconst connection = {\n  host: 'localhost',\n  port: 6379,\n};\n\nexport const emailQueue = new Queue('email', { connection });
\n\n
// worker.ts\nimport { Worker } from 'bullmq';\nimport { sendEmail } from './emailService';\n\nconst worker = new Worker('email', async job => {\n  const { to, subject, body } = job.data;\n  await sendEmail(to, subject, body);\n  console.log(`Email sent to ${to}`);\n}, { connection });\n\nworker.on('completed', job => {\n  console.log(`Job ${job.id} completed`);\n});\n\nworker.on('failed', (job, err) => {\n  console.error(`Job ${job.id} failed: ${err.message}`);\n});
\n\n

现在,我们可以在应用程序的任何位置添加任务:

\n\n
import { emailQueue } from './queue';\n\nawait emailQueue.add('send-welcome', {\n  to: 'user@example.com',\n  subject: '欢迎!',\n  body: '感谢您的注册...'\n});
\n\n

很简单,对吧?但这只是开始。BullMQ 提供了更多功能。

\n\n

BullMQ 的高级功能

\n
    \n
  • 重试 — 如果任务失败,可以在 N 秒后自动重新启动。
  • \n
  • 延迟执行 — 将任务推迟到特定时间。
  • \n
  • 优先级 — 紧急任务优先处理。
  • \n
  • 事件 — 可以订阅进度、完成、错误事件。
  • \n
  • 沙箱 — 在隔离进程中执行代码(安全 + 干净)。
  • \n
\n\n

带有重试和延迟的示例:

\n\n
await emailQueue.add('send-invoice', {\n  invoiceId: 123,\n  email: 'client@example.com'\n}, {\n  attempts: 5,\n  backoff: { type: 'expon                

博客

书籍推荐