想用队列?但我一个中间件都不想引入:PGMQ 超简单使用

想用队列?但我一个中间件都不想引入:PGMQ 超简单使用

你有没有这种精神洁癖:

想要"消息队列"的快乐,但不想再引入一个"队列中间件"来占内存、占运维、占你周末?

这时候,PGMQ 就像你家楼下那位"热心但不多话的快递柜":

你把包裹(消息)放进去,它负责存着;你来取,它负责按规则给你。

不搞花活,不拉群,不开会------主打一个"我在 PostgreSQL 里把队列给你安排了"。

本文基于 PGMQ 的二开开源项目:

并且所有示例代码严格来自该项目 README:

你要的核心卖点:@PgMqListener 一把梭,两种消费模式

这套用法里,最爽的就是:你几乎不用写"队列消费框架代码"。

你只要用 @PgMqListener 标记方法,它就能让你在两种订阅模式里随便切换:

模式 subscribeType 一句话人话
广播模式 BROADCASTING 所有消费者都能收到同一条消息(像班级群发通知)
集群模式 CLUSTERING 一条消息只会分配给一个消费者(像排队取号,谁叫到谁办)

接下来我用"拟人比喻"给你讲清楚:

  • 广播模式:消息像"八卦",传出去后大家都得知道
  • 集群模式:消息像"外卖订单",只需要一个人去送,别来一堆骑手围观

广播模式:消息是"全员通知",每个消费者都要读一遍

想象一下:你在公司群里发了一句"今晚团建自愿参加"。

然后两个同事(listener1、listener2)都看到了------这就是广播。

下面代码严格来自 README(原样照抄):

java 复制代码
@Slf4j
@Component
@RequiredArgsConstructor
public class DemoBroadcastingHandler {

    @PgMqListener(subscribeType = SubscribeType.BROADCASTING, bindMsgDto = DemoMsgDto.class)
    public void listener1(DemoMsgDto msg) {
        log.info("广播.listener1: {}", msg);
    }

    @PgMqListener(subscribeType = SubscribeType.BROADCASTING, bindMsgDto = DemoMsgDto.class)
    public void listener2(DemoMsgDto msg) {
        log.info("广播.listener2: {}", msg);
    }
}

看点就三个字:都能收

  • 同一个队列/同一类消息
  • 两个方法都用 @PgMqListener 订阅
  • subscribeType = SubscribeType.BROADCASTING
    结果就是:两位"打工人消费者"都会处理到消息

集群模式:消息是"派单任务",只要一个消费者处理就行

再想象一下:你点了份外卖。

平台派单时不会把同一单同时派给两个骑手,不然你会收到两份外卖,然后你钱包当场去世。

下面代码同样严格来自 README(原样照抄):

java 复制代码
@Slf4j
@Component
@RequiredArgsConstructor
public class DemoClusteringHandler {

    @PgMqListener(subscribeType = SubscribeType.CLUSTERING, bindMsgDto = DemoMsgDto.class)
    public void listener1(DemoMsgDto msg) {
        log.info("集群.listener1: {}", msg);
    }

    @PgMqListener(subscribeType = SubscribeType.CLUSTERING, bindMsgDto = DemoMsgDto.class)
    public void listener2(DemoMsgDto msg) {
        log.info("集群.listener2: {}", msg);
    }
}

这段的精髓也很直白:只给一个人

  • 两个消费者都在"候场"
  • 但 subscribeType = SubscribeType.CLUSTERING 会让消息只分配给其中一个
    结果就是:不会重复消费(至少从模式设计上,就是奔着避免"群殴同一条消息"去的)

你可能会问:我到底该选哪个?

按"人类社会运作方式"来选就行:

  • 选 BROADCASTING:像"发公告"

    • 缓存更新通知
    • 多系统都要同步处理的事件
    • "大家都要知道"的消息
  • 选 CLUSTERING:像"派工单"

    • 发短信/发券这类"发一次就行"的任务
    • 订单处理、异步任务
    • "只要有人做完就行"的消息

(可选)配合 Postgres 镜像启用扩展:把"快递柜"先装上

如果你用的是 supernpc/pgsql:18 这种集成镜像,首次创建数据库需要手动启用扩展(同样来自 README):

sql 复制代码
CREATE EXTENSION IF NOT EXISTS timescaledb CASCADE;
CREATE EXTENSION IF NOT EXISTS postgis CASCADE;
CREATE EXTENSION IF NOT EXISTS postgis_topology CASCADE;
CREATE EXTENSION IF NOT EXISTS pg_cron;
CREATE EXTENSION IF NOT EXISTS pg_stat_statements;
CREATE EXTENSION IF NOT EXISTS plpython3u;
CREATE EXTENSION IF NOT EXISTS vector;
CREATE EXTENSION IF NOT EXISTS pgmq;

总结:这套玩法为什么很适合懒人(我)

因为你想要的核心其实是:我能不能用最少的心智,把消息消费跑起来?

而这里的答案是:可以。

你只要记住一件事:@PgMqListener + subscribeType

  • BROADCASTING:消息像八卦,大家都要听到
  • CLUSTERING:消息像派单,只给一个人干活

剩下的,就交给 PostgreSQL 和这套二开生态去忙。

相关推荐
IvorySQL9 小时前
PostgreSQL 日报|修复截断 zstd 备份检测(10 月 9 日)
数据库·postgresql
余槐i17 小时前
200万行表加索引锁死写入:PostgreSQL CONCURRENTLY 的三类等待与重建路径
数据库·postgresql·性能优化·索引·explain
杨云龙UP1 天前
PostgreSQL 四种常见部署模式快速理解:单实例、流复制、repmgr、Patroni
linux·运维·数据库·postgresql·流复制·高可用ha
l1t1 天前
DeepSeek总结的PostgreSQL 19回退会一直继续,直到士气好转
数据库·postgresql
胖头鱼的鱼缸(尹海文)1 天前
胖头鱼的技术专栏-474 从能跑到能上线:PG SplitJSON 0.2.0 和 0.1.0 差在哪(20261008)
postgresql·json
云贝贝贝2 天前
PostgreSQL 分区表:从设计到运维,大表不再卡
运维·数据库·postgresql
Knight_AL2 天前
PostgreSQL Docker 数据库备份:pg_dump 与 SQL 格式备份的区别
数据库·docker·postgresql
长春的KAKA2 天前
GitLab 项目页面报 500 错误的完整修复记录:PostgreSQL 数据库损坏、统计表缺失及数据库迁移
数据库·postgresql·gitlab
IvorySQL2 天前
VACUUM FULL 之后 ROWID 就废了? IvorySQL 兼容性实测
数据库·人工智能·ai·postgresql·开源
瀚高PG实验室2 天前
HGHAC集群VIP-MANAGER挂载的VIP消失
数据库·postgresql·瀚高数据库