队列?不妨试试pgmq

0 阅读7分钟

在现代分布式系统中,消息队列(Message Queue)扮演着至关重要的角色。作为一名经验丰富的开发者,我在工作中深度使用过 RabbitMQ、Kafka 等主流消息中间件,它们各自有着独特的优势和适用场景。然而,对于许多中小型项目来说,引入这些重量级中间件可能带来额外的复杂性和运维成本。

最近,我发现了一个基于 PostgreSQL 的消息队列插件——pgmq,以及围绕它构建的 Spring Boot 集成项目 pgsql-ext-spring。这个组合为小规模、轻量级的消息队列需求提供了一个优雅的解决方案。

一、pgmq 与其他 MQ 的对比分析

1.1 传统消息中间件的优势与不足

RabbitMQ

  • 优势:成熟的 AMQP 协议支持,丰富的 Exchange 类型,强大的路由能力
  • 不足:需要单独的 Erlang 运行时环境,集群配置相对复杂

Kafka

  • 优势:极高的吞吐量,支持海量数据流处理,完善的生态
  • 不足:配置复杂,资源消耗较大,延迟相对较高

1.2 Kafka 与 pgmq 对比表格

特性Kafkapgmq
架构类型独立的分布式消息系统PostgreSQL 扩展插件
性能极高吞吐量(百万级/秒)中等吞吐量(万级/秒)
延迟毫秒级毫秒到秒级
消息持久化基于磁盘,可配置保留时间基于数据库表,可长期存储
事务支持有限的事务支持完整的 PostgreSQL ACID 事务
适用场景大数据流处理,高吞吐量场景中小型应用,强一致性要求场景

1.2 pgmq 的定位与特点

pgmq 是 PostgreSQL 的一个扩展插件,它将队列功能直接集成到数据库中:

优势

  1. 零中间件依赖:无需部署额外的消息中间件服务
  2. 强一致性保证:利用 PostgreSQL 的 ACID 特性,确保消息的可靠性
  3. 简化架构:对于已经使用 PostgreSQL 的项目,无需引入新的技术栈
  4. 运维简单:队列数据与业务数据统一管理,监控方便

不足与适用场景

  1. 性能限制:相比 Kafka、RocketMQ 等专用消息中间件,吞吐量有限
  2. 功能相对基础:缺少复杂路由、消息追踪等高级特性
  3. 最佳适用场景
    • 中小型项目,日处理消息量在百万级以下
    • 对消息可靠性要求较高的场景
    • 希望简化技术栈,减少运维成本的团队
    • 已在使用 PostgreSQL,希望避免引入新中间件的项目

二、为什么选择 pgmq?

2.1 原子性优势

pgmq 最大的优势在于其与 PostgreSQL 的深度集成带来的原子性保证:

-- pgmq 操作与业务操作可以在同一个事务中
BEGIN;
-- 业务操作
INSERT INTO orders (id, amount) VALUES (1, 100.00);
-- 发送消息
SELECT pgmq.send('order_created', jsonb_build_object('order_id', 1, 'amount', 100.00));
COMMIT;

这种原子性保证了业务操作与消息发送要么同时成功,要么同时失败,避免了分布式事务的复杂性。

2.2 轻量化部署

对于小项目来说,pgmq 的轻量化特性极具吸引力:

  1. 零额外部署:无需安装和配置额外的消息中间件
  2. 学习成本低:开发者只需了解基本的 SQL 操作
  3. 资源消耗小:共享 PostgreSQL 的资源,无需为消息队列单独分配资源
  4. 监控统一:队列指标可以通过 PostgreSQL 的监控系统统一采集

三、pgsql-ext-spring 项目的优势

pgsql-ext-spring 是一个基于 Spring Boot 4 和 JDK 21+ 的 pgmq 集成框架,它让使用 pgmq 变得更加简单和高效。

3.1 注解式开发,类似 RabbitMQ/Kafka

与 RabbitMQ 的 @RabbitListener 和 Kafka 的 @KafkaListener 类似,pgsql-ext-spring 提供了简洁的 @PgmqListener 注解来声明消息处理器。开发者只需在方法上添加相应注解,即可实现消息的自动监听和处理。具体的使用方法和代码示例请参考项目 README:github.com/super-npc/p…

3.2 虚拟线程支持

项目采用 JDK 21+ 的虚拟线程(Virtual Threads)技术,大幅提升了并发处理能力。以下是使用虚拟线程实现的监听逻辑:

