Spring Data Redis—Pub/Sub(附Web项目源码)

一、发布和订阅机制

  当一个客户端通过 PUBLISH 命令向订阅者发送信息的时候,我们称这个客户端为发布者(publisher)。

  而当一个客户端使用 SUBSCRIBE 或者 PSUBSCRIBE 命令接收信息的时候,我们称这个客户端为订阅者(subscriber)。

为了解耦发布者(publisher)和订阅者(subscriber)之间的关系,Redis 使用了 channel (频道)作为两者的中介 —— 发布者将信息直接发布给 channel ,而 channel 负责将信息发送给适当的订阅者,发布者和订阅者之间没有相互关系,也不知道对方的存在

注意:Redis的Pub Sub功能(或许是暂时)不支持持久化,意思就是消息在管道中是即发即失的,Subscriber端一收到消息,消息即从管道中删除。所以如果是对消息的准确性要求比较高或者是有持久化的需求,Redis就不是那么合适了,期待以后的版本加入持久化功能。

 

二、Pub/Sub的作用

其实从Pub/Sub的机制来看,它更像是一个广播系统,多个Subscriber可以订阅多个Channel,多个Publisher可以往多个Channel中发布消息。可以这么简单的理解:

Subscriber:收音机(只不过这个收音机可以收到多个频道,并以队列方式显示)

Publisher:电台(电台可以往不同的FM频道中发消息)

Channel:不同频率的FM频道

 

所以根据这个理解,那么我觉得有几种用法是比较可取的:

  1.一个Publisher,多个Subscriber:

  如下图所示,可以作为消息队列或者消息管道。

  主要应用:通知、公告。

  2.多个Publisher,一个Subscriber:

  可以将PubSub做成独立的HTTP接口,各应用程序作为Publisher向Channel中发送消息,Subscriber端收到消息后执行相应的业务逻辑,比如写数据库,显示等等。

  主要应用:排行榜、投票、计数。

 

3.多个Publisher,多个Subscriber

图就不上了,故名思议,就是可以向不同的Channel中发送消息,由不同的Subscriber接收。

主要应用:群聊、聊天。

可参考Spring data redis主页的开源项目retwisj。

Github地址:https://github.com/spring-projects/spring-data-keyvalue-examples/tree/master/retwisj

 

从上述几种用法来看,根据不同的限制条件,限制Publisher、Subscriber和Channel的数量,可以实现不同的功能,其实完全可以把Pub/Sub理解为Socket编程,用Socket也可以实现上述功能,但是Redis提供了相应的封装和底层实现,不管是安全性、健壮性的等各方面都有不错的表现,以及未来的一些拓展,个人觉得Redis是个不错的选择。

 

三、Demo演示:

因为我的上一篇博客Spring Data Redis简介以及项目Demo,RedisTemplate和 Serializer详解,已经演示了Spring Data Redis的基本配置和使用,所以这里就只贴上Pub/Sub的重要代码,读者可以阅读上篇博客或者下载源码。

Pub/Sub配置(XMl):

 

复制代码
 1 <!-- SDR Pub/Sub配置 -->2     <!-- SubServiceImpl是实现了MessageListener接口的类,MessageListener接口中定义了onMessage方法,也就是接收消息的方法,每当Channel中有消息,onMessage方法会被自动调用, -->3     <bean id="messageListener" class="com.chr.service.impl.SubServiceImpl">4     </bean>5     6     <!-- 可以有多个messageListener,每个messageListener必须注册到RedisMessageListenerContainer中,读者可参阅API文档 -->7     <bean id="messageContainer"8         class="org.springframework.data.redis.listener.RedisMessageListenerContainer"9         destroy-method="destroy">
10         <property name="connectionFactory" ref="connectionFactory" />
11         <!--<property name="taskExecutor"> <bean class="org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler"> 
12 <property name="poolSize" value="3"></property> </bean> </property>
13 此处可以定义Executor,参阅java.util.concurrent.Executor-->
14         <property name="messageListeners">
15             <map>
16                 <entry key-ref="messageListener">
17                     <ref bean="channelTopic" />
18                 </entry>
19             </map>
20         </property>
21     </bean>
22 
23     <!-- Channel设置 -->
24     <bean id="channelTopic" class="org.springframework.data.redis.listener.ChannelTopic">
25         <constructor-arg value="user:topic" />
26     </bean>
复制代码

 

