Spring Data Redis(Redis Messaging/PubSub)

Spring Boot 2.x基础教程:使用Redis的发布订阅功能 通过前面一篇集中式缓存的使用教程,我们已经了解了Redis的核心功能:作为K、V存储的高性能缓存。 接下来我们会分几篇来继续讲讲Redis的一些其他强大用法!如果你对此感兴趣,一定要关注收藏我哦! 发布订阅模式 如果你看过之前我写的关于MQ的相关文章,那么对于发布订阅功能应该不会陌生。如果没看过,那也不要紧,这里先做一个简单介绍,已经了解的可以跳过直接看下一节内容。 什么是发布订阅模式? 在发布订阅模式中有个重要的角色,一个是发布者Publisher,另一个订阅者Subscriber。本质上来说,发布订阅模 阅读详情

Redis Messaging/PubSub

Spring Data为 Redis提供了专用的消息传送集成,与Spring 框架集成JMS有相似的功能和命名方式;实际上,对Spring 支持的JMS 熟悉的用户,则很容易对Redis 的消息传送上手。

Redis messaging在功能上可以粗略的分为两个部分:生产/发布 和 消费/订阅,因此简称pubsub(Publish/Subscribe)。RedisTemplate这个类是用来生产消息的。对于异步接收,与JavaEE的消息驱动bean风格很相似,Spring Data提供了一个专用的消息监听容器,用来创建消息驱动POJOs(MDPs);对于同步接收,则由RedisConnecton contract。

对于使用Redis messaging 提供了核心的功能的类或接口,都在下面这两个包内:org.springframework.data.redis.connection 和 org.springframework.data.redis.listener 。

1. Sending/Publishing messages
发送/发布消息

要发布一个消息,你可以像其他操作一样,使用底层的RedisConnection 或高级别的RedisTemplate 。两个实体都提供了发布的方法,方法需要传递参数:要发送的消息和目的地通道。然而,RedisConnetion 需要传递的消息类型是原生的数据(字节数组),而RedisTemplate 则允许任意的 objects。

伪代码示例:

// send message through connection RedisConnection con = ...
byte[] msg = ...
byte[] channel = ...
con.publish(msg, channel); // send message through RedisTemplate
RedisTemplate template = ...
template.convertAndSend("hello!", "world");

2. Receiving/Subscribing for messages
接收/订阅消息

在接收端,你可以订阅一个或多个通道,通过直接命名或使用模式匹配。使用模式匹配的方式是相当有用的,它不仅仅可以用一个命令创建多个订阅,还可以监听在订阅的时候还没有创建的通道,只要它们匹配模式即可。

在底层,RedisConnection 提供了subscribe 和pSubscribe 方法,来对应Redis 的订阅命令,并由各自的模式来匹配各个通道。注意,大多数的通道或模式都被作为参数传递使用的。要改变一个连接的订阅,或者简单的查询是不是被订阅了,可以使用RedisConnection 的getSubscription 和isSubscribed 方法。

在Spring Data Redis 中订阅的命令是阻塞的。就是说,在一个连接上调用subscribe 方法,会阻塞当前线程来等待消息,否则只有在该订阅被取消的情况下该线程才会被释放,取消订阅必须由另外一个线程在同一个连接上调用unsubscribe 或者pUnsubscribe方法。要解决上面的问题需要查看下面的消息监听容器章节。

像上面提到的一样,一旦订阅了一个连接开始等待消息,在该连接上将不会调用其他命令,除了添加新的订阅 或 修改/取消一个存在的订阅。就是说,除了subscribe、pSubscribe、unsubscribe或者 pUnsubscribe,调用任何其他命令都是非法的,将抛出一个异常。

为了订阅消息,你需要实现MessageListener callback:每当一个新消息到了后,这个callbakc 将会被调用,在onMessage 方法中的用户的代码将会被执行。通过这个接口可以访问到:真实的消息、接收消息的通道、让订阅来匹配通道的模式(如果有的话)。这些信息可以供调用者来区分各式各样的消息,不仅仅可以通过内容还可以通过数据来进行。

