# Redis 发布订阅
概念
Redis 发布订阅(Pub/Sub)是一种消息通信模式,允许消息的 发布者(Publisher) 向指定 频道(Channel) 发送消息, 订阅者(Subscriber) 通过订阅频道接收消息。这种模式实现了消息的 广播机制 ,发布者和订阅者完全解耦,无需知道彼此的存在。
# 作用
实时消息推送:支持一对多的实时消息广播。
事件通知:用于系统间的事件驱动通信(如订单状态变更)。
解耦系统模块:发布者和订阅者通过频道间接通信,降低模块依赖性。
# 特性
频道订阅:订阅者通过
SUBSCRIBE
监听指定频道,支持多频道同时订阅。模式匹配订阅:使用
PSUBSCRIBE
通过通配符(如*
、?
)匹配多个频道(如news.*
)。无消息持久化:消息仅发送给当前在线的订阅者,离线后无法接收历史消息。
轻量级:基于内存操作,性能高,适合高频、实时场景。
# 场景
公众号消息推送:用户订阅不同公众号(频道),公众号发布新文章时通知所有订阅用户。
实时聊天室:用户加入聊天室(订阅频道),发送消息实时广播给所有成员。
系统监控告警:监控系统发布告警到指定频道,运维人员订阅接收通知。
# 示例
场景描述:
用户 A、B 订阅了 技术频道(tech_news)。
用户 C 订阅了 体育频道(sports)。
公众号运营者发布新文章时,通过频道推送消息给订阅用户。
# 1.订阅频道(用户视角)
启动第一个Redis客户端(redis-cli),作为用户A订阅技术频道和体育频道:
# 用户A 订阅技术频道和体育频道
127.0.0.1:6379> SUBSCRIBE tech_news sports
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "tech_news"
3) (integer) 1 # 订阅技术频道响应
1) "subscribe"
2) "sports"
3) (integer) 2 # 订阅体育频道响应
启动第二个Redis客户端(redis-cli),作为用户B订阅技术频道:
127.0.0.1:6379> SUBSCRIBE tech_news
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "tech_news"
3) (integer) 1 # 订阅技术频道响应
# 2.发布消息(公众号运营者视角)
启动第三个Redis客户端(redis-cli),作为运营者发布技术消息:
127.0.0.1:6379> PUBLISH tech_news "New tech message to http://feixiang.net"
(integer) 2 # 收到消息的订阅者数量(用户A、B)
用户A视角:
127.0.0.1:6379> SUBSCRIBE tech_news sports
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "tech_news"
3) (integer) 1
1) "subscribe"
2) "sports"
3) (integer) 2
1) "message" # 接收到来自技术频道的消息
2) "tech_news"
3) "New tech message to http://feixiang.net" # 具体的消息内容
用户B视角:
127.0.0.1:6379> SUBSCRIBE tech_news
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "tech_news"
3) (integer) 1
1) "message" # 接收到来自技术频道的消息
2) "tech_news"
3) "New tech message to http://feixiang.net" # 具体的消息内容
接下来,运营者再发布体育消息:
127.0.0.1:6379> PUBLISH sports "New sport message to http://feixiang.net"
(integer) 1
此时用户A接到如下新消息,但用户B由于没有订阅而未接到消息:
127.0.0.1:6379> SUBSCRIBE tech_news sports
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "tech_news"
3) (integer) 1
1) "subscribe"
2) "sports"
3) (integer) 2
1) "message"
2) "tech_news"
3) "New tech message to http://feixiang.net"
1) "message" # 接收到来自体育频道的消息
2) "sports"
3) "New sport message to http://feixiang.net" # 具体的消息内容
# 3.批量订阅频道(用户视角)
如果有多个频道名称有相同的前缀,可以直接使用模式匹配的功能批量订阅,包括后续加入的新频道也会被订阅:
127.0.0.1:6379> PSUBSCRIBE tech_* # 订阅了所有以tech_开头的频道
Reading messages... (press Ctrl-C to quit)
1) "psubscribe"
2) "tech_*"
3) (integer) 1
1) "pmessage" # 接收到来自tech_news的消息
2) "tech_*"
3) "tech_news"
4) "New tech message to http://feixiang.net"
运营者新增一个名为 tech_study 的频道:
127.0.0.1:6379> PUBLISH tech_study "New tech study message to http://feixiang.net"
(integer) 1
用户无需其它操作也能接收到这个新频道的信息:
127.0.0.1:6379> PSUBSCRIBE tech_*
Reading messages... (press Ctrl-C to quit)
1) "psubscribe"
2) "tech_*"
3) (integer) 1
1) "pmessage"
2) "tech_*"
3) "tech_news"
4) "New tech message to http://feixiang.net"
1) "pmessage" # 接收到来自tech_study的消息
2) "tech_*"
3) "tech_study"
4) "New tech study message to http://feixiang.net"
# 4.查看活跃频道
假设用户订阅了两个频道:
127.0.0.1:6379> SUBSCRIBE tech_news sports
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "tech_news"
3) (integer) 1
1) "subscribe"
2) "sports"
3) (integer) 2
发布者使用PUBSUB CHANNELS可以查看所有活跃的频道:
127.0.0.1:6379> PUBSUB CHANNELS
1) "sports"
2) "tech_news"
# 5.查看具体频道的订阅者数量
# 查看 tech_news 频道的订阅者数量
127.0.0.1:6379> PUBSUB NUMSUB tech_news
1) "tech_news"
2) (integer) 1 # 表示有1个订阅者
# 6.取消订阅说明
在订阅客户端按 Ctrl + C 快捷键即可退出订阅。
Redis 客户端在订阅频道后,会进入 监听状态 ,持续等待服务器推送消息。此时,当前连接被占用,无法执行任何其他命令(包括 UNSUBSCRIBE
和 PSUBSCRIBE
)。
# 命令集
在 Redis 客户端(如 redis-cli )可以通过help @pubsub
命令查找所有与发布订阅相关的命令,效果如下:
127.0.0.1:6379> help @pubsub
PSUBSCRIBE pattern [pattern ...]
summary: Listen for messages published to channels matching the given patterns
since: 2.0.0
PUBLISH channel message
summary: Post a message to a channel
since: 2.0.0
PUBSUB subcommand [argument [argument ...]]
summary: Inspect the state of the Pub/Sub subsystem
since: 2.8.0
……
以下是 Redis-x64-3.0.504 版本的发布订阅命令集:
命令 | 说明 | 版本 |
---|---|---|
PSUBSCRIBE pattern [pattern ...] | 监听发布到匹配指定模式的频道的消息 | 2.0.0+ |
PUBLISH channel message | 向指定频道发布消息 | 2.0.0+ |
PUBSUB subcommand [argument ...] | 检查发布订阅子系统的状态 | 2.8.0+ |
PUNSUBSCRIBE [pattern [pattern ...]] | 停止监听匹配指定模式的频道的消息 | 2.0.0+ |
SUBSCRIBE channel [channel ...] | 监听发布到指定频道的消息 | 2.0.0+ |
UNSUBSCRIBE [channel [channel ...]] | 停止监听指定频道的消息 | 2.0.0+ |

微信公众号

QQ交流群
如若发现错误,诚心感谢反馈。
愿你倾心相念,愿你学有所成。
愿你朝华相顾,愿你前程似锦。