Postgres ListenNotify如何构建轻量级发布订阅系统?

摘要:概述 原先设计一个内部系统的消息模块和缓存模块时,只有一个Postgres依赖。想着没多大用户量,没必要额外安装Redis,徒增运维工夫。缓存好解决,配个UNLOGGED表即可。吭吭哧哧琢磨怎么用数据表实现消息的时候,发现PostgreSQ
概述 原先设计一个内部系统的消息模块和缓存模块时,只有一个Postgres依赖。想着没多大用户量,没必要额外安装Redis,徒增运维工夫。缓存好解决,配个UNLOGGED表即可。吭吭哧哧琢磨怎么用数据表实现消息的时候,发现PostgreSQL 提供了内置命令 LISTEN 和 NOTIFY,用于在数据库服务器和连接的客户端之间实现异步通信。这个 PostgreSQL 特有的扩展功能使得数据库可以作为一个轻量级的消息队列(MQ)系统使用,允许应用程序从数据库中生成事件,并由其他客户端实时响应。于是一拍即合,上手体验一下。 核心特性 轻量级实现:无需额外的消息中间件,直接利用 PostgreSQL 内置功能 异步通信:支持发布-订阅模式,实现解耦的组件通信 内存高效:通道(Channel)是纯内存对象,不占用磁盘空间 零配置:无需预先创建或管理通道,随用随建 适用场景 实时仪表盘:数据变更时实时推送更新 缓存失效:数据更新时通知缓存层刷新 数据审计:跟踪重要数据变更事件 任务调度:构建简单的分布式任务队列 事件驱动架构:实现微服务间的事件通信 通道(Channel)机制 重要特性: Channel 是纯内存对象,随 LISTEN 命令隐式创建 当所有监听会话断开或执行 UNLISTEN 时自动回收 无需手动创建或删除通道,也不支持此操作 消息传递模型 PostgreSQL 的 NOTIFY 采用典型的 "无监听即丢弃" 机制: 没有监听者时,消息不会入队 不占用磁盘空间 不消耗持久化内存 消息仅在存在活跃监听者时传递 基础使用 psql 命令行示例 -- 监听指定通道 LISTEN task_channel; -- 向通道发送消息 NOTIFY task_channel, '123456'; -- 取消监听所有通道 UNLISTEN *; -- 查看当前监听的通道 SELECT pg_listening_channels(); -- 查看系统通知状态 SELECT * FROM pg_stat_activity WHERE backend_type = 'client backend'; 动态消息生成 标准的 NOTIFY 命令要求消息内容必须明确指定,不支持动态字符串拼接。
阅读全文