SpringBoot2.0集成Redis的sub/pub(订阅/发布)功能实现获取Redis实时数据

本文介绍了如何在SpringBoot2.0项目中集成Redis的订阅/发布(Sub/Pub)功能,以实现从SparkStreaming处理后的实时数据获取。首先,添加Redis相关依赖;接着,在SparkStreaming中处理数据并存储到Redis,部分数据通过Redis发布给订阅客户端;然后,详细阐述了SpringBoot项目中订阅/发布配置类RedisReceiver和RedisSubListenerConfig的创建。启动后,receiveMessage方法接收消息并进行推送处理。

实现场景如下:项目在SparkStreaming中对数据进行实时处理 处理结果会存储到redis中,其中一部分数据还会通过redis发布功能 发布给Redis的订阅客户端 ,达到实时数据处理结果的获取,(客户端订阅该频道,会实时的收到推送信息,然后将信息通过WebScoket在推送到前台,WebScoket的推送在另偏博客有写)。

1.SpringBoot项目中的pom依赖 需要引入redis相关依赖

        <!-- Spring Boot Redis依赖 -->
        <!-- 注意:1.5版本的依赖和2.0的依赖不一样,注意看哦 1.5我记得名字里面应该没有“data”, 2.0必须是“spring-boot-starter-data-redis” 这个才行-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
            <!-- 1.5的版本默认采用的连接池技术是jedis  2.0以上版本默认连接池是lettuce, 在这里采用jedis,所以需要排除lettuce的jar -->
            <exclusions>
                <exclusion>
                    <groupId>redis.clients</groupId>
                    <artifactId>jedis</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>io.lettuce</groupId>
                    <artifactId>lettuce-core</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <!-- 添加jedis客户端 -->
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
        </dependency>

        <!--spring2.0集成redis所需common-pool2-->
        <!-- 必须加上,jedis依赖此  -->
        <!-- spring boot 2.0 的操作手册有标注 大家可以去看看 地址是:https://docs.spring.io/spring-boot/docs/2.0.3.RELEASE/reference/htmlsingle/-->
        &
在 Spring Boot 中,将 Redis发布/订阅Pub/Sub)机制转换为使用 Redis Stream 的方式,需要理解两者在实现机制和使用场景上的差异。Redis Stream 是 Redis 5.0 引入的特性,它提供了持久化、消息确认、消费者组等高级功能,适合用于构建可靠的消息队列系统。以下是如何在 Spring Boot 中实现这一转换的步骤。 ### 1. 使用 Redis Stream 替代 Pub/Sub 的核心机制 Redis Pub/Sub 是一种基于主题的消息广播机制,消息在发布后如果没有订阅者接收,就会被丢弃。而 Redis Stream 则支持消息持久化存储,即使消费者暂时不可用,消息也不会丢失。 在 Spring Boot 中,可以通过 `RedisTemplate` 或 `ReactiveRedisTemplate` 来操作 Redis Stream。以下是一个使用 `RedisTemplate` 向 Stream 发送消息的示例: ```java @Autowired private RedisTemplate<String, Object> redisTemplate; public void sendMessageToStream(String streamKey, Map<String, Object> message) { redisTemplate.opsForStream().add(streamKey, message); } ``` ### 2. 消费 Redis Stream 中的消息 为了消费 Redis Stream 中的消息,可以使用 `StreamMessageListenerContainer` 来监听指定的 Stream。Spring Data Redis 提供了 `StreamMessageListenerContainer` 来支持异步消费 Stream 消息,并支持消费者组和消息确认机制。 以下是一个基于 `StreamMessageListenerContainer` 的监听器配置示例: ```java @Configuration public class RedisStreamConfig { @Autowired private RedisConnectionFactory redisConnectionFactory; @Bean public StreamMessageListenerContainer<String, ObjectRecord<String, String>> streamMessageListenerContainer() { StreamMessageListenerContainer.StreamMessageListenerContainerOptions<String, ObjectRecord<String, String>> options = StreamMessageListenerContainerOptions.builder() .pollTimeout(Duration.ofSeconds(1)) .build(); StreamMessageListenerContainer<String, ObjectRecord<String, String>> container = StreamMessageListenerContainer.create(redisConnectionFactory, options); container.receive(StreamOffset.create("mystream", ReadOffset.lastConsumed())); container.start(); return container; } } ``` ### 3. 消费者组与消息确认机制 Redis Stream 支持消费者组(Consumer Group),多个消费者可以共享一个消费者组,从而实现负载均衡。消费者在处理完消息后需要手动确认(ACK),否则消息会保留在 Stream 中,直到确认成功。 以下是一个使用消费者组监听 Stream 的示例: ```java @Bean public void registerStreamListener(StreamMessageListenerContainer<String, ObjectRecord<String, String>> container) { container.receive("mygroup", StreamOffset.create("mystream", ReadOffset.from("0-0")), message -> { System.out.println("Received message: " + message.getValue()); // 业务处理逻辑 // 确认消息 message.ack(); }); } ``` ### 4. 替换 Pub/Sub 的注意事项 - **持久化与可靠性**:Redis Stream 的消息默认持久化存储,适合需要高可靠性的场景;而 Pub/Sub 是即时广播,消息不持久化。 - **消费者组与负载均衡**:Stream 支持消费者组,适合构建分布式消息队列系统;而 Pub/Sub 是广播模式,无法实现负载均衡。 - **消息重放与追溯**:Stream 支持按 ID 重新读取消息,适合需要追溯历史消息的场景;而 Pub/Sub 不支持消息回溯。 ### 5. 示例:从 Pub/Sub 转换为 Stream 的代码对比 #### Pub/Sub 发送消息: ```java redisTemplate.convertAndSend("channel", "message"); ``` #### Stream 发送消息: ```java Map<String, Object> message = new HashMap<>(); message.put("event", "test"); redisTemplate.opsForStream().add("mystream", message); ``` #### Pub/Sub 接收消息: ```java @Component public class RedisSubscriber { @Autowired private RedisTemplate<String, Object> redisTemplate; @PostConstruct public void subscribe() { redisTemplate.getConnectionFactory().getConnection().subscribe((message, pattern) -> { System.out.println("Received: " + new String(message.getBody())); }, "channel".getBytes()); } } ``` #### Stream 接收消息(使用消费者组): ```java container.receive("mygroup", StreamOffset.create("mystream", ReadOffset.lastConsumed()), message -> { System.out.println("Received from Stream: " + message.getValue()); message.ack(); }); ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值