JAVA 实现 Redis 发布订阅

news2024/11/19 3:48:07

Redis 发布订阅

发布订阅:消息发布者发布消息消息订阅者接收消息,两者之间通过某种媒介联系起来

例如订杂志,当自己订阅了爱格杂志,每个月会发刊一本。到发布的时候派送员将杂志送到自己手上就能看到杂志内容。只有我们订阅了该杂志才会派送给我们

Redis 发布订阅(pub/sub)是一种 消息通信模式 :发送者(pub)发送消息,订阅者(sub)接收消息。

Redis 客户端可以订阅任意数量的频道。

订阅 / 发布消息图:

图中可以看出,所需:

  1. 消息发送者 、 2. 频道 、 3. 消息订阅者

发布订阅机制

  1. 当一个客户端通过 PUBLISH 命令向订阅者发布消息的时候,称这个客户端为发布者publisher
  2. 当一个客户端通过subscribe 或者 PSUBSCRIBE 接收消息时,称这个客户端为 订阅者 subscriber
  3. 为了解耦发布者和订阅者之间的关系,Redis 使用了频道channel(频道)作为两者之间的中介,发布者直接把消息发送给 channel,而 channel 负责把消息发送给订阅者,发布者和订阅者之间没有直接的联系,都不知道对方的存在

订阅者 1,2,3 订阅了频道 channel,当有消息发布给频道时,这个消息就会被发送到三个订阅者客户端

demo 实现

学习参考链接

引入依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

添加配置文件

spring:
  redis:
    host: 127.0.0.1
    database: 5
    password:
    port: 6379
  1. Listener模式

创建一个监听容器

@Configuration
public class CatListenerConfig extends CachingConfigurerSupport {

    /**
     * 消息监听容器
     *
     * @param factory
     * @return
     */
    @Bean
    RedisMessageListenerContainer container(RedisConnectionFactory factory){
        RedisMessageListenerContainer container = new RedisMessageListenerContainer();
        container.setConnectionFactory(factory);
        //订阅一个通道 该处的通道名是发布消息时的名称
       container.setConnectionFactory(connectionFactory);
        //订阅了一个叫cat 的通道
        container.addMessageListener(catAdapter, new PatternTopic("cat"));
        container.addMessageListener(fishAdapter, new PatternTopic("fish"));
        return container;
    }

    

}
@Component
public class CatListener implements MessageListener {
    @Override
    public void onMessage(Message message, byte[] bytes) {
        System.out.println("我是监听者,我监听到的消息是 " + message.toString());
    }
}
package com.maoxs.listener;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.connection.MessageListener;
import org.springframework.data.redis.core.RedisTemplate;

/**
 * 监听发送的消息
 */
public class FishListener extends MessageListenerAdapter implements MessageListener  {

    @Autowired
    RedisTemplate redisTemplate;

    @Override
    public void onMessage(Message message, byte[] bytes) {
        System.out.println("我是Fish监听" + message.toString());
    }
}

建测试类,测试发布监听

@RestController
public class TestController {

    @Resource
    StringRedisTemplate stringRedisTemplate;

    @PostMapping("/cat")
    public void test2(){
        stringRedisTemplate.convertAndSend("cat","测试:消息发布者发布消息");
    }
  
   @PostMapping("/fish")
    public void fish(){
        stringRedisTemplate.convertAndSend("fish","测试:消息发布者发布消息");
    }
}

测试结果

  1. Adapter模式

    2.1 配置

        /**
         * MessageListenerAdapter 模式
         * 该处topic的 key为bean的name
         * @param connectionFactory
         * @param adapterMap
         * @return
         */
        @Bean
        public RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory,Map<String, MessageListenerAdapter> adapterMap) {
            RedisMessageListenerContainer container = new RedisMessageListenerContainer();
            container.setConnectionFactory(connectionFactory);
            adapterMap.keySet().forEach(topic-> container.addMessageListener(adapterMap.get(topic),new PatternTopic(topic)));
            return container;
        }
    

    监听1

    package com.sst.loan.risk.listener;
    
    import com.sst.loan.risk.manager.RuleLoadManager;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.data.redis.connection.Message;
    import org.springframework.data.redis.listener.adapter.MessageListenerAdapter;
    import org.springframework.stereotype.Component;
    
    import javax.annotation.Resource;
    
    /**
     * 监听适配器
     *
     * @author 蔡定努
     * @date 2023/06/13 10:26
     */
    @Slf4j
    @Component("ruleRefreshAdapter")
    public class RuleRefreshAdapter  extends MessageListenerAdapter {
      
    
    
        @Override
        public void onMessage(Message message, byte[] bytes) {
            log.info(">>>>>>> 消息适配器收到刷新规则的请求 <<<<<<<<<<<<<<");
    
        }
    }
    
    

    监听2

    package com.sst.loan.risk.listener;
    
    import com.sst.loan.risk.manager.RuleLoadManager;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.data.redis.connection.Message;
    import org.springframework.data.redis.listener.adapter.MessageListenerAdapter;
    import org.springframework.stereotype.Component;
    
    import javax.annotation.Resource;
    
    /**
     * 监听适配器
     *
     * @author 蔡定努
     * @date 2023/06/13 10:26
     */
    @Slf4j
    @Component("ruleRefreshAdapter2")
    public class RuleRefreshAdapter2  extends MessageListenerAdapter {
      
    
    
        @Override
        public void onMessage(Message message, byte[] bytes) {
            log.info(">>>>>>> 消息适配器收到刷新规则的请求 <<<<<<<<<<<<<<");
            
        }
    }
    

    测试

    
        @Resource
        private StringRedisTemplate stringRedisTemplate;
    
    
        /**
         * 
         * @author 蔡定努
         */
        @GetMapping("refresh")
        public Object refresh() {
            stringRedisTemplate.convertAndSend("ruleRefreshAdapter","refresh");
            return Result.success();
        }
        
        
        /**
         * 
         * @author 蔡定努
         */
        @GetMapping("refresh")
        public Object refresh() {
            stringRedisTemplate.convertAndSend("ruleRefreshAdapter2","refresh");
            return Result.success();
        }
    

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