Message Listener Containers

由于它具有阻塞的本性,低层次的订阅并不被人所关注,因为对于每个单独的监听都需要管理连接和线程。为了缓和这个问题,Spring Data提供了RedisMessageListenerContainer ,它代替用户做了所有的繁重的工作,熟悉EJB 和JMS 的用户可能会理解这个观念,它被设计的尽可能的被Spring 框架和它的消息驱动POJOs(MDPs)支持。

RedisMessageListenerContainer 作为一个消息监听容器;它被用来从Redis 通道接收消息,驱动所有注入到它里面的MessageListener。这个监听容器负责所有消息接收,然后发送到监听器进行处理。一个消息监听容器是一个MDP和一个消息提供者的中间媒介,它关心的是注册接收消息、资源的获取和释放、异常的转换等类似的事情。这允许应用开发者专心去写涉及到接收消息的业务逻辑(可能很复杂),让框架来关注Redis 底层的基础。

此外,为了最小化应用程序的内存占用,RedisMessageListenerContainer 允许一个连接和一个线程可以被多个监听器共享,即使它们不共享一个订阅都可以。因此无论一个应用有多少个监听器或通道,在它的生命周期内运行时的内存消耗都是一样的。此外,容器允许在运行的时候对配置信息进行修改,所以当应用运行中可以添加或删除监听器,而不用重启应用。加之容器还使用了懒订阅的方式,因此只有在需要的时候才使用RedisConnection ,如果所有的监听器都没有被订阅,会自动执行清除,释放掉所有的线程。

为了处理异步方式的消息,容器需要一个 java.util.concurrent.Executor ( 或者Spring 的TaskExecutor)来发送消息。依据机器的负载、监听器的数量或运行时的环境,你应该通过修改或设置执行器使它能更好的服务。尤其是在托管的环境下(像app服务),强烈的建议选择一个适当的TaskExecutor,使其在运行时能充分的发挥作用。

The MessageListenerAdapter

MessageListenerAdapter 这个类是Spring 异步消息发送支持的最后一个组件:简单的说,它允许你将几乎任何一个类转化为一个MDP(当然也有一些限制)。

考虑以下接口的定义。注意尽管这个接口不能继承MessageListener 接口,但它通过使用MessageListenerAdapter 这个类仍可以作为一个MDP。还要注意,依据可以接收和处理的各种消息类型的内容,各种消息的处理方法是如何强化类型的。此外,消息发送使用的通道或模式,以String类型作为第二个参数传入方法。

代码示例如下:

public interface MessageDelegate {
  void handleMessage(String message);
  void handleMessage(Map message); void handleMessage(byte[] message);
  void handleMessage(Serializable message);
  // pass the channel/pattern as well
  void handleMessage(Serializable message, String channel);
 }
public class DefaultMessageDelegate implements MessageDelegate {
  // implementation elided for clarity...
}

特别应该注意的是,上面的MessageDelegate 接口的实现类(如DefaultMessageDelegate )已经完全不依赖于Redis了。它只是一个POJO,我们将通过下面的配置将它变成一个MDP。

配置如下:

<?xml version="1.0" encoding="UTF-8"?>
 <beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns:redis="http://www.springframework.org/schema/redis"
   xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
   http://www.springframework.org/schema/redis http://www.springframework.org/schema/redis/spring-redis.xsd">

<!-- the default ConnectionFactory -->
<redis:listener-container>
  <!-- the method attribute can be skipped as the default method name is "handleMessage" -->
  <redis:listener ref="listener" method="handleMessage" topic="chatroom" />
</redis:listener-container>

<bean id="listener" class="redisexample.DefaultMessageDelegate"/>
 ...
<beans>
The listener topic can be either a channel (e.g. topic="chatroom") or a pattern (e.g. topic="*room")
监听器的主题可以是一个通道或一个模式。

上面示例使用Redis的命名空间声明了消息的监听器容器,并自动将POJOs注册为一个监听器。beans的定义展示如下:

