PGMQ:一个基于PostgreSQL的轻量级消息队列

PGMQ 是一个基于 PostgreSQL 实现的轻量级消息队列工具,可以实现类似 AWS SQS 或者 RSMQ(Redis Simple Message Queue)的接口和功能。

PGMQ 完全使用 SQL 语句实现,遵循 PostgreSQL 开源协议,代码托管在 GitHub:

https://github.com/pgmq/pgmq

功能特性

  • 轻量级:PGMQ 不需要后台工作进程或者外部组件依赖,只需要安装一个 PostgreSQL 扩展插件,支持 PostgreSQL 14+。
  • 可靠性:PGMQ 能够确保在可见性超时之内精确传递一次消息到消费者。
  • API:兼容 AWS SQS 以及 RSMQ 消息队列 API。
  • FIFO:遵循 FIFO 原则(First-In-First-Out),支持消息分组和顺序处理。
  • 分区队列:通过集成 pg_partman 插件按照时间或者 ID 自动分表存储消息,冷数据可以自动淘汰。
  • 性能提升:通过创建非日志表(create_unlogged)可以极大地提高消息队列处理时间,但是可能在系统崩溃时丢失队列数据。
  • 显式删除:消息可以一直存储在队列中,直到明确删除为止。
  • 消息重放:消息可以被归档,用于长期保留和重放。
  • 客户端驱动:官方提供 Rust、Python 驱动,社区提供 Dart、Go、Elixir、Java、Kotlin、JavaScript、.NET、Ruby、PHP 等语言驱动。

下载安装

推荐使用 Docker 进行快速体验:

bash 复制代码
docker run -d --name pgmq-postgres -e POSTGRES_PASSWORD=postgres -p 5432:5432 ghcr.io/pgmq/pg18-pgmq:v1.10.0

然后使用客户端工具连接到 PostgreSQL:

bash 复制代码
# Connect to Postgres
psql postgres://postgres:postgres@0.0.0.0:5432/postgres

-- create the extension in the "pgmq" schema
CREATE EXTENSION pgmq;

使用示例

创建消息队列

PGMQ 对于消息队列的所有操作都使用 SQL 语句完成,以下语句可以创建一个名为 my_queue 的消息队列:

sql 复制代码
-- creates the queue
SELECT pgmq.create('my_queue');

 create
-------------

(1 row)

每个消息队列都对应 pgmq 模式下的一个表,表的命名规则为 q_ 前缀加上消息队列名。以上语句创建的消息队列表名为 pgmq.q_my_queue。

发送消息

接下来我们给这个消息队列发送一个消息:

sql 复制代码
-- messages are sent as JSON
SELECT * from pgmq.send(
  queue_name  => 'my_queue',
  msg         => '{"foo": "bar1"}'
);

 send
-----------
         1
(1 row)

消息内容使用 JSON 格式,查询返回的是消息编号。

发送消息时还可以指定一个延迟时间(秒数或者时间戳),在此之前该消息对消费者不可见。

sql 复制代码
-- Optionally provide a delay
-- this message will be on the queue but unable to be consumed for 5 seconds
SELECT * from pgmq.send(
  queue_name => 'my_queue',
  msg        => '{"foo": "bar2"}',
  delay      => 5
);

 send
-----------
         2
(1 row)

读取消息

消费者可以读取队列中的消息:

sql 复制代码
SELECT * FROM pgmq.read(
  queue_name => 'my_queue',
  vt         => 30,
  qty        => 2
);

 msg_id | read_ct |          enqueued_at          |         last_read_at          |              vt               |     message     | headers 
--------+---------+-------------------------------+-------------------------------+-------------------------------+-----------------+---------
      1 |       1 | 2026-01-23 20:27:21.7741-06   | 2026-01-23 20:27:31.605236-06 | 2026-01-23 20:28:01.605236-06 | {"foo": "bar1"} | 
      2 |       1 | 2026-01-23 20:27:26.505063-06 | 2026-01-23 20:27:31.605252-06 | 2026-01-23 20:28:01.605252-06 | {"foo": "bar2"} | 

以上查询读取了 2 条消息,并且使其在接下来的 30 秒内不可见。如果这些消息在 30 秒内不被删除或者归档,将会重新可见并且可以被其他消费者读取。

弹出消息

弹出(POP)表示消费者读取消息之后立即从队列中删除相应的消息:

sql 复制代码
-- Read a message and immediately delete it from the queue. Returns an empty record if the queue is empty or all messages are invisible.
SELECT * FROM pgmq.pop('my_queue');

 msg_id | read_ct |         enqueued_at         |         last_read_at          |              vt               |     message     | headers 
--------+---------+-----------------------------+-------------------------------+-------------------------------+-----------------+---------
      1 |       1 | 2026-01-23 20:27:21.7741-06 | 2026-01-23 20:27:31.605236-06 | 2026-01-23 20:28:01.605236-06 | {"foo": "bar1"} | 

归档消息

归档消息意味着从队列中删除消息,并且将其插入归档表中:

sql 复制代码
-- Archive message with msg_id=2.
SELECT pgmq.archive(
  queue_name => 'my_queue',
  msg_id     => 2
);

 archive
--------------
 t
(1 row)

消息队列 my_queue 对应的归档表为 pgmq.a_my_queue。

删除消息

使用 pgmq.delete 函数从队列中删除消息:

sql 复制代码
SELECT pgmq.delete('my_queue', 2);

 delete
-------------
 t
(1 row)

删除消息队列

使用以下语句删除消息队列 my_queue:

sql 复制代码
SELECT pgmq.drop_queue('my_queue');

 drop_queue
-----------------
 t
(1 row)

更多接口可以参考文档:https://pgmq.github.io/pgmq/latest/

相关推荐
Juchecar3 小时前
翻译:2026年了,直接用 PostgreSQL 吧
postgresql
l1t5 小时前
利用Docker安装PostgreSQL 19 dev版
docker·postgresql·容器
、BeYourself5 小时前
PostgreSQL 安装中文全文检索插件zhparser扩展
数据库·postgresql·全文检索
dcmfxvr5 小时前
WESFDS
postgresql
Andy Dennis18 小时前
一文了解异步通信基础消息队列之RabbitMQ(一)
分布式·消息队列·rabbitmq·erlang·异步任务
数据知道1 天前
PostgreSQL:防止 WAL 文件撑爆磁盘的策略(WAL归档配置)
数据库·postgresql
像少年啦飞驰点、1 天前
零基础入门 RabbitMQ:从消息队列是什么到 Spring Boot 实战收发消息
java·spring boot·微服务·消息队列·rabbitmq·异步编程
竟未曾年少轻狂1 天前
Spring Boot 项目集成 Redis
java·spring boot·redis·缓存·消息队列·wpf·redis集群