当前位置: 首页 > article >正文

【Redis】基于redis实现订阅发布

背景

业务发展过程中,希望做到异步解耦,但是又不想引入MQ中间件,在中小型服务中,就可以考虑使用redis自带的订阅发布来解决这个问题。使用 Redis 实现消息的订阅和发布时,可以通过 Spring Boot 集成 Redis 来方便地实现。

引入redis依赖

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

配置 Redis

application.properties 文件中,添加 Redis 配置:

spring.redis.host=localhost
spring.redis.port=6379

编写代码

  1. Redis 配置

    创建一个配置类来配置 Redis 的连接工厂和监听器:

    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.data.redis.connection.RedisConnectionFactory;
    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.core.StringRedisTemplate;
    
    @Configuration
    public class RedisConfig {
    
        @Bean
        public RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory,
                                                       MessageListenerAdapter listenerAdapter) {
            RedisMessageListenerContainer container = new RedisMessageListenerContainer();
            container.setConnectionFactory(connectionFactory);
            container.addMessageListener(listenerAdapter, topic());
            return container;
        }
    
        @Bean
        public MessageListenerAdapter listenerAdapter(RedisMessageSubscriber subscriber) {
            return new MessageListenerAdapter(subscriber, "onMessage");
        }
    
        @Bean
        public ChannelTopic topic() {
            return new ChannelTopic("messageQueue");
        }
    
        @Bean
        public StringRedisTemplate template(RedisConnectionFactory connectionFactory) {
            return new StringRedisTemplate(connectionFactory);
        }
    }
    
  2. 创建消息订阅者

    编写一个类来处理收到的消息:

    import org.springframework.stereotype.Service;
    
    @Service
    public class RedisMessageSubscriber {
    
        public void onMessage(String message, String channel) {
            System.out.println("Received message: " + message + " from channel: " + channel);
        }
    }
    
  3. 创建消息发布者

    编写一个发布者通过 Redis 模板发送消息:

    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.data.redis.core.StringRedisTemplate;
    import org.springframework.data.redis.listener.ChannelTopic;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RequestParam;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    public class MessagePublisher {
    
        @Autowired
        private StringRedisTemplate template;
    
        @Autowired
        private ChannelTopic topic;
    
        @GetMapping("/publish")
        public String publish(@RequestParam String message) {
            template.convertAndSend(topic.getTopic(), message);
            return "Message published: " + message;
        }
    }
    

如果需要监听多个channel,可以通过RedisConfig中添加新的消息适配器。

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
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.core.StringRedisTemplate;

@Configuration
public class RedisConfig {

    @Bean
    public RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory,
            MessageListenerAdapter listenerAdapter1,
            MessageListenerAdapter listenerAdapter2) {
        RedisMessageListenerContainer container = new RedisMessageListenerContainer();
        container.setConnectionFactory(connectionFactory);
        container.addMessageListener(listenerAdapter1, topic1());
        container.addMessageListener(listenerAdapter2, topic2());
        return container;
    }

    @Bean
    public MessageListenerAdapter listenerAdapter1(RedisMessageSubscriber subscriber) {
        return new MessageListenerAdapter(subscriber, "onMessage");
    }

    @Bean
    public MessageListenerAdapter listenerAdapter2(RedisMessageSubscriber subscriber) {
        return new MessageListenerAdapter(subscriber, "onMessage");
    }

    @Bean
    public ChannelTopic topic1() {
        return new ChannelTopic("channelOne");
    }

    @Bean
    public ChannelTopic topic2() {
        return new ChannelTopic("channelTwo");
    }

    @Bean
    public StringRedisTemplate template(RedisConnectionFactory connectionFactory) {
        return new StringRedisTemplate(connectionFactory);
    }
}

同时RedisMessageSubscriber 也可以书写多个来区分不同的业务场景下不同业务处理。


http://www.kler.cn/a/387294.html

相关文章:

  • 【C++】详解RAII思想与智能指针
  • CSP/信奥赛C++语法基础刷题训练(1):洛谷P5715 :三位数排序
  • Elasticsearch中什么是倒排索引?
  • Java项目实战II基于Spring Boot的药店管理系统的设计与实现(开发文档+数据库+源码)
  • 基于python 的opencv 使用GrabCut算法分割图像代码
  • ReactPress:构建高效、灵活、可扩展的开源发布平台
  • 算法训练(leetcode)二刷第十七天 | 235. 二叉搜索树的最近公共祖先、701. 二叉搜索树中的插入操作、*450. 删除二叉搜索树中的节点
  • 停车场微信小程序的设计与实现(lw+演示+源码+运行)
  • 饱和限幅器MATLAB和CODESYS平台下的实现
  • 同步时钟装置为新能源电力赋能强基!
  • 【数据集】【YOLO】【目标检测】水面船只识别数据集 9798 张,YOLO船只识别算法实战训练教程!
  • [FBCTF 2019]rceservice 详细题解
  • O-RAN 分布式单元 (O-DU) 参考架构
  • 【SPIE出版 | ISSN: 0277-786X,EI检索稳定!】2024年计算机视觉与图像处理国际学术会议 (CVIP 2024,11月15-17日)
  • 以旅游产品为例改写一篇系统架构风格的论文
  • Docker Compose部署Rabbitmq(延迟插件已下载)
  • 搜维尔科技:Manus VR数据手套-人形机器人的远程操作和机器学习
  • 从0开始学习机器学习--Day20--优化算法的思路
  • leetcode25:k个一组链表反转
  • C++STL容器详解——list
  • nvidia本地环境部署以及jetson交叉编译环境部署
  • 网络安全技术及其在企业中的应用
  • Jest进阶知识:深入测试 React Hooks-确保自定义逻辑的可靠性
  • yum下载时出现报错 Couldn‘t read a file:// file for file:///mnt/repodata/repomd.xml
  • 进程设计理念
  • 【sass】sass中两种去重的方法:混合 - mixin/include、继承 - extend