聊一聊Redis的发布订阅

学疏才浅,班门弄斧只为加强自己的记忆,望各位看客海涵。如果错漏之处,望指出,互相探讨。

首先先说一下发布订阅模式,

一、发布-订阅模式

发布订阅模式由两类角色组成,
发布者观察者。
通过 “频道” 在消息源与消息接收方之间传送消息,相当于一个自由的协议,生活中我们可以找到很多的类似场景。例如 汽车电台, 电台在固定的频道发布消息, 而司机们可以自由的切换频道获取相应的消息。如果你事先知道某个电台有你喜欢听的节目,你可以随机切换到该电台。显然,这种模式是利于观众的,也就是我们的观察者,因而也被成为观察者模式。
基于观察者模式java设计模式一书中给出的定义是:

定义对象之间的一种一对多的依赖关系,使得每当一个对象状态发生改变时其相关依赖对象皆得到通知并被自动更新。

该定义将 发布者与频道本身作为了一个完整的对象,观察者只关心自己所观察的对象的变化,并依此采取动作。其次,我们能够意识到这是一种一对多的关系,一对多不仅体现在一个频道可以被多个观众订阅,也体现在一个一个观众可以同时订阅多个频道。这与我们上述的例子不尽相同,毕竟一台汽车在某个时刻只能听一个频道的广播。
下面展示一个图示,希望能够帮助各位更直观的了解发布-订阅模式。
在这里插入图片描述
图表比较潦草。望海涵。
实际上,你在浏览这篇文章的时候,你正是其中一个观察者,博客网站则是我们的频道,无数的博客作者在频道中发布消息,并不关心受众是否受到该消息(对于功利心而言,可能是希望的,但显然是无能为力的),也有无数的读者在频道中阅读消息,但是读者与指定的文章之间并没有订阅关系,被订阅的应该是博客的网站,或者对应的APP,你下载了这个APP后,当有内容更新时,消息将推送到你的手机。如果你在扩展着来看,报纸可能是较早的发布订阅模式的实践。但显然,发布订阅模式的提出,与其说是天才的发现,倒不如说是对生活中个别事例的完美总结。

注:
报纸最先出现于西汉初年公元前二世纪左右。 《邸报》是世界上最早的报纸。
发布-订阅模式/观察者模式 由 2000年9月 GOF四人组出版的《设计模式》一书中提出。

二、Redis的发布-订阅模式

上面介绍了发布-订阅模式之后,再来看redis的发布订阅之后就简单的多了。
简单复制一下一些教程网站上的图片来进行说明。

Redis的发布订阅只要进行简单的两部即可完成

1. 订阅

客户端通过 subscribe 命令订阅 channel

subscribe <channel...>

当然也支持批量订阅,通过 psubscribe 命令 + 通配符 完成

psubscribe *ball

上述命令表示订阅所有后缀为 ball的频道
在这里插入图片描述

2. 发布

发布者(也是一台客户端)通过 publish 命令 发布消息到对应的频道

publish <channel> <message>

通过上述图例我们可以知道,多个客户端可以同时订阅一个频道,单个客户端可以订阅多个频道,而相对于发布者,发布更是简单直接的动作。Redis通过一个类似管理中心的东西来管理被订阅的频道名称及其订阅者,当有消息发布时,匹配频道名称,并将消息发送到匹配上的订阅客户端中。
在这里插入图片描述

值得注意的是,Redis的发布订阅只能在单台Redis服务器中进行。无法在Redis服务器间进行发布订阅。

三、Redis发布-订阅的实践

首先在服务器中安装并运行Redis服务,启动两台Redis客户端连接
在这里插入图片描述
我们假定有两个 体育频道 football 和 basketball
其中一台进行频道的订阅,

subscribe football basketball

在这里插入图片描述
可以看到,订阅后,Redis客户端就进入了监听模式。

然后 我们用另外一台Redis进行消息的发布

publish basketball los 108 : 100 rocket

在这里插入图片描述
可以看到,客户端已经接收到了消息。消息格式如下

type  消息类型
channel  频道
message  消息

这边就进行一下简单的演示,有兴趣的小伙伴可以自己去试一下。

四、Redis 发布-订阅的不足

下列内容引用自 redis的发布订阅缺陷。作者:狂奔的蜗牛Snails 感谢大佬。

虽然redis实现了发布订阅(publish/subscribe)的功能,但是在通常的情况下是不推荐使用的,如果想使用消息队列这种功能,最好还是使用专业的各种MQ中间件,例如rabbitMQ,rockedMQ,activitedMQ等,本文主要讲一下不推荐使用redis的发布订阅功能的原因。

概要说一下就是,PUBLISH和SUBSCRIBE的缺陷在于客户端必须一直在线才能接收到消息,断线可能会导致客户端丢失消息,除此之外,旧版的redis可能会由于订阅者消费不够快而变的不稳定导致崩溃,甚至被管理员杀掉。

第一个原因是和redis系统的稳定性有关。对于旧版的redis来说,如果一个客户端订阅了某个或者某些频道,但是它读取消息的速度不够快,那么不断的积压的消息就会使得redis输出缓冲区的体积越来越大,这可能会导致redis的速度变慢,甚至直接崩溃。也可能会导致redis被操作系统强制杀死,甚至导致操作系统本身不可用。新版的redis不会出现这种问题,因为它会自动断开不符合client-output-buffer-limit pubsub配置选项要求的订阅客户端

第二个原因是和数据传输的可靠性有关。任何网络系统在执行操作时都可能会遇到断网的情况。而断线产生的连接错误通常会使得网络连接两端中的一端进行重新连接。如果客户端在执行订阅操作的过程中断线,那么客户端将会丢失在断线期间的消息,这在很多业务场景下是不可忍受的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值