用途
PgQue 是一个纯 PL/pgSQL 实现的 Postgres 队列,重新实现了经过实战检验的 PgQ(Skype/Postgres)架构。它面向需要在 Postgres 内部实现事件队列、且不希望引入 C 扩展或额外中间件的场景,可用于生产者/消费者模式、事件扇出、重试与死信处理等。
主要能力
- 零膨胀:事件存储在轮换表中,通过 TRUNCATE 而非 DELETE 清理,不产生死元组。
- 快照式批处理:通过 Tick 周期性关闭一批事件,订阅者原子消费整批。
- 原生扇出:一个队列可注册多个消费者,每个消费者独立获得每批事件的完整副本。
- 纯 SQL 安装:单个 SQL 文件即可安装,兼容 Postgres 14+ 及托管服务(RDS、Aurora、Cloud SQL、Supabase、Neon)。
- 角色与权限:提供 pgque_reader(只读)、pgque_writer(生产者与消费者)、pgque_admin(运维与迁移)三种角色。
- 监控与内省:提供 get_queue_info、get_consumer_info、get_batch_info、version 等函数查看队列深度、消费者滞后、批次详情。
- 重试与死信:支持 event_retry 安排延迟重试,配合 maint 维护任务处理重试调度。
使用方式
安装:克隆仓库后,通过 psql 以单事务方式执行 sql/pgque.sql;也可在 psql 会话中 begin; \i sql/pgque.sql; commit;。
启动 Ticker:推荐使用 pg_cron,执行 select pgque.start(); 创建 ticker(每秒)和 maintenance(每 30 秒)任务;无 pg_cron 时需外部调度器每秒调用 pgque.ticker()、每 30 秒调用 pgque.maint()。注意:没有运行中的 ticker,消费者将看不到任何事件。
核心 API(现代风格):
- 创建队列:SELECT pgque.create_queue('orders');
- 订阅消费者:SELECT pgque.subscribe('orders', 'order-processor');
- 发送事件:SELECT pgque.send('orders', 'new_order', '{"order_id": 42, "amount": 99.99}'); 或使用 send_batch 批量发送。
- 接收与确认:SELECT * FROM pgque.receive('orders', 'order-processor'); 处理后 SELECT pgque.ack('orders', 'order-processor', :batch_id); 失败可 SELECT pgque.nack(...)。
- 取消订阅:SELECT pgque.unsubscribe('orders', 'order-processor');
低层 PgQ API:insert_event、register_consumer、next_batch、get_batch_events、finish_batch、event_retry、unregister_consumer 等,映射原始 PgQ 原语。
配置与调优:可通过 cron.alter_job 调整 tick 间隔;使用 pgque.force_tick('orders') 或 pgque.ticker() 强制立即 tick;可关闭 cron.log_run 或定期清理 cron.job_run_details 以控制日志。若 pg_cron 与 PgQue 位于不同数据库,可使用 cron.schedule_in_database。
常见模式:事务性入队(事件随业务事务一起提交)、队列深度检查、列出消费者滞后。
故障排查:消费者收不到事件通常因 ticker 未运行,可检查 last_tick 或手动执行 pgque.ticker();重试事件未重现需确认 pgque.maint() 每约 30 秒运行。
适用场景
- 在 Postgres 内部构建事件驱动架构,避免引入外部消息中间件。
- 需要多消费者独立消费同一事件流的扇出场景(如分析、通知、审计)。
- 对死元组膨胀敏感、需要持续负载下可预测性能的队列。
- 运行在托管 Postgres 服务上、无法安装 C 扩展的环境。
限制
- 端到端投递延迟约 1–2 秒(一个 tick 间隔加轮询),不适合超低延迟场景。
- 必须持续运行 ticker,否则消费者看不到事件。
- 需要 Postgres 14+。
- 升级/重装路径仍在稳定中,安全重装需先执行 pgque_uninstall.sql 再重新安装。
- 资料未提供收费、价格或平台限制等更多信息。