3.3 自动表管理

项目会自动创建和管理 pgmq 所需的表结构,无需手动执行 SQL 脚本。

四、UI 管理界面

pgsql-ext-spring 提供了一个简洁的 Web UI 界面,方便开发者管理队列:

image.png

image.png

4.1 队列查看与管理

  1. 查看已有队列:通过动态表名技术展示所有已创建的队列
  2. 队列状态监控
    • 待处理消息数量
    • 已处理消息数量
    • 处理失败消息数量
    • 消息处理延迟统计

4.2 队列操作

  1. 创建队列

    • 普通队列:基础的消息队列
    • 延迟队列:支持延迟投递的消息队列
    • 日志队列:专门用于日志收集的队列
    • 死信队列:处理失败消息的队列
  2. 队列归档

    • 自动归档已处理的消息
    • 可配置的归档策略(按时间、按数量)
    • 归档数据查询和导出
  3. 消息操作

    • 查看队列中的消息内容
    • 手动重试失败的消息
    • 删除无效消息
    • 批量操作支持

五、监听模式与使用示例

pgsql-ext-spring 目前支持两种监听模式:

5.1 轮询模式(Polling Mode)

这是最基础的监听模式,通过定时轮询数据库表来获取新消息。适用于对实时性要求不高的场景。

5.2 通知模式(Notify Mode)

利用 PostgreSQL 的 LISTEN/NOTIFY 机制,实现实时消息推送。当有新消息到达时,PostgreSQL 会主动通知应用程序,减少轮询开销。

5.3 使用说明

项目采用 JDK 21+ 的虚拟线程(Virtual Threads)技术,大幅提升了并发处理能力。具体的使用方法和代码示例请参考项目 README:github.com/super-npc/p…

六、一键 Docker 部署

pgsql-ext-spring 提供了完整的 Docker Compose 配置,可以快速搭建开发环境:

services:
   redis:
      restart: always
      image: redis
      ports:
         - 6379:6379
      networks:
         - npc_net
   postgres:
      image: supernpc/pgsql:18
      networks:
         - npc_net
      environment:
         POSTGRES_USER: root
         POSTGRES_PASSWORD: root
      ports:
         - 5432:5432
   pgsql-ext-admin:
      image: supernpc/pgsql-ext-admin:latest
      container_name: pgsql-ext-admin
      networks:
         - npc_net
      environment:
         - TZ=Asia/Shanghai
         - spring.profiles.active=prd
         - feign.secret=123456 # 如果未使用微服务调用,固定默认值123456即可
         - password=123456 # 有使用加密功能,参考Jasypt实现
      ports:
         - 9019:9019
networks:
   npc_net:
      external: true

部署步骤:

  1. 克隆项目:
git clone https://github.com/super-npc/pgsql-ext-spring.git
cd pgsql-ext-spring
  1. 启动服务:
docker-compose up -d
  1. 访问服务:

  2. 查看日志:

docker-compose logs -f pgmq-ext-spring

七、总结

pgmq 结合 pgsql-ext-spring 项目,为中小型项目提供了一个简单、可靠、易用的消息队列解决方案。它特别适合以下场景:

  1. 技术栈简化:对于已经使用 PostgreSQL 的项目,避免引入新的中间件
  2. 强一致性要求:需要保证业务操作与消息发送原子性的场景
  3. 运维成本敏感:希望降低系统复杂性和运维负担的团队
  4. 快速原型开发:需要快速搭建消息队列功能的开发阶段

虽然 pgmq 在性能上无法与 Kafka、RocketMQ 等专用中间件相比,但对于大多数中小型应用来说,它的性能已经完全足够。更重要的是,它带来的架构简化和运维便利是其他方案难以比拟的。

pgsql-ext-spring 项目的注解式开发模式和虚拟线程支持,让开发者能够以极低的成本享受到类似 RabbitMQ/Kafka 的开发体验。对于追求简洁、高效的团队来说,这无疑是一个值得尝试的选择。

适用建议

  • 日消息量 < 100 万:pgmq 是最佳选择
  • 100 万 < 日消息量 < 1000 万:可以尝试 pgmq,根据实际性能测试决定
  • 日消息量 > 1000 万:建议使用专业消息中间件

在技术选型时,我们应该避免"为了用而用"的思维,选择最适合当前业务规模和技术团队能力的方案。pgmq 正是这种务实思维的产物,它为消息队列领域提供了一个新的、有价值的选项。