Spring Boot+Redis 实现消息队列实践示例

Spring Boot+Redis 实现一个轻量级的消息队列

文章目录

  • Spring Boot+Redis 实现一个轻量级的消息队列
  • 0.前言
  • 1.基础介绍
  • 2.步骤
    • 2.1. 引入依赖
    • 2.2. 配置文件
    • 2.3. 核心源码
  • 4.总结
    • 答疑
  • 5.参考文档
  • 6. Redis从入门到精通系列文章

在这里插入图片描述

0.前言

本文将介绍如何利用Spring Boot与Redis结合实现消息队列的实践示例。消息队列是一种常用的解耦和异步通信的机制,可以在系统中实现高效的消息传递和处理。而Redis作为一种高性能的内存数据库,具备发布/订阅功能,非常适合用于构建消息队列系统。

在本实践示例中,我们将使用Spring Boot框架和Redis作为基础,通过Redis的发布/订阅模型来实现简单的消息队列。 如何通过消息通道进行消息的发布和订阅。

在开始之前,你需要对Spring Boot和Redis有一定的了解,并确保已正确配置好开发环境。本文将提供实际的代码示例和详细的步骤说明, 并能够根据具体业务需求进行扩展和定制。

1.基础介绍

Redis提供了发布/订阅(Publish/Subscribe)模式,用于实现消息的广播和异步通信。下面是关于Redis发布/订阅模式的介绍:

发布/订阅模式(Pub/Sub)
发布/订阅模式是一种消息通信模式,其中消息的发布者(Publisher)将消息发送到特定的频道(Channel),而订阅者(Subscriber)可以订阅一个或多个频道以接收消息。这种模式允许消息的广播和异步传递,发送者和接收者之间解耦。

Redis的发布/订阅功能
Redis提供了原生的发布/订阅功能,使得开发者可以使用Redis作为消息中间件来实现高效的消息传递。以下是与Redis发布/订阅相关的关键概念和操作:
下面是将Redis发布/订阅功能整理成表格的示例:

概念说明
频道(Channel)Redis中用于发布和订阅消息的通道。每个消息都被发布到一个特定的频道,而订阅者可以选择订阅一个或多个感兴趣的频道。
发布消息(Publish)通过使用PUBLISH命令,发布者可以将消息发送到指定的频道。一旦消息被发布到频道,所有订阅该频道的客户端将接收到该消息。
订阅频道(Subscribe)通过使用SUBSCRIBE命令,客户端可以订阅一个或多个频道。一旦订阅成功,客户端将成为该频道的订阅者,可以接收到该频道上发布的消息。
取消订阅频道(Unsubscribe)通过使用UNSUBSCRIBE命令,客户端可以取消对一个或多个频道的订阅。当客户端不再对某个频道感兴趣时,可以选择取消订阅。
模式匹配订阅(Pattern Subscription)Redis支持使用PSUBSCRIBE命令进行模式匹配订阅。通过指定一个模式,可以订阅与该模式匹配的多个频道。

通过Redis的发布/订阅功能,可以构建高效的消息系统,实现消息的广播和异步传递。发布者将消息发布到特定的频道,而订阅者可以选择订阅感兴趣的频道来接收消息。这种模式的优点包括解耦、异步通信和实时性等,适用于很多场景,如实时通知、事件驱动系统和分布式系统间的消息传递等。

本文我们通过Spring Boot +Redis 实现一个轻量级的消息队列。

2.步骤

2.1. 引入依赖

<dependencies>
    <!-- Spring Data Redis -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>
</dependencies>

2.2. 配置文件

# Redis连接配置
spring.redis.host=127.0.0.1
spring.redis.port=6379
spring.redis.password=your_password
spring.redis.database=0

# Redis连接池配置
spring.redis.jedis.pool.max-active=50
spring.redis.jedis.pool.max-idle=10
spring.redis.jedis.pool.min-idle=5
spring.redis.jedis.pool.max-wait=-1

在上面的配置中,您可以根据实际情况修改以下属性:

  • spring.redis.host:Redis服务器的主机名或IP地址。
  • spring.redis.port:Redis服务器的端口号。
  • spring.redis.password:Redis服务器的密码(如果有的话)。
  • spring.redis.database:Redis数据库的索引,默认为0。

