想用队列?但我一个中间件都不想引入: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 和这套二开生态去忙。

相关推荐
hudson20223 小时前
work_mem: 这是一个陷阱!
后端·postgresql
李长渊哦4 小时前
家用宽带动态公网 IP 下 Node + PostgreSQL 服务的 DDNS 全流程部署实践
网络协议·tcp/ip·postgresql
程序人生5184 小时前
ubuntu桌面版安装后配置允许root通过图形界面登录和ssh登录 亲测有效
ubuntu·postgresql·ssh
lbb 小魔仙4 小时前
无公网 IP 环境下的 PostgreSQL 远程访问方案:基于内网穿透技术的全流程解析
网络协议·tcp/ip·postgresql
蓦然乍醒1 天前
使用 DBeaver 还原 PostgreSQL 备份文件 (.bak) 技术文档
数据库·postgresql
l1t1 天前
DeepSeek总结的PostgreSQL使用 RDTSC 降低 EXPLAIN ANALYZE 的计时开销
数据库·postgresql
l1t1 天前
DeepSeek总结的PostgreSQL检查点和写入风暴
jvm·postgresql·oracle
丸辣,我代码炸了1 天前
用 PostgreSQL 一库模拟 MySQL / MongoDB / Redis / Elasticsearch(附 ts_rank 详解)
mysql·mongodb·postgresql
XDHCOM2 天前
PostgreSQL 25001: active_sql_transaction 报错原因分析,故障修复步骤详解,远程处理解决方案
数据库·sql·postgresql