# 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 客户端在订阅频道后,会进入 监听状态 ,持续等待服务器推送消息。此时,当前连接被占用,无法执行任何其他命令(包括 UNSUBSCRIBEPSUBSCRIBE )。

# 命令集

在 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交流群
原创网站开发,偏差难以避免。

如若发现错误,诚心感谢反馈。

愿你倾心相念,愿你学有所成。

愿你朝华相顾,愿你前程似锦。