另外,您还可以配置Redis连接池的属性,以控制连接池的行为。在示例配置中,设置了以下连接池属性:

  • spring.redis.jedis.pool.max-active:连接池中的最大活动连接数。
  • spring.redis.jedis.pool.max-idle:连接池中的最大空闲连接数。
  • spring.redis.jedis.pool.min-idle:连接池中的最小空闲连接数。
  • spring.redis.jedis.pool.max-wait:从连接池获取连接的最大等待时间(毫秒),-1表示无限等待。

如果 使用的是YAML格式的配置文件(application.yml),可以将上述配置转换为相应的格式:

spring:
  redis:
    host: 127.0.0.1
    port: 6379
    password: your_password
    database: 0
  redis.jedis.pool:
    max-active: 50
    max-idle: 10
    min-idle: 5
    max-wait: -1

请根据您的实际Redis服务器配置进行调整,并根据需要添加其他相关配置,如超时设置、SSL配置等。

2.3. 核心源码

当使用Spring Boot与Redis结合实现消息队列时,可以使用Redis的发布/订阅功能来处理消息的发布和订阅。下面是

接下来,创建一个消息发布者和一个消息订阅者的类。在发布者类中,使用RedisTemplate来发布消息,而在订阅者类中,通过实现MessageListener接口来处理接收到的消息。

// 消息发布者
@Component
public class MessagePublisher {
    private final RedisTemplate<String, String> redisTemplate;
    private final ChannelTopic topic;

    public MessagePublisher(RedisTemplate<String, String> redisTemplate, ChannelTopic topic) {
        this.redisTemplate = redisTemplate;
        this.topic = topic;
    }

    public void publishMessage(String message) {
        redisTemplate.convertAndSend(topic.getTopic(), message);
    }
}

消息订阅者

// 消息订阅者
@Component
public class MessageSubscriber implements MessageListener {
    @Override
    public void onMessage(Message message, byte[] pattern) {
        String receivedMessage = message.toString();
        // 处理接收到的消息
        System.out.println("Received message: " + receivedMessage);
    }
}

接下来,配置Redis消息监听容器,以便启动消息监听器:

@Configuration
public class RedisConfig {

    @Bean
    public ChannelTopic topic() {
        return new ChannelTopic("messageQueue"); // 定义消息队列的通道名称
    }

    @Bean
    public MessageListenerAdapter messageListenerAdapter(MessageSubscriber messageSubscriber) {
        return new MessageListenerAdapter(messageSubscriber);
    }

    @Bean
    public RedisMessageListenerContainer redisContainer(RedisConnectionFactory redisConnectionFactory,
                                                       MessageListenerAdapter messageListenerAdapter,
                                                       ChannelTopic topic) {
        RedisMessageListenerContainer container = new RedisMessageListenerContainer();
        container.setConnectionFactory(redisConnectionFactory);
        container.addMessageListener(messageListenerAdapter, topic);
        return container;
    }
}

最后,在需要发布消息的地方,注入MessagePublisher并调用publishMessage()方法来发布消息:

@Service
public class MyService {
    private final MessagePublisher messagePublisher;

    public MyService(MessagePublisher messagePublisher) {
        this.messagePublisher = messagePublisher;
    }

    public void doSomethingAndPublishMessage() {
        // 执行一些操作
        String message = "Hello, Redis message queue!";
        messagePublisher.publishMessage(message);
    }
}

这样,当调用MyService中的doSomethingAndPublishMessage()方法时,消息将被发布到Redis的消息队列中,并由订阅者接收和处理。

请注意,以上示例是一个简化的实现,仅用于演示基本的消息发布和订阅流程。在实际的生产环境中,可能需要考虑更多的细节,如错误处理、消息确认机制、并发处理等。

4.总结

通过Redis的发布/订阅模型,Spring Boot利用RedisTemplate将消息发布到指定的Redis通道,同时使用MessageListenerAdapter将订阅者与消息通道绑定。当有消息发布到通道时,Redis会将消息广播给所有订阅该通道的客户端,然后MessageListenerAdapter将接收到的消息传递给相应的消息监听器进行处理。

这样,利用Redis的发布/订阅功能,我们可以实现基于Spring Boot与Redis的消息队列系统,实现消息的发布和订阅。通过这种异步的方式,消息发布者和订阅者可以解耦,提高系统的可伸缩性和性能。