<bean id="messageListener" class="org.springframework.data.redis.listener.adapter.MessageListenerAdapter">
  <constructor-arg>
    <bean class="redisexample.DefaultMessageDelegate"/>
  </constructor-arg>
</bean>

<bean id="redisContainer" class="org.springframework.data.redis.listener.RedisMessageListenerContainer">
  <property name="connectionFactory" ref="connectionFactory"/>
  <property name="messageListeners">
    <map>
      <entry key-ref="messageListener">
        <bean class="org.springframework.data.redis.listener.ChannelTopic">
          <constructor-arg value="chatroom">
        </bean>
      </entry>
    </map>
  </property>
</bean>

每收到一个消息,这个适配器会自动的执行转化(使用配置的RedisSerializer),显示的将低级的格式转化为需要的对象类型,或反之。方法调用引起的任何异常,将会被容器捕获并处理。

Spring Boot集成Redis实现keyevent监听 | Spring Cloud 33 Spring Boot集成Redis实现Key事件监听。 阅读详情

相关推荐

java.lang.NoClassDefFoundError: org/springframework/data/redis/connection/SubscriptionListener

报错如下图,从图中明显可以看到服务已经启动成功,测试redis链接,请求都是正常的。但在启动后有一次发布链接超时,从报错信息上看 是订阅读取超时。研究了一番,发现是包有冲突的问题导致的。将引用的包拆分,不在使用redisson-spring-boot-starter,redisson 这个包是我项目中通过redis的延时关单机制,使用到的。redis发布订阅只需要用到常规的spring-data-redis包。

aayygg1234的专栏 2097

Rk3568 百兆以太网RMII模式DTS配置详解

本文详细解析了RK3568芯片在百兆以太网RMII模式下的DTS配置方法,包括时钟树配置、PHY接口模式定义及实际工程中的进阶设置。通过实战案例和调试技巧,帮助开发者快速解决RMII模式下的常见问题,提升工业控制设备的网络稳定性。

weixin_29189377的博客 420

解决SpringBoot启动报错:NoClassDefFoundError: org/springframework/data/redis/connection/RedisStreamCommands

22

dengchao1013的博客 1万+

戴尔PowerEdge服务器R450 RAID配置步骤

戴尔PowerEdge服务器R450 RAID配置步骤

且听风呤tmj的博客 6910

C#上位机通信层封装:西门子S7NetPlus库的优雅使用

支持S7-1200/1500(机架号0,槽号1)、S7-300/400(机架号/槽号需根据实际配置);支持位(Bit)、字节(Byte)、字(Word)、双字(DWord)、浮点数(Float/Double)等数据类型的读写;支持DB块、输入寄存器(I)、输出寄存器(Q)、内存寄存器(M)、定时器(T)、计数器(C)的操作;轻量无依赖,兼容.NET 5+。首先定义核心枚举和常量,统一规范参数类型,避免硬编码。/// 西门子PLC型号(对应不同的机架/槽号默认配置)

这里只有干货:从 Modbus 通信到 MES 对接,从 YOLO 训练到工控机部署,带你搞定工业软件开发全流程。 1085

解决java.lang.NoClassDefFoundError: org/springframework/data/redis/connection/RedisStreamCommands

这是在 springboot 中使用 redisson 时,因为引入的依赖为 <dependency> <groupId>org.redisson</groupId> <artifactId>redisson-spring-boot-starter</artifactId> <version>3.14.0</version> </dependency> 这个...

哇哇哇,真的学到了!!! 1万+

深度学习在移动开发中的应用:实时姿态估计实战

我们将使用TensorFlow Lite框架,结合专为移动端优化的MoveNet模型,实现一个能够在主流Android设备上达到30FPS的多人姿态跟踪解决方案,并深入探讨其优化技巧和实际应用场景。特别是3D姿态估计、多人长期跟踪等前沿技术的发展,将进一步推动移动端姿态估计技术的应用深度和广度。在下一篇文章中,我们将探讨深度学习在移动端的另一个创新应用:实时手势识别,包括如何在资源受限的环境中实现复杂手势的实时识别,以及这项技术在AR/VR交互、智能家居控制等场景中的应用。第四部分:典型应用场景实现。