在代码中可以看到subServiceImpl实现类被手动注册到配置文件中,这样可能会使代码混乱,并且会带来一些问题,比如需要使用注解自动注入rankService,但是因为Spring配置中,XML的优先级大于Annotation,所以subServiceImpl中的rankService不能被@Autowired。

那么解决办法有两种:

  1.在配置文件中(messageLisener bean前)加入:

<!-- 类扫描器 --><context:component-scan base-package="com.songod.service" />

 

这样Spring会先扫描Annotation,创建rankService bean,之后再注入messageLisener。

 

  2.在messageContainer bean中,只注入connectionFactory,不注入messageLisener和channelTopic。 之后在Controller中手动注入,调用addMessageListener(MessageListener listener, Topic topic)方法手动注入,但是注意只能注入一次,可以设置Flag判断。

 

PubServiceImpl:

复制代码
 1 @Service2 public class PubServiceImpl implements PubService {3     @Resource(name="stringRedisTemplate")4     private  StringRedisTemplate stringRedisTemplate;5     6     private String channelTopic = "user:topic";7     8     /*发布消息到Channel*/9     public void Publisher(String message) {
10         stringRedisTemplate.convertAndSend(channelTopic, message);
11     }
12 }
复制代码

我这里用的是StringRedisTemplate,读者可以使用RedisTemplate设置其它序列化方式,可以看我的上一篇博客。

 

SubServiceImpl:

复制代码
public class SubServiceImpl implements SubService {@Autowiredprivate ChannelTopic channelTopic;private MessageList messageList = new MessageList();public void onMessage(Message message, byte[] pattern) {System.out.println(message.toString() + "  " + channelTopic.getTopic());messageList.add(message.toString());}public MessageList getMessageList() {return messageList;}
}
复制代码

主要是onMessage方法,可以在此方法中将message传入其它业务逻辑中进行处理。

 

四、Demo运行:

Publish:

Subscrib:

 

五、项目源码:

redis-web-pubsub

 

http://www.cnblogs.com/edwinchen/p/3836239.html

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/293987.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

突破历史,21年C#将首获年度编程语言奖!

2021年渐入尾声&#xff0c;TIOBE今日发布了12月排行榜&#xff0c;Java(第3)持续下滑&#xff0c;PHP(第12)跌出前十&#xff0c;而C#(第5)继续稳步增长。据悉&#xff0c;TIOBE的CEO Paul Jansen表示&#xff0c;C#极有可能获取“TIOBE 年度编程语言奖”。该奖项一般颁发给被…

史上最接近上帝的方程!神秘的数字4.669,目前没有人能解开这个谜语......

全世界只有3.14 % 的人关注了爆炸吧知识上帝指纹统治世界&#xff1f;春节进入倒计时&#xff0c;实不相瞒&#xff0c;超模君想鸽的心蠢蠢欲动&#xff0c;费了好大劲才摁住&#xff01;为了不鸽&#xff0c;连夜翻了个墙&#xff0c;明明刚开始还在认认真真看论文&#xff0c…

html仿苹果浏览器,完美仿iPhone风格主题 领航浏览器体验

1仿iPhone的图标式导航页手机浏览器这个市场因其使用情况极为广泛和频繁因此吸引了无数厂商进入&#xff0c;不仅是传统的浏览器厂商也有许多新晋的手机软件厂商&#xff0c;其产品也从强调省流量、云概念、操作体验和自主核心、HTML 5等功能不一而足&#xff0c;今天带来的体验…

【JavaScript】关于eval( )

为什么80%的码农都做不了架构师&#xff1f;>>> 一、eval() 动态执行时使用当前函数的闭包。 var i 100; function myFunc(ctx) {var i test;eval(var test "hello."); //test执行后为局部变量 } myFunc(); // 输出值100 alert(i); 二、eva l() 访问…

在ASP.Net Core和JAVA中,使用Azure配置密钥——Key Vault

思路浅析 在软件开发中&#xff0c;项目安全是重中之重&#xff0c;特别是在多部门或者开源项目中&#xff0c;如何保存我们的密钥&#xff0c;但又不影响本地的开发&#xff0c;更需要我们开发者需要考虑的问题&#xff0c;这里简单的列举了下平时开发中我们做的…

我怀疑对象做了什么对不起我的事......