答疑

上次介绍了 Redis 的pub和sub,以及Stream 有很多同学有疑惑项目中应该使用哪种。那么我们在此处再聊聊
Redis提供了两种不同的功能来实现消息队列:发布/订阅(Pub/Sub)和流(Stream)。选择使用哪种功能作为消息队列取决于您的具体需求和使用场景。

特点Redis发布/订阅(Pub/Sub)Redis流(Stream)
适用场景简单的消息广播和异步通信场景更复杂的消息队列需求,包括任务队列、事件溯源、日志收集等
消息持久化不支持消息的持久化和历史记录支持消息的持久化和历史记录
消息订阅方式订阅者选择订阅感兴趣的频道来接收消息多个消费者对消息进行消费
订阅前发布的消息无法获取先于订阅的消息可以获取订阅前发布的消息
实时性适用于需要即时通知、实时事件处理和实时数据传递的场景实时性较高,但受消费者的处理速度影响
消费者组管理不支持消费者组管理支持消费者组管理
消息顺序性消息的顺序不保证消息的顺序保证
用例示例即时聊天应用、实时通知系统、发布/订阅模式的消息传递任务队列、事件溯源、日志收集等

所以如果你的需求是简单的消息广播和异步通信,并且对消息的持久化和历史记录要求不高,可以选择使用Redis发布/订阅功能作为消息队列。而如果您需要更丰富的消息队列功能,包括消息的持久化、多个消费者的支持和消息历史记录等,那么Redis流是更好的选择。根据具体的使用场景和需求,选择适合的功能来实现消息队列。

5.参考文档

  1. Redis官方文档 - 发布/订阅:

    • 链接:https://redis.io/topics/pubsub ↗
    • 该文档提供了Redis发布/订阅功能的详细说明,包括基本概念、命令使用、示例代码和常见问题解答等。
  2. Redis命令文档 - PUBLISH:

    • 链接:https://redis.io/commands/publish ↗
    • 该文档介绍了PUBLISH命令的语法、参数和用法,以及与发布消息相关的注意事项。
  3. Redis命令文档 - SUBSCRIBE:

    • 链接:https://redis.io/commands/subscribe ↗
    • 该文档详细说明了SUBSCRIBE命令的语法、参数和用法,以及如何订阅频道并接收发布的消息。
  4. Redis命令文档 - UNSUBSCRIBE:

    • 链接:https://redis.io/commands/unsubscribe ↗
    • 该文档提供了UNSUBSCRIBE命令的说明,包括取消订阅频道的语法和参数。
  5. Redis命令文档 - PSUBSCRIBE:

    • 链接:https://redis.io/commands/psubscribe ↗
    • 该文档介绍了PSUBSCRIBE命令的用法,用于进行模式匹配订阅,可以订阅与指定模式匹配的多个频道。

6. Redis从入门到精通系列文章

  • 《Redis使用Lua脚本和Redisson来保证库存扣减中的原子性和一致性》
  • 《SpringBoot Redis 使用Lettuce和Jedis配置哨兵模式》
  • 《Redis【应用篇】之RedisTemplate基本操作》
  • 《Redis 从入门到精通【实践篇】之SpringBoot配置Redis多数据源》
  • 《Redis 从入门到精通【进阶篇】之三分钟了解Redis HyperLogLog 数据结构》
  • 《Redis 从入门到精通【进阶篇】之三分钟了解Redis地理位置数据结构GeoHash》
  • 《Redis 从入门到精通【进阶篇】之高可用哨兵机制(Redis Sentinel)详解》
  • 《Redis 从入门到精通【进阶篇】之redis主从复制详解》
  • 《Redis 从入门到精通【进阶篇】之Redis事务详解》
  • 《Redis从入门到精通【进阶篇】之对象机制详解》
  • 《Redis从入门到精通【进阶篇】之消息传递发布订阅模式详解》
  • 《Redis从入门到精通【进阶篇】之持久化 AOF详解》
  • 《Redis从入门到精通【进阶篇】之持久化RDB详解》
  • 《Redis从入门到精通【高阶篇】之底层数据结构字典(Dictionary)详解》
  • 《Redis从入门到精通【高阶篇】之底层数据结构快表QuickList详解》
  • 《Redis从入门到精通【高阶篇】之底层数据结构简单动态字符串(SDS)详解》
  • 《Redis从入门到精通【高阶篇】之底层数据结构压缩列表(ZipList)详解》
  • 《Redis从入门到精通【进阶篇】之数据类型Stream详解和使用示例》
    在这里插入图片描述大家好,我是冰点,今天的 Spring Boot+Redis 实现消息队列实践示例,全部内容就是这些。如果你有疑问或见解可以在评论区留言。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Docker容器与虚拟化技术:Docker资源控制、数据管理

