pg-boss | PostgreSQL 之上的 Node.js 作业队列
pg-boss GitHub 仓库 — 项目首页。
pg-boss 是一个基于 PostgreSQL 构建的 Node.js 作业队列库,slogan 是「Queueing jobs in Postgres from Node.js like a boss」。它利用 PostgreSQL 的 SKIP LOCKED 特性实现消息队列,提供 Exactly-once 投递 保证和数据库事务级别的原子提交。v12.26.1,MIT 协议,GitHub 获 3.8K Star,npm 月下载量 346 万。
什么场景需要它
Node.js 生态中的后台作业队列长期存在一个经典选择困境:
- Bull / BullMQ(基于 Redis):性能出色,但引入 Redis 增加了运维复杂度
- Graphile Worker(基于 PostgreSQL):轻量但功能较少
- Agenda(基于 MongoDB):需要额外维护 MongoDB
pg-boss 的选择是:如果你已经在用 PostgreSQL,就别多加一个基础设施。 直接在同一个数据库里跑作业队列——这意味着事务一致、备份统一、运维减负。
核心能力
Exactly-once 投递
pg-boss 利用 PostgreSQL 的 SKIP LOCKED 实现精确一次投递(exactly-once delivery),避免 RabbitMQ/Redis 队列常见的「至少一次」语义带来的重复处理问题。这对于支付回调、订单处理等不可重入的场景尤其有价值。
丰富的队列语义
| 功能 | 说明 |
|---|---|
| 作业创建 | send()、sendAfter()(延迟)、sendOnce()(幂等去重) |
| Workers | 背压兼容的轮询 Worker,支持 LISTEN/NOTIFY 低延迟通知 |
| Cron 调度 | 标准 cron 表达式定时创建作业 |
| 依赖编排 | 一个作业完成后触发下游作业,支持 DAG 工作流 |
| 优先级队列 | 通过 priority 参数设定作业优先级 |
| 死信队列 | 超出重试次数的作业自动转入死信,支持重新投递(redrive) |
| 自动重试 | 指数退避,可配置重试次数 |
| 速率限制 | 队列级别的速率控制和去重(debouncing) |
| 队列存储策略 | 支持 FIFO、时间窗口、去重等多种存储策略 |
| Pub/Sub | Fan-out 队列关系,一条消息分发到多个消费者 |
ORM 适配器
现有的数据库事务中直接创建作业,无需拆分成两步:
| ORM | 支持 |
|---|---|
| Prisma | ✅ |
| Drizzle | ✅ |
| Knex | ✅ |
| Kysely | ✅ |
扩展生态
| 包 | 用途 |
|---|---|
| pg-boss(核心) | 队列引擎 |
| @pg-boss/dashboard | Web 监控仪表盘,实时查看队列、作业、调度 |
| @pg-boss/proxy | HTTP 代理,支持连接池和平台兼容 |
多后端支持
除了标准 PostgreSQL,pg-boss 还支持:
- CockroachDB — 分布式 SQL
- YugabyteDB — 分布式 PostgreSQL 兼容
- Citus — PostgreSQL 水平扩展
- PGlite — 嵌入式 PostgreSQL,可完全在进程内运行
竞争格局
| 产品 | 后端 | Exactly-once | Cron | 插件生态 | 运维复杂度 |
|---|---|---|---|---|---|
| pg-boss | PostgreSQL | ✅ | ✅ | 仪表盘/代理 | 低(复用 PG) |
| BullMQ | Redis | ❌ | ✅ | ❌ | 中(需维护 Redis) |
| Graphile Worker | PostgreSQL | ✅ | ❌ | ❌ | 低(复用 PG) |
| Agenda | MongoDB | ❌ | ✅ | ❌ | 低(复用 Mongo) |
| Temporal | 自建 | ✅ | ✅ | ❌ | 高(独立集群) |
pg-boss 与 BullMQ 的差异选择本质是 PostgreSQL vs Redis 的取舍:
- 选择 pg-boss:如果你不想新增 Redis,并且需要 Exactly-once 和事务一致性
- 选择 BullMQ:如果你已经在用 Redis,或者对吞吐量有极高性能要求(Redis 的纯内存操作在极端场景下比 PG 快)
适合谁
- 已在使用 PostgreSQL 的 Node.js 项目:不想再维护 Redis
- 需要 Exactly-once 语义:支付、订单处理、通知等不可重入的场景
- 小型到中型队列负载:API/SaaS 产品的后台异步任务(发送邮件、生成报告、数据同步)
- Drizzle/Prisma/Knex 用户:现有事务中直接提交作业
不太适合
- 超大规模队列:日处理千万级作业的场景,BullMQ(Redis)或 Temporal(专用集群)的吞吐量更有保障
- 离开 Node.js 生态:pg-boss 是 Node.js 库,非 JS 运行时需通过 SQL 或 HTTP 代理调用
- 需要可视化编排:复杂 DAG 工作流最好用 Temporal
快速开始
npm install pg-boss
import { PgBoss } from 'pg-boss';
const boss = new PgBoss('postgres://user:pass@localhost/db');
await boss.start();
// 发作业
await boss.send('email-queue', { to: 'user@example.com', template: 'welcome' });
// 消费
await boss.work('email-queue', async ([job]) => {
await sendEmail(job.data);
});