为什么美颜插件比传统集成方式更快?

都说云市场插件快&#xff0c;快在哪里呢&#xff1f; 美颜功能是实时互动应用的基础功能&#xff0c;广泛应用在社交、直播、约会、会议等场景&#xff0c;开发者们往往在集成美颜功能时候非常头疼。今天&#xff0c;我们来介绍云市场美颜插件相比传统的裸数据集成方式快在哪…

Unity与原生交互之Unity篇——AndroidStudio导出aar/jar包供Unity使用实现交互全流程(2)

序言:此篇介绍在(1)的基础上引入Unity的API库进行交互,原生调Unity 1.导入Unity库 注意: (1)老版本Unity的classes.jar里包含UnityPlayerActivity API (2)新版本Unity的UnityPlayerActivity API 在UnityEditor安装路径中,需单独导入,后续介绍 1.1导入unity的classes.jar …

Seesion会话超时时间测试-业务安全测试实操(3)

Seesion会话超时时间测试, Cookie仿冒测试, 密文比对认证测试 本地加密传输测试-业务安全测试实操(2)_luozhonghua2000的博客-CSDN博客 测试原理和方法 在用户成功登录系统获得Session认证会话后,该Session认证会话应具有生命周期,即用户在成功登录系统后,如果在固定时间内…

反汇编逆向实战——扫雷辅助制作

一、编程前准备 刚开始是预备知识&#xff0c;如果熟悉的话&#xff0c;可以直接跳到第二部分阅读 在 Windows API 中&#xff0c;SetTimer 函数用于创建一个定时器&#xff0c;并在指定的时间间隔后触发一个定时器消息。以下是关于 SetTimer 函数的介绍&#xff1a; 功能&a…

接口文档设计注意事项

接口名称清晰 一般接口url要求能看得出接口的作用。比如说&#xff0c;查询用户信息&#xff08;queryUserInfo&#xff09;&#xff0c;就是一个不错的接口名称。 接口地址完整 接口的地址&#xff0c;也叫接口的URL地址。即别人调用你的接口&#xff0c;用的是什么URL。比…

【Unity Shader】入门到惊叹(1)基本概念:什么是网格?材质?Shader?

文章目录 一、什么是网格(Mesh)?二、什么是MeshFilter(网格过滤器)?三、什么是MeshRenderer(网格渲染器)?四、什么是材质(Material)?五、什么是Shader(着色器)?一、什么是网格(Mesh)? 如图,模型的三角形面就叫做网格(Mesh),它的本质是一堆顶点数据的规则排…

华为OD机试真题 JavaScript 实现【按身高和体重排队】【2022Q4 100分】,附详细解题思路

一、题目描述 某学校举行运动会&#xff0c;学生们按编号(1、2、3…n)进行标识&#xff0c;现需要按照身高由低到高排列&#xff0c;对身高相同的人&#xff0c;按体重由轻到重排列&#xff1b; 对于身高体重都相同的人&#xff0c;维持原有的编号顺序关系。请输出排列后的学生…

医械围城的觉醒时刻:从“乱世枭雄” 到“剩者为王”

我们现在看到医疗器械行业其实非常的热&#xff0c;不管是投资&#xff0c;还是创业&#xff0c;还有各种跨界进来打劫想分一杯羹的。 但是这个行业是不是一个围城&#xff1f; 真的是进来就可以捡钱吗&#xff1f; 在一片繁荣的景象下&#xff0c;企业的发展存在什么风险&a…

STM32FreeRTOS操作系统移植

移植好的FreeRTOS模板&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1_87VQAWXUl4jTqSCZ0MFjw?pwddw52 提取码&#xff1a;dw52 1.在工程中新建FreeRTOS文件夹 2.把源码source里面的文件全部粘贴进FreeRTOS文件夹中 3.在portable文件中只保留一下文件&#xff0c;…

