博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Spring Data Redis—Pub/Sub(附Web项目源码)
阅读量:6424 次
发布时间:2019-06-23

本文共 3193 字,大约阅读时间需要 10 分钟。

一、发布和订阅机制

  当一个客户端通过 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地址:

 

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

 

三、Demo演示:

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

Pub/Sub配置(XMl):

 

复制代码
1 
2
3
4
5 6
7
10
11
14
15
16
17
18
19
20
21
22 23
24
25
26
复制代码

 

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

那么解决办法有两种:

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

 

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

 

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

 

PubServiceImpl:

复制代码
1 @Service 2 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 {    @Autowired    private 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:

 

五、项目源码:

 

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

 

转载于:https://www.cnblogs.com/softidea/p/5559979.html

你可能感兴趣的文章
Nginx_PHP_PHP-FPM网站环境部署手册
查看>>
Spring aop 配置和使用
查看>>
简单栈溢出
查看>>
我的友情链接
查看>>
MySql启动预编译功能
查看>>
欧拉定理
查看>>
EventLoop(netty源码死磕4)
查看>>
#17 HABTM Checkboxes
查看>>
如何修改WordPress自带标签云小工具的显示参数
查看>>
在MyEclipse下使用JUnit
查看>>
Hashtable的使用
查看>>
n&(n-1)的妙用
查看>>
嵌入式ARM系统实战开发视频教程
查看>>
iOS开发篇--OC 过程式编程讲解
查看>>
java学习笔记4
查看>>
ELK之logstash系统日志和nginx,tomcat日志收集-4
查看>>
Maven学习总结(十)——使用Maven编译项目gbk的不可映射问题
查看>>
阶梯流程图在PowerPoint2013中如何制作?工作总结ppt模板
查看>>
Java基础学习总结(9)——this关键字
查看>>
Maven学习总结(四)——Maven核心概念
查看>>