1 狗狗已经这么明显提醒你了▼2 传销老总都怕的传销......▼3 和一只狗撞衫了▼4 你信吗&#xff1f;我跳水不会湿头发&#xff01;▼5 东北雪糕行业繁荣的原因还挺在理▼6 打了个平手&#xff1f;▼7 缅甸网红苏娜英腰围35公分她还想减▼8 哈哈哈哈▼你点的每个赞&…

记一次 .NET 某市附属医院 Web程序 偶发性CPU爆高分析

一&#xff1a;背景 1. 讲故事这个月初&#xff0c;一位朋友加微信求助他的程序出现了 CPU 偶发性爆高&#xff0c;希望能有偿解决一下。从描述看&#xff0c;这个问题应该困扰了很久&#xff0c;还是医院的朋友给力&#xff0c;开门就是 100块 红包 &#x1f923;&#x1f923…

[iOS]应用内支付(内购)的个人开发过程及坑!

本文基于XcodeVersion 7.3 (7D175)版本&#xff0c;手机是iPhone 6&#xff0c;9.3系统。 一. 创建测试App 首先你需要登录 App的ItunesConnection&#xff0c;你会看到如下界面 简单的介绍一下这几个选项 1.我的App主要用于管理自己的App应用&#xff0c;例如编辑资料&…

农商银行招聘计算机人员考什么,农商银行招聘考试题都考什么?

整理了农商农商一、行政职业能力测试类农商银行行测考试题型主要以选择题形式出现。主要包括言语理解、数量关系、判断推理、资料分析、常识五大部分。二、英语类农商银行考试英语部分&#xff1a;一般银行英语考试内容包括英语词汇与语法、英汉互译、改错、完型填空和阅读理解…

讲一讲应用服务的新鲜事儿

微软中国MSDN 点击上方蓝字关注我们为了新功能的发布&#xff0c;以及 Linux 和 Windows 的改进&#xff0c;Azure App Service 团队付出了非常多的努力。很开心的是&#xff0c;我们看到了 Windows Containers 的正式版本&#xff0c;并可应用于 App Service 环境 v3 上。此外…

iOS中的动画

2019独角兽企业重金招聘Python工程师标准>>> iOS中的动画 Core Animation Core Animation是一组非常强大的动画处理API,使用它能做出非常绚丽的动画效果,而且往往是事半功倍,使用它需要添加QuartzCore .framework和引入对应的框架<QuartzCore/QuartzCore.h>…

全世界70亿人同时起跳,地球会天崩地裂?答案可能让你难以置信

全世界只有3.14 % 的人关注了爆炸吧知识地球表示微微一笑不得不说&#xff0c;模友们的脑袋里总是充满了奇思妙想&#xff0c;比如超模君最近就收到了这么个问题&#xff1a;首先&#xff0c;这问题真就属于一看很有趣&#xff0c;细想全是BUG的那种。且不说怎么让70亿人同时聚…

2021.NET Conf China上的GraphQL

今天给大家分享.NET中的GraphQL&#xff0c;半个小时&#xff0c;没有把所有的代码敲出来&#xff0c;高估了自己的写码速度&#xff0c;所以通过这个文章分享出来。1、核心PPT2、主要代码using Conf2021GraphQL; using Conf2021GraphQL.Models; using Microsoft.EntityFramewo…

Rust 社区求变,PHP 大旗不倒?

文 | 一君出品 | OSC开源社区&#xff08;ID&#xff1a;oschina2013&#xff09;上月底发生了两件开源语言相关的大事。一是 JetBrains 牵头成立 PHP 基金会&#xff0c;希望能确保语言的长寿和繁荣。二是 Rust 审核团队集体辞职&#xff0c;理由是 Rust 核心团队造成了“寡头…

centos安装vsftp后的虚拟用户设置

2019独角兽企业重金招聘Python工程师标准>>> 安装好vsftpd之后&#xff0c;有的时候需要配置虚拟用户&#xff0c;可以先写一个login.txt&#xff0c;奇数行为用户名&#xff0c;偶数为用户名密码&#xff0c;例如: user1 password1 user2 password2 然后将其生成文…

2021 .NET 开发者峰会顺利在网上落幕,线上直播回看汇总

.NET Conf China 2021 是面向开发人员的社区峰会&#xff0c;基于 .NET Conf 2021的活动&#xff0c;庆祝 .NET 6 的发布和回顾过去一年来 .NET 在中国的发展成果展示&#xff0c;它是由中国各地区的技术社区共同发起举办、知名企业和开源组织联合协办&#xff0c;是年度国内规…