Spring Boot 2.x基础教程:使用Redis的发布订阅功能
通过前面一篇集中式缓存的使用教程,我们已经了解了Redis的核心功能:作为K、V存储的高性能缓存。
接下来我们会分几篇来继续讲讲Redis的一些其他强大用法!如果你对此感兴趣,一定要关注收藏我哦!
发布订阅模式
如果你看过之前我写的关于MQ的相关文章,那么对于发布订阅功能应该不会陌生。如果没看过,那也不要紧,这里先做一个简单介绍,已经了解的可以跳过直接看下一节内容。
什么是发布订阅模式?
在发布订阅模式中有个重要的角色,一个是发布者Publisher,另一个订阅者Subscriber。本质上来说,发布订阅模式就是一种生产者消费者模式,Publisher负责生产消息,而Subscriber则负责消费它所订阅的消息。这种模式被广泛的应用于软硬件的系统设计中。比如:配置中心的一个配置修改之后,就是通过发布订阅的方式传递给订阅这个配置的订阅者来实现自动刷新的。
不就是观察者模式吗?
看到这里,学过设计模式的同学可能很容易将它与设计模式中的观察者模式联系起来,你会觉得发布订阅模式中的两个概念与观察者模式中的两个概念似乎干的是一样的事情?所以:Publisher就是观察者模式中的Subject?Subscriber就是观察者模式中的Observer?
重要区别在哪里?
从这两种模式的角色任务来说确实是非常相似的,但从实现架构上来说有一个核心不同点!
我们通过下面的图示来理解,就很清晰了:


