首页 > 其他分享 >9

9

时间:2024-06-11 22:56:22浏览次数:10  
标签: 订阅 频道 notice 链表 消息 客户端

9.Redis的发布订阅

2023年3月17日21:34:59

什么是发布订阅

  • Redis 发布订阅(pub/sub)是一种消息通信模式:发送者(pub)发送消息,订阅者(sub)接收消息.

  • Redis 的 subscribe 命令可以让客户端订阅任意数量的频道, 每当有新信息发送到被订阅的频道时, 信息就会被发送给所有订阅指定频道的客户端。

图 1

图 2

熟悉消息中间件的同学都知道,针对消息订阅发布功能,市面上很多大厂使用的是kafka、RabbitMQ、ActiveMQ, RocketMQ等这几种,redis的订阅发布功能跟这三者相比,相对轻量,针对数据准确和安全性要求没有那么高可以直接使用,适用于小公司。

双端队列

  • redis 的List数据类型结构提供了 blpop 、brpop 命令结合 rpush、lpush 命令可以实现消息队列机制,基于双端链表实现的发布与订阅功能

图 3

局限性

  • 不能支持一对多的消息分发
  • 如果生产者生成的速度远远大于消费者消费的速度,易堆积大量未消费的消息
  • 双端队列模式只能有一个或多个消费者轮着去消费,却不能将消息同时发给其他消费者

发布/订阅模式

  • redis订阅发布模式,生产者生产完消息通过频道分发消息,给订阅了该频道的所有消费

图 4

#subscribe key  订阅频道
#publish key message 向频道发布消息
#unsubscribe key 停止订阅

#客户端1 订阅频道
127.0.0.1:6379> subscribe notice
Reading messages... (press Ctrl-C to quit)

#客户端2 向频道发布消息
127.0.0.1:6379> publish notice hello,world
(integer) 1
127.0.0.1:6379> publish notice 'its 8 oclock now'
(integer) 1

#客户端1 收到消息
1) "subscribe"      #订阅操作
2) "notice"         #订阅频道notice
3) (integer) 1      #数量
1) "message"        #消息类型message
2) "notice"         #频道名称
3) "hello,world"    #收到内容
1) "message"        #消息类型message
2) "notice"         #频道名称
3) "its 8 oclock now" #收到内容
#客户端1 手动停止订阅
127.0.0.1:6379> unsubscribe notice
1) "unsubscribe"
2) "notice"
3) (integer) 0

内部原理

图 5

  • 底层通过字典实现。pubsub_channels 是一个字典类型,保存订阅频道的信息:字典的key为订阅的频道, 字典的value是一个链表, 链表中保存了所有订阅该频道的客户端
  • 订阅频道:先检查字段内部是否存在;不存在则为当前频道创建一个字典且创建一个链表存储客户端id;否则直接将客户端id插入到链表中。
  • 取消订阅:时将客户端id从对应的链表中删除;如果删除之后链表已经是空链表了,则将会把这个频道从字典中删除。
  • 发布消息:首先根据 channel 定位到字典的键, 然后将信息发送给字典值链表中的所有客户端

总结

  • 使用场景
    • 电商中,用户下单成功之后向指定频道发送消息,下游业务订阅支付结果这个频道处理自己相关业务逻辑
    • 粉丝关注功能
    • 公众号文章推送
  • 使用注意
    • 客户端需要及时消费和处理消息。客户端订阅了channel之后,如果接收消息不及时,可能导致DCS实例消息堆积,当达到消息堆积阈值(默认值为32MB),或者达到某种程度(默认8MB)一段时间(默认为1分钟)后,服务器端会自动断开该客户端连接,避免导致内部内存耗尽。
    • 客户端需要支持重连。当连接断开之后,客户端需要使用subscribe或者psubscribe重新进行订阅,否则无法继续接收消息。
    • 不建议用于消息可靠性要求高的场景中。Redis的pubsub不是一种可靠的消息系统。当出现客户端连接退出,或者极端情况下服务端发生主备切换时,未消费的消息会被丢弃。
    • 对消息队列有高可靠性要求的场景,可以使用rabbitMQ kafka等消息队列中间件。

标签:,订阅,频道,notice,链表,消息,客户端
From: https://www.cnblogs.com/hyt810/p/18242963

相关文章