重学SpringBoot3-集成Redis(六)之消息队列
更多SpringBoot3内容请关注我的专栏:《SpringBoot3》
期待您的点赞👍收藏⭐评论✍
重学SpringBoot3-集成Redis(六)之消息队列
- 1. 什么是发布/订阅(Pub/Sub)?
- 2. 场景应用
- 3. Spring Boot 3 整合 Redis 实现发布/订阅
- 3.1. 添加依赖
- 3.2. 配置 Redis 连接
- 3.3. 实现消息发布功能
- 3.4. 实现消息订阅功能
- 3.5. 测试发布/订阅功能
- 3.6. 使用Redisson
- 4. 总结
Redis 不仅是一个高效的缓存解决方案,也具备强大的消息队列功能。通过 Redis 的 发布/订阅(Pub/Sub) 机制,开发者可以轻松实现服务之间的通信和消息传递功能,而无需引入专门的消息队列工具。这篇文章将介绍如何通过 Spring Boot 3 和 Redis 实现消息队列的发布与订阅功能。
1. 什么是发布/订阅(Pub/Sub)?
发布/订阅是一种消息传递模式,发布者发送消息到某个频道(channel),而订阅了该频道的所有订阅者都会收到该消息。这种模式与传统的消息队列不同,不会将消息存储下来,而是将其立即广播给所有的订阅者。因此,发布/订阅模式非常适合用于通知、事件广播等实时性较强的场景。
- 发布者:向一个或多个频道发布消息。
- 订阅者:订阅一个或多个频道,实时接收消息。
2. 场景应用
- 事件驱动系统:如任务通知、状态更新、日志广播。
- 消息通知服务:如实时的新闻推送、股票行情推送。
- 微服务通信:不同服务之间的消息传递。
3. Spring Boot 3 整合 Redis 实现发布/订阅
在 Spring Boot 3 中,我们可以通过 Spring Data Redis 轻松集成 Redis 的发布/订阅功能。
3.1. 添加依赖
首先,我们需要在项目的 pom.xml 文件中添加必要的依赖,详细参考重学SpringBoot3-集成Redis(一)基本使用。
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency>
3.2. 配置 Redis 连接
在 application.yml 中配置 Redis 连接信息:
spring:data:redis:host: localhostport: 6379 # Redis 端口password: # 如果有密码可以在这里配置lettuce:pool:max-active: 100 # 最大并发连接数max-idle: 50 # 最大空闲连接数min-idle: 10 # 最小空闲连接数
3.3. 实现消息发布功能
首先,我们需要创建一个 消息发布者,用于发送消息到特定的频道:
package com.coderjia.boot310redis.config;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;/*** @author CoderJia* @create 2024/10/6 下午 10:44* @Description**/
@Component
public class MessagePublisher {@Autowiredprivate RedisTemplate redisTemplate;public void publish(String channel, String message) {redisTemplate.convertAndSend(channel, message);System.out.println("Message published to channel " + channel + ": " + message);}
}
在这个类中,RedisTemplate 被用来将消息发送到指定的频道。
3.4. 实现消息订阅功能
接下来,我们实现一个 消息订阅者,用于监听特定频道的消息:
package com.coderjia.boot310redis.config;import org.springframework.stereotype.Component;/*** @author CoderJia* @create 2024/10/6 下午 10:45* @Description**/
@Component
public class MessageSubscriber {public void onMessage(String message, String channel) {System.out.println("Received message from channel " + channel + ": " + message);}
}
为了让这个订阅者生效,我们需要注册一个消息监听器:
package com.coderjia.boot310redis.config;import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.listener.ChannelTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.data.redis.listener.adapter.MessageListenerAdapter;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;/*** @author CoderJia* @create 2024/10/4 下午 12:43* @Description**/
@Configuration
public class RedisConfig {@Beanpublic RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {RedisTemplate<String, Object> template = new RedisTemplate<>();template.setConnectionFactory(redisConnectionFactory);// 使用String序列化器序列化Keytemplate.setKeySerializer(new StringRedisSerializer());// 使用Jackson2JsonRedisSerializer序列化ValueObjectMapper objectMapper = new ObjectMapper();Jackson2JsonRedisSerializer<Object> serializer = new Jackson2JsonRedisSerializer<>(objectMapper,Object.class);template.setValueSerializer(serializer);return template;}@Beanpublic RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory,MessageListenerAdapter listenerAdapter) {RedisMessageListenerContainer container = new RedisMessageListenerContainer();container.setConnectionFactory(connectionFactory);container.addMessageListener(listenerAdapter, new ChannelTopic("myChannel"));return container;}@Beanpublic MessageListenerAdapter listenerAdapter(MessageSubscriber subscriber) {return new MessageListenerAdapter(subscriber, "onMessage");}
}
在这个配置类中,我们使用 RedisMessageListenerContainer 来监听频道消息,并使用 MessageListenerAdapter 将消息处理委托给 MessageSubscriber。
3.5. 测试发布/订阅功能
在我们的控制器或服务中,我们可以调用 MessagePublisher 来发布消息,并观察 MessageSubscriber 是否正确接收消息。
package com.coderjia.boot310redis.demos.web;import com.coderjia.boot310redis.config.MessagePublisher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;/*** @author CoderJia* @create 2024/10/6 下午 10:47* @Description**/
@RestController
public class PubSubController {@Autowiredprivate MessagePublisher messagePublisher;@GetMapping("/publish")public String publishMessage(@RequestParam String message) {messagePublisher.publish("myChannel", message);return "Message published!";}
}
现在,我们可以启动应用程序,并通过访问 curl http://localhost:8080/publish?message=Hello 来测试消息发布,订阅者会自动接收到该消息。

也可以使用 redis 命令 PUBLISH myChannel "Hello, world!" 向渠道发布消息,订阅者同样可以接收到消息。

3.6. 使用Redisson
使用 Redisson 同样能能实现发布订阅功能,而且是更接近 MQ 使用方式,下列代码仅供参考。
public void publish(String channel, String message) {// redisTemplate.convertAndSend(channel, message);// System.out.println("Message published to channel " + channel + ": " + message);// 获取TopicRTopic topic = redissonClient.getTopic("myChannel");// 向渠道发送消息topic.publish("Hello, world!");topic.addListener(String.class, (channel1, message1) -> {System.out.println("Received message from channel " + channel1 + ": " + message1);});}
4. 总结
通过 Spring Boot 3 与 Redis 的整合,消息发布与订阅功能的实现非常简洁且高效。Redis 的发布/订阅功能不仅可以用于简单的消息通知,还可以结合其他业务场景,如微服务通信、日志广播等。虽然 Redis 的 Pub/Sub 并不具备消息持久化的能力,但它在需要即时消息传递的场景下,具有很高的性能和灵活性。
这篇文章为 Redis 消息队列功能奠定了基础,后续将深入 Redis 的其他功能,如缓存管理、分布式锁等。如果你对 Redis 有其他问题或建议,欢迎留言讨论!
相关文章:
重学SpringBoot3-集成Redis(六)之消息队列
更多SpringBoot3内容请关注我的专栏:《SpringBoot3》 期待您的点赞👍收藏⭐评论✍ 重学SpringBoot3-集成Redis(六)之消息队列 1. 什么是发布/订阅(Pub/Sub)?2. 场景应用3. Spring Boot 3 整合 R…...
LeetCode 134 Gas Station 解题思路和python代码
题目: There are n gas stations along a circular route, where the amount of gas at the ith station is gas[i]. You have a car with an unlimited gas tank and it costs cost[i] of gas to travel from the ith station to its next (i 1)th station. You …...
服务攻防
171、一次完整的 HTTP 请求过程 域名解析 --> 发起 TCP 的 3 次握手 --> 建立 TCP 连接后发起 http 请求 --> 服务器 响应 http 请求,浏览器得到 html 代码 --> 浏览器解析 html 代码,并请求 html 代码中的资源(如 js、 css…...
leetcode 力扣算法题 快慢指针 双指针 19.删除链表的倒数第n个结点
删除链表的倒数第N个结点 题目要求题目示例解题思路从题目中的已知出发思考寻找目标结点条件转换核心思路 需要注意的点改进建议 完整代码提交结果 题目要求 给你一个链表,删除链表的倒数第n个结点,并且返回链表的头结点。 题目示例 示例 1࿱…...
网络五层模型:物理层、数据链路层、网络层、传输层、应用层,分别解决了什么问题?
网络五层模型(也称为TCP/IP模型的简化版本)将网络通信过程分为五个层次,每一层都解决了特定的问题。以下是每一层的详细解释及其解决的问题: 1. 物理层(Physical Layer) 解决的问题:数据的物理…...
OpenCV视频I/O(18)视频写入类VideoWriter之初始化 VideoWriter 对象的函数open()的使用
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 初始化或重新初始化视频编写器。 该方法打开视频编写器。参数与构造函数 VideoWriter::VideoWriter 中的相同。 cv::VideoWriter::open() 函数用…...
大数据处理从零开始————4.认识HDFS分布式文件系统
1.分布式文件系统HDFS 1.1 认识HDFS 当单台服务器的存储容量和计算性能已经无法处理大文件时,分布式文件系统应运而生。什么是分布式系统,分布式系统是由多个独立的计算机或节点组成的系统,这些计算机通过网络连接ÿ…...
jwt认证课件讲解
JWT 基本概念 在用户登录后,我们需要在不同请求之间记录用户的登录状态,常用方式一般有三种:Cookie,Session和Token。 这里我们使用第三种Token令牌方式来实现认证鉴权,采用Json Web Token认证机制(简称…...
【判断推理】逻辑基础
1.1 命题 用语言、符号或者式子表达的,可以判断真假的陈述句称为命题,一般写为 若p,则q 真命题:判断为真的语句假命题:判断为假的语句 eg1:小张是中国人(若是小张,则是中国人&#…...
AcWing 655:天数转换 ← 整除、求余
【题目来源】https://www.acwing.com/problem/content/657/【题目描述】 读取对应于一个人的年龄(以天为单位)的整数值,并转化为年,月和日表示方式输出,年、月、日分别对应 ano(s), mes(es), dia(s)。 注意:…...
【解决办法】git clone报错unable to access ‘xxx‘: SSL certificate problem:
使用git clone 时报错unable to access xxx: SSL certificate problem: 这个报错通常是由于SSL证书问题引起的。通常可以按照以下步骤进行排查: 检查网络连接:确保你的网络连接正常,可以访问互联网。尝试使用其他网站或工具测试网络连接是否正…...
算法笔记(十三)——BFS 解决最短路问题
文章目录 迷宫中离入口最近的出口最小基因变化单词接龙为高尔夫比赛砍树 BFS 解决最短路问题 BFS(广度优先搜索) 是解决最短路径问题的一种常见算法。在这种情况下,我们通常使用BFS来查找从一个起始点到目标点的最短路径。 迷宫中离入口最近的出口 题目:…...
Android 简单实现联系人列表+字母索引联动效果
效果如上图。 Main Ideas 左右两个列表左列表展示人员数据,含有姓氏首字母的 header item右列表是一个全由姓氏首字母组成的索引列表,点击某个item,展示一个气泡组件(它会自动延时关闭), 左列表滚动并显示与点击的索引列表item …...
自动驾驶-问题笔记-待解决
参考线的平滑方法 参考线平滑算法主要有三种: 离散点平滑;螺旋曲线平滑;多项式平滑; 参考链接:参考线平滑 对于平滑方法,一直不太理解平滑、拟合以及滤波三者的作用与区别; 规划的起点&#x…...
在掌控板中加载人教版信息科技教学指南中的educore库
掌控板中加载educore库 人教信息科技数字资源平台(https://ebook.mypep.cn/free)中的《信息科技教学指南硬件编程代码说明》文件中提到“本程序说明主要供教学参考。需要可编程主控板须支持运行MicroPython 脚本程序。希望有更多的主控板在固件中支持ed…...
关于CSS Grid布局
关于CSS Grid布局 实际效果参考 参考代码 <template><view class"baseInfo"><up-image class"cover" height"160rpx" width"120rpx" :src"bookInfo.cover"><template #error><view style"…...
初始爬虫12(反爬与反反爬)
学到这里,已经可以开始实战项目了,多去爬虫,了解熟悉反爬,然后自己总结出一套方法怎么做。 1.服务器反爬的原因 服务器反爬的原因 总结: 1.爬虫占总PV较高,浪费资源 2.资源被批量抓走,丧失竞争力…...
成像基础 -- 最大对焦清晰的物距计算
最大对焦清晰的物距计算 1. 基本概念 最大对焦清晰的物距通常与景深(Depth of Field, DOF)相关,尤其是无穷远处的物体可以被清晰对焦到的距离,称为超焦距(Hyperfocal Distance)。通过计算超焦距ÿ…...
win10服务器启动且未登录时自动启动程序
场景:公司服务器安装了几个程序,当服务器断电重启之后希望程序能自动打开,而不需要手动登录服务器打开。 因为软件是自己开发的所以安全方面这里没有考虑。 1.打开服务器管理器,点击工具,选择任务计划程序 2.在任务计…...
算法专题四: 前缀和
目录 1. 前缀和2. 二维前缀和3. 寻找数组的中心下标4. 除自身以外数组的乘积5. 和为k的子数组6. 和可被K整除的子数组7. 连续数组8. 矩阵区域和 博客主页:酷酷学!!! 感谢关注~ 1. 前缀和 算法思路: 根据题意, 创建一个前缀和数组, dp[i] dp[i -1] arr[i], 再使用前缀和数组,…...
遍历 Map 类型集合的方法汇总
1 方法一 先用方法 keySet() 获取集合中的所有键。再通过 gey(key) 方法用对应键获取值 import java.util.HashMap; import java.util.Set;public class Test {public static void main(String[] args) {HashMap hashMap new HashMap();hashMap.put("语文",99);has…...
Cesium1.95中高性能加载1500个点
一、基本方式: 图标使用.png比.svg性能要好 <template><div id"cesiumContainer"></div><div class"toolbar"><button id"resetButton">重新生成点</button><span id"countDisplay&qu…...
Python爬虫实战:研究feedparser库相关技术
1. 引言 1.1 研究背景与意义 在当今信息爆炸的时代,互联网上存在着海量的信息资源。RSS(Really Simple Syndication)作为一种标准化的信息聚合技术,被广泛用于网站内容的发布和订阅。通过 RSS,用户可以方便地获取网站更新的内容,而无需频繁访问各个网站。 然而,互联网…...
页面渲染流程与性能优化
页面渲染流程与性能优化详解(完整版) 一、现代浏览器渲染流程(详细说明) 1. 构建DOM树 浏览器接收到HTML文档后,会逐步解析并构建DOM(Document Object Model)树。具体过程如下: (…...
在Ubuntu中设置开机自动运行(sudo)指令的指南
在Ubuntu系统中,有时需要在系统启动时自动执行某些命令,特别是需要 sudo权限的指令。为了实现这一功能,可以使用多种方法,包括编写Systemd服务、配置 rc.local文件或使用 cron任务计划。本文将详细介绍这些方法,并提供…...
Java面试专项一-准备篇
一、企业简历筛选规则 一般企业的简历筛选流程:首先由HR先筛选一部分简历后,在将简历给到对应的项目负责人后再进行下一步的操作。 HR如何筛选简历 例如:Boss直聘(招聘方平台) 直接按照条件进行筛选 例如:…...
如何理解 IP 数据报中的 TTL?
目录 前言理解 前言 面试灵魂一问:说说对 IP 数据报中 TTL 的理解?我们都知道,IP 数据报由首部和数据两部分组成,首部又分为两部分:固定部分和可变部分,共占 20 字节,而即将讨论的 TTL 就位于首…...
OPENCV形态学基础之二腐蚀
一.腐蚀的原理 (图1) 数学表达式:dst(x,y) erode(src(x,y)) min(x,y)src(xx,yy) 腐蚀也是图像形态学的基本功能之一,腐蚀跟膨胀属于反向操作,膨胀是把图像图像变大,而腐蚀就是把图像变小。腐蚀后的图像变小变暗淡。 腐蚀…...
Reasoning over Uncertain Text by Generative Large Language Models
https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829 1. 概述 文本中的不确定性在许多语境中传达,从日常对话到特定领域的文档(例如医学文档)(Heritage 2013;Landmark、Gulbrandsen 和 Svenevei…...
GitFlow 工作模式(详解)
今天再学项目的过程中遇到使用gitflow模式管理代码,因此进行学习并且发布关于gitflow的一些思考 Git与GitFlow模式 我们在写代码的时候通常会进行网上保存,无论是github还是gittee,都是一种基于git去保存代码的形式,这样保存代码…...