可以看到这里有一个非常大的区别就是:发布订阅模式在两个角色中间是一个中间角色来过渡的,发布者并不直接与订阅者产生交互。
回想一下生产者消费者模式,这个中间过渡区域对应的就是是缓冲区。因为这个缓冲区的存在,发布者与订阅者的工作就可以实现更大程度的解耦。发布者不会因为订阅者处理速度慢,而影响自己的发布任务,它只需要快速生产即可。而订阅者也不用太担心一时来不及处理,因为有缓冲区在,可以一点点排队来完成(也就是我们常说的“削峰填谷”效果)。
而我们所熟知的RabbitMQ、Kafka、RocketMQ这些中间件的本质其实就是实现发布订阅模式中的这个中间缓冲区。而Redis也提供了简单的发布订阅实现,当我们有一些简单需求的时候,也是可以一用的!如果你已经理解了这个概念,那么就进入下一节,一起来做个例子吧!
动手试一试
下面的动手任务,我们将在Spring Boot应用中,通过接口的方式实现一个消息发布者的角色,然后再写一个Service来实现消息的订阅(把接口传过来的消息内容打印处理)。
第一步:创建一个基础的Spring Boot应用,如果还不会点这里
第二步:pom.xml中加入必须的几个依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
第三步:创建一个接口,用来发送消息。
@SpringBootApplication
public class Chapter55Application {
private static String CHANNEL = "didispace";
public static void main(String[] args) {
SpringApplication.run(Chapter55Application.class, args);
}
@RestController
static class RedisController {
private RedisTemplate<String, String> redisTemplate;
public RedisController(RedisTemplate<String, String> redisTemplate) {
this.redisTemplate = redisTemplate;
}
@GetMapping("/publish")
public void publish(@RequestParam String message) {
// 发送消息
redisTemplate.convertAndSend(CHANNEL, message);
}
}
}
这里为了简单实现,公用CHANNEL名称字段,我都写在了应用主类里。
第四步:继续应用主类里实现消息订阅,打接收到的消息打印处理
@Slf4j
@Service
static class MessageSubscriber {
public MessageSubscriber(RedisTemplate redisTemplate) {
RedisConnection redisConnection = redisTemplate.getConnectionFactory().getConnection();
redisConnection.subscribe(new MessageListener() {
@Override
public void onMessage(Message message, byte[] bytes) {
// 收到消息的处理逻辑
log.info("Receive message : " + message);
}
}, CHANNEL.getBytes(StandardCharsets.UTF_8));
}
}
第六步:验证结果
- 启动应用Spring Boot主类
- 通过curl或其他工具调用接口
curl localhost:8080/publish?message=hello - 观察控制台,可以看到打印了收到的message参数
2021-06-19 16:22:30.935 INFO 34351 --- [ioEventLoop-4-2] .c.Chapter55Application$MessageSubscribe : Receive message : hello
好了,今天的内容到这里结束了。如果你对本系列教程《Spring Boot 2.x基础教程》感兴趣,可以点击直达!。学习过程中如遇困难,建议加入Spring技术交流群,参与交流与讨论,更好的学习与进步!
代码示例
本文的完整工程可以查看下面仓库中的chapter5-5目录:
- Github:https://github.com/dyc87112/SpringBoot-Learning/
- Gitee:https://gitee.com/didispace/SpringBoot-Learning/
如果您觉得本文不错,欢迎Star支持,您的关注是我坚持的动力!更多本系列免费教程连载「点击进入汇总目录」
欢迎关注我的公众号:程序猿DD,分享外面看不到的干货与思考!
Spring Boot 2.x基础教程:使用Redis的发布订阅功能的更多相关文章
- Spring Boot 2.x基础教程:使用集中式缓存Redis
之前我们介绍了两种进程内缓存的用法,包括Spring Boot默认使用的ConcurrentMap缓存以及缓存框架EhCache.虽然EhCache已经能够适用很多应用场景,但是由于EhCache是进 ...
- Spring Boot 2.x基础教程:EhCache缓存的使用
上一篇我们学会了如何使用Spring Boot使用进程内缓存在加速数据访问.可能大家会问,那我们在Spring Boot中到底使用了什么缓存呢? 在Spring Boot中通过@EnableCachi ...
- Spring Boot 2.x基础教程:使用@Scheduled实现定时任务
我们在编写Spring Boot应用中经常会遇到这样的场景,比如:我需要定时地发送一些短信.邮件之类的操作,也可能会定时地检查和监控一些标志.参数等. 创建定时任务 在Spring Boot中编写定时 ...
- Spring Boot 2.x基础教程:使用Swagger2构建强大的API文档
随着前后端分离架构和微服务架构的流行,我们使用Spring Boot来构建RESTful API项目的场景越来越多.通常我们的一个RESTful API就有可能要服务于多个不同的开发人员或开发团队:I ...
- Spring Boot 2.x基础教程:JSR-303实现请求参数校验
请求参数的校验是很多新手开发非常容易犯错,或存在较多改进点的常见场景.比较常见的问题主要表现在以下几个方面: 仅依靠前端框架解决参数校验,缺失服务端的校验.这种情况常见于需要同时开发前后端的时候,虽然 ...
- Spring Boot 2.x基础教程:Swagger接口分类与各元素排序问题详解
之前通过Spring Boot 2.x基础教程:使用Swagger2构建强大的API文档一文,我们学习了如何使用Swagger为Spring Boot项目自动生成API文档,有不少用户留言问了关于文档 ...
- Spring Boot 2.x基础教程:Swagger静态文档的生成
前言 通过之前的两篇关于Swagger入门以及具体使用细节的介绍之后,我们已经能够轻松地为Spring MVC的Web项目自动构建出API文档了.如果您还不熟悉这块,可以先阅读: Spring Boo ...
- Spring Boot 2.x基础教程:使用国产数据库连接池Druid
上一节,我们介绍了Spring Boot在JDBC模块中自动化配置使用的默认数据源HikariCP.接下来这一节,我们将介绍另外一个被广泛应用的开源数据源:Druid. Druid是由阿里巴巴数据库事 ...
- Spring Boot 2.x基础教程:找回启动日志中的请求路径列表
如果您看过之前的Spring Boot 1.x教程,或者自己原本就对Spring Boot有一些经验,或者对Spring MVC很熟悉.那么对于Spring构建的Web应用在启动的时候,都会输出当前应 ...
随机推荐
- BUAA-OO-第四单元总结——终章
面向对象第四单元博客总结--终章 第四单元作业设计 第13次作业设计 类和对应方法属性设计 类设计如下图所示 本次作业主要涉及六个类,其中包括主类 Main ,通用Map类 UmlElementIdM ...
- 为什么说Zoho CRM是最好的销售预测系统?
在文章的开头,我们来讲讲什么是销售预测--销售预测是指利用销售管道中的商机.已完成的配额.有望完成目标的销售团队或个人等关键信息对产品的销售数量与销售金额进行预测的手段.企业在制定销售计划时的重要任务 ...
- 企业CRM系统选型的标准有哪些?
随着市场的发展,企业开始意识到客户的重要性.越来越多的企业形成了"以客户为核心"的理念,更加注重客户数据和管理,因此CRM客户关系管理系统成为企业的首选.选择一个适合企业的CRM系 ...
- 消息队列RabbitMQ(五):死信队列与延迟队列
死信队列 引言 死信队列,英文缩写:DLX .Dead Letter Exchange(死信交换机),其实应该叫做死信交换机才更恰当. 当消息成为Dead message后,可以被重新发送到另一个交换 ...
- [bug] maven“1.5不支持diamond运算符,请使用source 7或更高版本以启用diamond运算符”
原因 maven打包默认采用jdk 1.5,无法识别<> 解决 在pom.xml中加入: <properties> <maven.compiler.source>1 ...
- 保姆级别的RabbitMQ教程!一看就懂!(有安装教程,送安装需要的依赖包,送Java、Golang两种客户端教学Case)
保姆级别的RabbitMQ教程!一看就懂!(有安装教程,送安装需要的依赖包,送Java.Golang两种客户端教学Case) 目录 什么是AMQP 和 JMS? 常见的MQ产品 安装RabbitM ...
- 攻防世界(五)Web_php_include
攻防世界系列:Web_php_include 方法一:大小写绕过 strstr()函数对php我协议进行了过滤,但我们可以尝试大小写绕过 抓包POST传值让其执行我们输入的命令 ?page=Php:/ ...
- 046.Python协程
协程 1 生成器 初始化生成器函数 返回生成器对象,简称生成器 def gen(): for i in range(10): #yield 返回便能够保留状态 yield i mygen = gen( ...
- WPS2019党政机关单位版(无广告困扰)
WPS2019党政机关单位版(无广告困扰) 科技趣闻 中国石油大学(华东) 控制科学与工程硕士 17 人赞同了该文章 导读 WPS Office 2019专业版机关版是由WPS官方专为企业.机关单 ...
- Redis 主从架构搭建
引言 准备搭建的是主从架构( Master/Slave )中的一主两从模式:其中 Master 为 Redis 的主服务器,主要负责写操作,两个 Slave 为 Redis 的从服务器,主要负责读操作 ...