服务器(11)--Redis发布和订阅(pub/sub)

2024-08-26 10:38

本文主要是介绍服务器(11)--Redis发布和订阅(pub/sub),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、Redis发布订阅

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

Redis 客户端可以订阅任意数量的频道。

下图展示了频道 channel1 , 以及订阅这个频道的三个客户端 —— client2 、 client5 和 client1 之间的关系:

当有新消息通过 PUBLISH 命令发送给频道 channel1 时, 这个消息就会被发送给订阅它的三个客户端:


二、特点&问题&解决方案

"发布/订阅"在redis中,被设计的非常轻量级和简洁,它做到了消息的“发布”和“订阅”的 基本能力;

但是尚未提供关于消息的持久化等各种企业级的特性。

一个Redis client发布消息,其他多个redis client订阅消息,发布的消息“即发即失”,redis 不会持久保存发布的消息;

消息订阅者也将只能得到订阅之后的消息,通道中此前的消息将无 从获得。

消息发布者,即publish客户端,无需独占链接,你可以在publish消息的同时,使用同一个redis-client链接进行其他操作(例如:INCR等)

消息订阅者,即subscribe客户端,需要独占链接,即进行subscribe期间,redis-client无法穿插其他操作, 此时client以阻塞的方式等待“publish端”的消息;因此这里subscribe端需要使用单独的链接,甚至需要在额外的线程中使用。 Tcp默认连接时间固定,如果在这时间内sub端没有接收到pub端消息,或pub端没有消息产生,sub端的连接都会被强制回收, 这里就需要使用特殊手段解决,用定时器来模拟pub和sub之间的保活机制,定时器时间不能超过TCP最大连接时间,具体根据机器环境来定;
            一旦subscribe端断开链接,将会失去部分消息,即链接失效期间的消息将会丢失,所以这里就需要考虑到借助redis的list来持久化;

如果你非常关注每个消息,那么你应该基于Redis做一些额外的补充工作,如果你期望订阅是持久的,那么如下的设计思路可以借鉴:

1) subscribe端: 首先向一个Set集合中增加“订阅者ID”, 此Set集合保存了“活跃订阅”者, 订阅者ID标记每个唯一的订阅者,此Set为 "活跃订阅者集合"

2) subcribe端开启订阅操作,并基于Redis创建一个以 "订阅者ID" 为KEY的LIST数据结构, 此LIST中存储了所有的尚未消费的消息,此List称为 "订阅者消息队列"

3) publish端: 每发布一条消息之后,publish端都需要遍历 "活跃订阅者集合",并依次 向每个 "订阅者消息队列" 尾部追加此次发布的消息.

4) 到此为止,我们可以基本保证,发布的每一条消息,都会持久保存在每个 "订阅者消息队列" 中.

5) subscribe端,每收到一个订阅消息,在消费之后,必须删除自己的 "订阅者消息队列" 头部的一条记录.

6) subscribe端启动时,如果发现自己的 "订阅者消息队列" 有残存记录, 那么将会首先消费这些记录,然后再去订阅.

以上方法可以保证成功到达的消息必消费不丢失;

三、实例

创建了订阅频道名为 pubSubTest:

现在,我们先重新开启个 redis 客户端,然后在同一个频道 redisChat 发布两次消息,订阅者就能接收到消息。

订阅者接到的消息:

四、Python中的使用

1、发布订阅类

class RedisPubSub:"""Redis 发布订阅类:return:"""def __init__(self, channel):self.__conn = redis.Redis(host="127.0.0.1", port=6379, db=0)self.chan_pub = channelself.chan_sub = channeldef publish(self, msg):"""发布:param msg::return:"""self.__conn.publish(self.chan_pub, msg)return Truedef subscribe(self):"""订阅:return:"""pub = self.__conn.pubsub()pub.subscribe(self.chan_sub)pub.parse_response()return pub

2、发布

# 发布
test_id = 2
# 订阅频道名称
obj = RedisPubSub("pubSubTest")
obj.publish('{"test_id":' + str(test_id) + '}')

结果:

3、订阅

# 订阅
obj = RedisPubSub("pubSubTest")
redis_sub = obj.subscribe()
while True:msg = redis_sub.parse_response()print(msg)print(msg[2])

结果:

 

这篇关于服务器(11)--Redis发布和订阅(pub/sub)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1108329

相关文章

服务器集群同步时间手记

1.时间服务器配置(必须root用户) (1)检查ntp是否安装 [root@node1 桌面]# rpm -qa|grep ntpntp-4.2.6p5-10.el6.centos.x86_64fontpackages-filesystem-1.41-1.1.el6.noarchntpdate-4.2.6p5-10.el6.centos.x86_64 (2)修改ntp配置文件 [r

