一、发布和订阅机制

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

五、项目源码:

redis-web-pubsub

Spring mvc Data Redis—Pub/Sub(附Web项目源码)的更多相关文章

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

    一.发布和订阅机制 当一个客户端通过 PUBLISH 命令向订阅者发送信息的时候,我们称这个客户端为发布者(publisher). 而当一个客户端使用 SUBSCRIBE 或者 PSUBSCRIBE ...

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

    一.发布和订阅机制 当一个客户端通过 PUBLISH 命令向订阅者发送信息的时候,我们称这个客户端为发布者(publisher). 而当一个客户端使用 SUBSCRIBE 或者 PSUBSCRIBE ...

  3. 使用Spring MVC,Mybatis框架等创建Java Web项目时各种前期准备的配置文件内容

    1.pom.xml 首先,pom.xml文件,里面包含各种maven的依赖,代码如下: <project xmlns="http://maven.apache.org/POM/4.0. ...

  4. 【持久化框架】SpringMVC+Spring4+Mybatis3集成,开发简单Web项目+源码下载

    上篇博文我们介绍了mybatis的基本概念与原理,这篇博文我们通过Spring与Mybatis集成,开发一个简单用户增删改查的Web项目. 基本准备工作 1.安装JDK1.6以上版本,安装与配置 2. ...

  5. Spring+SpringMvc+Mybatis框架集成搭建教程五(项目源码发布到GitHub)

    一.背景 我们做完了上面的四步操作以后,来把我们写好的项目提交到自己的GitHub仓库进行版本管理,具体步骤如下. 二.提交步骤 1.首先你要保证你已经有GitHub的账号和密码(没有可以去githu ...

  6. Java eclipse下 Ant build.xml实例详解 附完整项目源码

    在有eclipse集成环境下ant其实不是很重要,但有些项目需要用到,另外通过eclipse来学习和理解ant是个很好的途径,所以写他demo总结下要点,希望能够帮到大家. 一.本人测试环境eclip ...

  7. Java Spring mvc 操作 Redis 及 Redis 集群

    本文原创,转载请注明:http://www.cnblogs.com/fengzheng/p/5941953.html 关于 Redis 集群搭建可以参考我的另一篇文章 Redis集群搭建与简单使用 R ...

  8. MyBatis项目配置案例详解与Web下的增删改查实现[附项目源码]

    MyBatis项目案例 项目图示: 项目源码地址:https://github.com/JluTiger/mybatispro 1.项目功能 项目案例:后台管理系统用户数据维护平台 所有用户数据查询 ...

  9. Shiro整合springboot,freemaker,redis(含权限系统完整源码)

    区块链技术联盟 2018-02-08 17:06:40 目录 一.导语 二.shiro功能介绍 三.shiro详解 四.shiro实战案例分享 五.系统配置 六.其他 一.导语 今天推荐给大家一个非常 ...

随机推荐

  1. MongoDB实战指南(四):MongoDB的Journaling日志功能

    mongoDB的Journaling日志功能与常见的log日志是不一样的,mongoDB也有log日志,它只是简单记录了数据库在服务器上的启动信息.慢查询记录.数据库异常信息.客户端与数据库服务器连接 ...

  2. [topcoder]SmartWordToy

    广度搜索BFS,要用Queue.还不是很熟,这道题帮助理清一些思绪了.其实这道题是求最短路径,所以BFS遇到第一个就可以返回了,所以后面有些现有大小和历史大小的判断可以省却. 过程中拿数组存step还 ...

  3. 第九章 Mass Storage设备

    9.1 Mass Storage设备介绍 USB的Mass Storage类是USB大容量储存设备类(Mass Storage Device Class).专门用于大容量存储设备,比如U盘.移动硬盘. ...

  4. Android开发之BroadcastReceiver的使用

    1.静态注册. 在manifest中注册. <receiver android:name="com.exce.learnbroadcastreceiver.MyReceiver&quo ...

  5. mapreduce实现全局排序

    直接附代码,说明都在源码里了. package com.hadoop.totalsort; import java.io.IOException; import java.util.ArrayList ...

  6. bzoj2753

    第一问dfs不说 第二问很容易让人想到最小树形图,但是我不会,而且时间复杂度也不允许 还有什么不同的方法呢? 首先想到的是prim的思想,设根节点已经确定,其他点未确定 我们就不断从已确定的点延伸,找 ...

  7. 转自 z55250825 的几篇关于FFT的博文(二)

    题目大意:高精度乘法.     fft的实现貌似有很多种,咱先写的是一种递归的fft,应该算是比较快的了吧.参考了 Evil君 的代码,那个运算符重载看的咱P党泪流满面. (没想到P竟然有运算符重载咩 ...

  8. 在 ASP.NET MVC 中使用 HTTPS (SSL/TLS)

    某些安全性较高的网页,如网上支付或用户登陆页面,可能会使用到https(SSL/TLS)来提高安全性.本文介绍了如何在ASP.NET MVC中强制某action使用https和如何进行向https页面 ...

  9. MySQL运行原理与基础架构

    1.MySQL基础 MySQL是一个开放源代码的关系数据库管理系统.原开发者为瑞典的MySQL AB公司,最早是在2001年MySQL3.23进入到管理员的视野并在之后获得广泛的应用. 2008年My ...

  10. 使用 testng.xml 参数化

    1. 创建 Java 测试类 2. 添加测试方法 TestngParameterTest(String name, String age) 3. 为测试方法添加注释 @Parameters({&quo ...