Programming Talk 325

RedisCache工具类

package com.kejin.utils.redis; import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.u...

u013008898的博客 4450

Stable Diffusion WebUI 安装前准备

大家好,我是水滴~~在安装 stable-diffusion-webui 前需要做一些准备工作,本篇文章主要介绍需要的电脑配置、魔法、安装 Python、安装 Git 等。

水滴的博客 2100

第4.4节:保护轴承与安全系统

飞轮储能系统的保护轴承是磁悬浮失效时的最后安全屏障,其设计需满足非干涉性、高可靠性和有限寿命承载原则。转子跌落过程包括自由下落、碰撞、进动和滑行减速等复杂非线性阶段,产生远超常规工况的冲击载荷。保护轴承需具备极限冲击容量、高温耐受性和抗卡死能力。系统采用多层级安全架构,结合故障诊断与健康管理,通过监测振动、电流等参数实现预测性维护。安全停机序列有序结合主动制动与被动摩擦制动,确保系统在极端工况下的安全。保护轴承类型多样,需根据系统规模与可靠性要求合理选择。

技术工作者 226

springboot连接redis出现org.springframework.data.redis。RedisConnectionFailureException异常

org.springframework.data.redis.RedisConnectionFailureException: Unable to connect to Redis; nested exception is io.lettuce.core.RedisConnectionException: Unable to connect to 192.168.36.129:6379 如果你的springboot连接redis异常跟我一样,也是无法连接,请往下接着看。 一、 查看application资源

m0_67393828的博客 1万+

AUTOSAE软件配置-达芬奇( DaVinci Configurator)从新建工程开始

方法1,直接使用案例工程,一般SIP包会有一个创建好的案例工程,在这样的路径YOUR_SIP_DIR/Applications/SipAddon/StartApplication下面直接打开这个*.dpa文件即可看到已经预先做好的工程:但是,这个也不是全的,也不一定完全正确,至少MCAL是没有配置好的(MCAL是IC厂商提供的,并不归属SIP包的一部分)。这样就需要你自己去配置你想要的模块,修改里面的错误。

m0_49148264的博客 2935

Redis(spring data redis) 发布订阅 pub/sub

Spring Data为Redis提供了专用的消息集成,功能类似,并命名为Spring Framework中的JMS集成。 Redis消息大致可分为两个功能区域: 发布或生产消息 订阅或消费消息 通常被称为发布/订阅模式。RedisTemplate类是用来生产消息的。对于类似于Java EE的消息驱动bean形式的异步接收,Spring Data提供了一个专用的消息监听器容器...

top_explore的博客 859

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

redis连接失败报错 org.springframework.data.redis.RedisConnectionFailureException: Unable to connect to Red

无法远程连接虚拟机redis 报错org.springframework.data.redis.RedisConnectionFailureException: Unable to connect to Redis;

miai_345的博客 4830

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

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

一、发布和订阅机制   当一个客户端通过 PUBLISH 命令向订阅者发送信息的时候,我们称这个客户端为发布者(publisher)。   而当一个客户端使用 SUBSCRIBE 或者 PSUBSCRIBE 命令接收信息的时候,我们称这个客户端为订阅者(subscriber)。 为了解耦发布者(publisher)和订阅者(subscriber)之间的关系,Redis 使用了 ch...

acy29712的博客 245

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

springboot项目整合springDataRedis实现消息对列的pub/sub

众所周知,redis是nosql数据库,因此大多数情况下,在我们的项目中都是用于数据信息的缓存(例如:商城项目中缓存商品的基本信息),以便于提高数据响应效率,同时又可减少对关系型数据库的压力。 然而redis非关系型数据库的另一个很重要的功能,往往会被大多数人忽略,这个功能就是“消息队列”功能,一般用于电商项目的红包过期通知,或一些项目的日志过滤处理等。 Redis 发布订阅(pub/sub)是一...