高效+灵活,万博智云全球发布AWS无代理跨云容灾方案!

摘要 近日,万博智云推出了基于AWS的无代理跨云容灾解决方案,并与拉丁美洲,中东,亚洲的合作伙伴面向全球开展了联合发布。这一方案以AWS应用环境为基础,将HyperBDR平台的高效、灵活和成本效益优势与无代理功能相结合,为全球企业带来实现了更便捷、经济的数据保护。 一、全球联合发布 9月2日,万博智云CEO Michael Wong在线上平台发布AWS无代理跨云容灾解决方案的阐述视频,介绍了

零基础学习Redis(10) -- zset类型命令使用

zset是有序集合,内部除了存储元素外,还会存储一个score,存储在zset中的元素会按照score的大小升序排列,不同元素的score可以重复,score相同的元素会按照元素的字典序排列。 1. zset常用命令 1.1 zadd  zadd key [NX | XX] [GT | LT]   [CH] [INCR] score member [score member ...]

Vue3项目开发——新闻发布管理系统(六)

文章目录 八、首页设计开发1、页面设计2、登录访问拦截实现3、用户基本信息显示①封装用户基本信息获取接口②用户基本信息存储③用户基本信息调用④用户基本信息动态渲染 4、退出功能实现①注册点击事件②添加退出功能③数据清理 5、代码下载 八、首页设计开发 登录成功后,系统就进入了首页。接下来,也就进行首页的开发了。 1、页面设计 系统页面主要分为三部分,左侧为系统的菜单栏,右侧

Linux服务器Java启动脚本

Linux服务器Java启动脚本 1、初版2、优化版本3、常用脚本仓库 本文章介绍了如何在Linux服务器上执行Java并启动jar包, 通常我们会使用nohup直接启动,但是还是需要手动停止然后再次启动, 那如何更优雅的在服务器上启动jar包呢,让我们一起探讨一下吧。 1、初版 第一个版本是常用的做法,直接使用nohup后台启动jar包, 并将日志输出到当前文件夹n

maven发布项目到私服-snapshot快照库和release发布库的区别和作用及maven常用命令

maven发布项目到私服-snapshot快照库和release发布库的区别和作用及maven常用命令 在日常的工作中由于各种原因,会出现这样一种情况,某些项目并没有打包至mvnrepository。如果采用原始直接打包放到lib目录的方式进行处理,便对项目的管理带来一些不必要的麻烦。例如版本升级后需要重新打包并,替换原有jar包等等一些额外的工作量和麻烦。为了避免这些不必要的麻烦,通常我们

速盾:直播 cdn 服务器带宽?

在当今数字化时代,直播已经成为了一种非常流行的娱乐和商业活动形式。为了确保直播的流畅性和高质量,直播平台通常会使用 CDN(Content Delivery Network,内容分发网络)服务器来分发直播流。而 CDN 服务器的带宽则是影响直播质量的一个重要因素。下面我们就来探讨一下速盾视角下的直播 CDN 服务器带宽问题。 一、直播对带宽的需求 高清视频流 直播通常需要传输高清视频

禅道Docker安装包发布

禅道Docker安装包发布 大家好, 禅道Docker安装包发布。 一、下载地址 禅道开源版:   /dl/zentao/docker/docker_zentao.zip  备用下载地址:https://download.csdn.net/download/u013490585/16271485 数据库用户名: root,默认密码: 123456。运行时,可以设置 MYSQL_ROOT_P

Redis中使用布隆过滤器解决缓存穿透问题

一、缓存穿透(失效)问题 缓存穿透是指查询一个一定不存在的数据,由于缓存中没有命中,会去数据库中查询,而数据库中也没有该数据,并且每次查询都不会命中缓存,从而每次请求都直接打到了数据库上,这会给数据库带来巨大压力。 二、布隆过滤器原理 布隆过滤器(Bloom Filter)是一种空间效率很高的随机数据结构,它利用多个不同的哈希函数将一个元素映射到一个位数组中的多个位置,并将这些位置的值置

一种改进的red5集群方案的应用、基于Red5服务器集群负载均衡调度算法研究

转自: 一种改进的red5集群方案的应用: http://wenku.baidu.com/link?url=jYQ1wNwHVBqJ-5XCYq0PRligp6Y5q6BYXyISUsF56My8DP8dc9CZ4pZvpPz1abxJn8fojMrL0IyfmMHStpvkotqC1RWlRMGnzVL1X4IPOa_  基于Red5服务器集群负载均衡调度算法研究 http://ww