目录 一、理论 1.资源控制 2.Docker数据管理 二、实验 1.Docker资源控制 2.Docker数据管理 三、问题 1.docker容器故障导致大量日志集满&#xff0c;造成磁盘空间满 2、当日志占满之后如何处理 四、总结 一、理论 1.资源控制 (1) CPU 资源控制 cgroups&#xff0…

数据结构:堆的实现

1.堆的概念 如果有一个关键码的集合 K { k1 &#xff0c;k2 &#xff0c;k3 &#xff0c;…&#xff0c;kn }&#xff0c;把它的所有元素按完全二叉树的顺序存储方式存储在一个一维数组中&#xff0c;并且 k(i) < k(i*21) 和 k(i) < k(i*22)&#xff0c; i 0 &#xff…

BUUCTF [安洵杯 2019]easy_serialize_php 1 详细讲解

题目来自buuctf&#xff0c;这是一题关于php序列化逃逸的题 1. 题目 题目给出的代码 <?php$function $_GET[f];function filter($img){$filter_arr array(php,flag,php5,php4,fl1g);$filter /.implode(|,$filter_arr)./i;return preg_replace($filter,,$img); }if($_S…

炬芯科技发布全新第二代智能手表芯片,引领腕上新趋势!

2023年7月&#xff0c;炬芯科技宣布全新第二代智能手表芯片正式发布。自2021年底炬芯科技推出第一代的智能手表芯片开始便快速获得了市场广泛认可和品牌客户的普遍好评。随着技术的不断创新和突破&#xff0c;为了更加精准地满足市场多元化的变幻和用户日益增长的体验需求&…

localhost:8080 is already in use

报错原因&#xff1a;本机的8080端口号已经被占用。因为机器的空闲端口号是随机分配的&#xff0c;而idea默认启动的端口号是8080,所以是存在这种情况。 对于这个问题&#xff0c;我们只需要重启idea或者修改项目的启动端口号即可。 更推荐第二种。对于修改项目启动端口号&…

vscode | linux | c++ intelliense 被弃用解决方案

每日一句&#xff0c;vscode用的爽是爽&#xff0c;主要是可配置太强了。如果也很会研究&#xff0c;可以直接去咸鱼接单了 废话少说&#xff0c;直接整。 用着用着说是c intelliense被弃用&#xff0c;很多辅助功能无法使用&#xff0c;像查看定义、查看引用、函数跳转、智能提…

Unity智慧园区夜景制作

近期使用Unity做了一个智慧园区场景的demo&#xff0c;初步了解了3D开发的一些步骤和知识&#xff0c;以下为制作的步骤&#xff0c;比较简略&#xff0c;备忘&#xff1a; 1. 制作前的设计分析&#xff1a; 1. 分析日光角度&#xff0c;阴影长度&#xff0c;效果 2. 分析冷暖…

前后端分离------后端创建笔记(10)用户修改

本文章转载于【SpringBootVue】全网最简单但实用的前后端分离项目实战笔记 - 前端_大菜007的博客-CSDN博客 仅用于学习和讨论&#xff0c;如有侵权请联系 源码&#xff1a;https://gitee.com/green_vegetables/x-admin-project.git 素材&#xff1a;https://pan.baidu.com/s/…

linux——mysql的高可用MHA

目录 一、概述 一、概念 二、组成 三、特点 四、工作原理 二、案例 三、构建MHA 一、基础环境 二、ssh免密登录 三、主从复制 master slave1 四、MHA安装 一、环境 二、安装node 三、安装manager 一、概述 一、概念 MHA&#xff08;MasterHigh Availability&a…

并发编程系列-CompletableFuture

利用多线程来提升性能&#xff0c;实质上是将顺序执行的操作转化为并行执行。仔细观察后&#xff0c;你还会发现在顺序转并行的过程中&#xff0c;一定会牵扯到异步化。举个例子&#xff0c;现在下面这段示例代码是按顺序执行的&#xff0c;为了优化性能&#xff0c;我们需要将…

哈工大开源“活字”对话大模型

一、介绍 大规模语言模型&#xff08;LLM&#xff09;在自然语言处理的通用领域已取得了令人瞩目的成功。对于广泛的应用场景&#xff0c;这种技术展示了强大的潜力&#xff0c;学术界和工业界的兴趣也持续升温。哈工大自然语言处理研究所30余位老师和学生参与开发了通用对话大…

数据库概述、部署MySQL服务、必备命令、密码管理、安装图形软件、SELECT语法 、筛选条件

Top NSD DBA DAY01 案例1&#xff1a;构建MySQL服务器案例2&#xff1a;密码管理案例3&#xff1a;安装图形软件案例4&#xff1a;筛选条件 1 案例1&#xff1a;构建MySQL服务器 1.1 问题 在IP地址192.168.88.50主机和192.168.88.51主机上部署mysql服务练习必备命令的使用 …

性能测试压力曲线模型分析

性能测试模压力曲线&#xff1a; 曲线图关键点介绍&#xff1a; 横轴&#xff1a;从左到右表现了Number of Concurrent Users&#xff08;并发用户数&#xff09;的不断增长。 纵轴&#xff1a;分别表示Utilization&#xff08;资源的利用情况&#xff0c;包括硬件资源和软件…

Android Framework 动态更新插拔设备节点执行权限

TF卡设备节点是插上之后动态添加&#xff0c;所以不能通过初始化设备节点权限来解决&#xff0c;需要监听TF插入事件&#xff0c;在init.rc 监听插入后动态更新设备节点执行权限 添加插拔TF卡监听 frameworks/base/services/core/java/com/android/server/StorageManagerServic…

Vue3组件库

Vue组件库 ViteVue3TypescriptTSX 1、项目搭建 1.1、创建项目&#xff08;yarn&#xff09; D:\WebstromProject>yarn create vite yarn create v1.22.19 [1/4] Resolving packages... [2/4] Fetching packages... [3/4] Linking dependencies... [4/4] Building fresh pa…

MySQL8安装和删除教程 下载源码 保姆级(Windows)

删除 停止Mysql服务 管理员的权限来运行cmd&#xff0c;输入 net stop MySQL80 注意你电脑上的MySQL服务不一定是MySQL80,MySQL80是默认的&#xff0c;不是怎么办?在services.msc中找即可 下载一个小工具 geek:Geek下载打开软件&#xff0c;在列表中找到图片中的两项 sc…

【微服务技术一】Eureka、Nacos、Ribbon(配置管理、注册中心、负载均衡)

微服务技术一 技术栈图一、注册中心Eureka概念&#xff1a;搭建EurekaServer服务注册服务发现&#xff08;消费者对提供者的远程调用&#xff09; 二、Ribbon负载均衡负载均衡的原理&#xff1a;LoadBalanced负载均衡的策略&#xff1a;IRule懒加载 三、Nacos注册中心Nacos的安…

excel中定位条件,excel中有哪些数据类型、excel常见错误值、查找与替换

一、如何定位条件 操作步骤&#xff1a;开始 - 查找和选择 - 定位条件&#xff08;ctrl G 或 F5&#xff09; 注&#xff1a;如果F5不可用&#xff0c;可能是这个快捷键被占用了 案例&#xff1a;使用定位条件选择取余中空单元格&#xff0c;填入100&#xff0c;按组合键ct…

【MySQL】MySQL不走索引的情况分析

未建立索引 当数据表没有设计相关索引时&#xff0c;查询会扫描全表。 create table test_temp (test_id int auto_incrementprimary key,field_1 varchar(20) null,field_2 varchar(20) null,field_3 bigint null,create_date date null );expl…

Python源码05:使用Pyecharts画词云图图

**Pyecharts是一个用于生成 Echarts 图表的 Python 库。Echarts 是一个基于 JavaScript 的数据可视化库&#xff0c;提供了丰富的图表类型和交互功能。**通过 Pyecharts&#xff0c;你可以使用 Python 代码生成各种类型的 Echarts 图表&#xff0c;例如折线图、柱状图、饼图、散…