qq_38041579的博客 544

Springboot-Redis - 10.Redis 消息 (Pub/Sub)

Redis 支持发布/订阅模式,允许客户端订阅指定的频道并收到发送到这些频道的消息。在 Spring Data Redis 中,你可以使用来处理消息的订阅和接收。

yueerba126的博客 991

java redis sub_基于Spring+redis实现pub/sub

基于Spring+redis实现pub/subPub / Sub(publisher/subcriber发布和订阅)消息是许多软件架构的重要组成部分。消息传递解决方案提供了高性能,可扩展性,队列持久性和耐用性,故障转移支持等,以及许多更漂亮具备的功能,在Java世界中大多总是使用JMS实现。后来使用Apache ActiveMQ的,有时只是需要简单的排队支持,而Apache ActiveMQ显得过...

weixin_29837797的博客 444

spring boot + redis 实现信息的发送和接收(pub/sub)

redis本身就带有发送接收的功能,用redis来发送接收的方法如下: 1.redis侦听的方法 2.redis发送信息的方法 3.刚才1中的画面中应该能看到如下内容 从以上看来redis-cli带有发送接收信息的功能,但是用spring-data-redis如何来实现呢,其实比较简单,可以有两个方法,一个方法通过实现MessageListener接口类实现,但是他有一个问题,在侦听信息需...

lin000_0的博客 5476

SpringBoot 集成Redis PubSub发布订阅/Stream消息队列

SpringBoot 集成Redis PubSub发布订阅/Stream消息队列

qq_41902662的博客 2378

org.springframework.data.redis.RedisConnectionFailureException异常解决

记录一下自己做项目的时候遇到的这个redis异常 场景描述: 我安装的是windows版本的redis,点击登录功能的时候将用户密码存到redis中结果报出异常: org.springframework.data.redis.RedisConnectionFailureException: Unable to connect to Redis; nested exception is io.lettuce.core.RedisConnectionException: Unable to connect to

Sexycool的博客 8666

Spring-data-redis

官方推荐两个都启用,如果对数据不敏感,可以选单独用RDB,不建议单独用 AOF,因为可能会出现Bug如果只是做纯内存缓存,可以都不用。

yyd686874的博客 1485

使用redis实现发布订阅功能及问题

通过接口调用时,请求只能打到服务B的一个pod上,而我们想要的是服务B的每个pod都能收到服务A发送的请求数据,所以使用redis的发布订阅来实现。提示就是加载SubscriptionListener这个类失败了,找不到,搜一圈之后各种尝试,然后找到了解决办法。服务A通过接口操作服务B,实现相应逻辑。生产环境上,服务A有两个pod,服务B有3个pod。1)redis配置类中,增加消息监听的逻辑。代码咔咔写完了,然后就是启动服务测试逻辑了。说是redis包的问题,项目中用的是。我们的data是个实体。

panying941206的博客 654

Spring整合Redis(八)----发布/订阅消息

Spring Data为Redis提供了专用的消息集成,在功能和命名方面与Spring Framework中的JMS集成类似。这是一个通常称为发布/订阅(简称Pub/Sub)的模式示例。RedisTemplate类用于消息生成。对于类似于Java EE的消息驱动bean风格的异步接收,Spring Data提供了一个专用的消息监听器容器,用于创建消息驱动的POJO(MDP),对于同步接收,还提供RedisConnection。

爱看技术博客 768

Spring Data Redis

5.9. Redis Messaging/PubSubSpring Data 提供 dedicated messaging 整合 for Redis, very similar in functionality and naming to the JMS integration in Spring Framework; in fact, users familiar with the JMS sup

沈林楠的专栏 791
上一篇: Spring Data Redis(Hash mapping)
下一篇: Spring Data Redis(Redis Transactions)
架构师的清醒
博客等级 码龄14年 291粉丝 397原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值