【剑指offer刷题记录 java版】数组双指针 之 二分搜索

本系列文章记录labuladong的算法小抄中剑指offer题目 【剑指offer刷题记录 java版】数组双指针 之 二分搜索 剑指 Offer 53 - I. 在排序数组中查找数字 I剑指 Offer II 068. 查找插入位置剑指 Offer 04. 二维数组中的查找剑指 Offer II 069. 山峰数组的顶部剑指 Offer II 073. …

java周期性线程池newScheduledThreadPool介绍,多线程下载url文件(断点下载、进度展示、网速展示、剩余时间展示)

文章目录 一&#xff1a;newScheduledThreadPool&#xff08;周期性线程池&#xff09;1.1 特点1.2 核心线程数1.3 创建实例1.4 常用方法1.4.1 schedule方法1.4.2 scheduleAtFixedRate方法1.4.3 scheduleWithFixedDelay方法 二&#xff1a;多线程下载展示文件总大小、剩余时间、…

基于SpringBoot+vue的简历系统设计和实现

博主介绍&#xff1a; 大家好&#xff0c;我是一名在Java圈混迹十余年的程序员&#xff0c;精通Java编程语言&#xff0c;同时也熟练掌握微信小程序、Python和Android等技术&#xff0c;能够为大家提供全方位的技术支持和交流。 我擅长在JavaWeb、SSH、SSM、SpringBoot等框架下…

ESXi 7.0 U3m HPE (慧与) 定制版 OEM Custom Installer CD

VMware ESXi 7.0 Update 3m - 领先的裸机 Hypervisor (All OEM Customized Installer CDs) ESXi 7.0 U3m Standard (标准版) ESXi 7.0 U3m Dell (戴尔) 定制版 OEM Custom Installer CD ESXi 7.0 U3m HPE (慧与) 定制版 OEM Custom Installer CD ESXi 7.0 U3m Lenovo (联想) 定…

基于SSM的养老机构信息管理系统设计与实现

摘 要 随着我国老年人逐渐增加&#xff0c;老人们的子女数量减少&#xff0c;工作时间过长无暇照顾父母&#xff0c;导致养老院和护工需求量大幅上涨。伴随我国生活水平提高的同时对老年人的护工人员的要求也越来越高。根据以上要求关于养老院有很多的信息需要进行管理&#…

Zero-Shot, One-Shot, and Few-Shot Learning概念介绍

导语 本文将介绍零样本学习、一次样本学习和少样本学习的概念&#xff0c;它们使得机器学习模型能够在仅有有限数量的示例情况下对对象或模式进行分类和识别。 在机器学习中&#xff0c;我们通常需要大量的训练数据来训练模型&#xff0c;以便它能够准确地识别和分类新的输入…

数据挖掘知识与学习方向

数据挖掘是一门涉及多个学科的交叉学科&#xff0c;需要掌握的知识点也比较多。以下是一些数据挖掘的基础知识和学习方向&#xff1a; 数据库&#xff1a;需要掌握 SQL 语言和数据库设计&#xff0c;以便能够有效地管理和处理数据。 统计学&#xff1a;需要掌握基本的统计学知…

硬盘初始化后数据还能恢复吗?硬盘被初始化怎么恢复数据

现今热门的数据恢复话题之一便是硬盘被初始化后如何恢复数据。或许许多人都遭遇过这一问题&#xff0c;往往因为误操作或不小心&#xff0c;导致硬盘数据被不可逆地清除。所以&#xff0c;为帮助广大用户避免数据丢失的情况&#xff0c;本文将为大家介绍如何恢复被初始化的硬盘…

基于注解的Spring(IOC+AOP)

目录 这是基于黑马Spring的笔记 写再前面 开始 Component(valuebean的名称) componet衍生出的3个注解 Bean内部的属性进行注入 非自定义的Bean管理 使用配置类完全替代XML配置文件 配置类中的注解 spring中的其他注解&#xff08;偶尔会用到) Spring注解的解析原理 sp…

Java Supervisor RPC2 接口对接

1.引入xmlrpc-client 如果是C#语言&#xff0c;请参考《C#对接supervisor XML-RPC API 实现进程控制》 如何安装Supervisor&#xff0c;请参考《Linux进程守护—Supervisor&#xff08;ubuntu&#xff09;》 如果是Maven项目&#xff0c;则在pom.xml引入jar包 <dependenc…

详解CSS中的flex布局

详解CSS中的flex布局 1、概念2、容器属性2.1 flex-direction2.2 flex-wrap2.3 flew-flow2.4 justify-content2.5 align-items2.6 align-content 3、元素属性3.1 order3.2 flex-grow3.3 flex-shrink3.4 flex-basis3.5 flex3.6 align-self 1、概念 弹性盒子&#xff08;display: …