【Redis】redis实现消息的发布和订阅

发布于:2025-03-25 ⋅ 阅读:(24) ⋅ 点赞:(0)

【一】实现过程

(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;

@Configuration
public class RedisPubSubConfig {

    @Bean
    RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory,
                                            MessageListenerAdapter listenerAdapter) {
        RedisMessageListenerContainer container = new RedisMessageListenerContainer();
        container.setConnectionFactory(connectionFactory);
        container.addMessageListener(listenerAdapter, new ChannelTopic("myChannel"));
        return container;
    }

    @Bean
    MessageListenerAdapter listenerAdapter(Receiver receiver) {
        return new MessageListenerAdapter(receiver, "receiveMessage");
    }

    @Bean
    Receiver receiver() {
        return new Receiver();
    }
}

【2】创建消息接收者

public class Receiver {

    public void receiveMessage(String message) {
        System.out.println("Received <" + message + ">");
    }
}

【3】发布消息

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

@Service
public class RedisPublisher {

    @Autowired
    private StringRedisTemplate redisTemplate;

    public void publish(String message) {
        redisTemplate.convertAndSend("myChannel", message);
    }
}

【4】使用示例

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class RedisPubSubApplication implements CommandLineRunner {

    @Autowired
    private RedisPublisher redisPublisher;

    public static void main(String[] args) {
        SpringApplication.run(RedisPubSubApplication.class, args);
    }

    @Override
    public void run(String... args) throws Exception {
        redisPublisher.publish("Hello, Redis Pub/Sub!");
    }
}

【二】使用场景

(1)实时消息通知:

例如在社交应用中,当有新的好友请求、评论或点赞时,通过 Redis 发布订阅机制将消息推送给相关用户。

(2)分布式系统解耦:

在微服务架构中,不同的服务之间可以通过 Redis 发布订阅进行通信,实现服务间的解耦。比如订单服务在创建订单后发布一个订单创建事件,库存服务订阅该事件来处理库存扣减。

(3)实时数据更新:

对于一些需要实时更新的数据,如股票价格、体育赛事比分等,服务端可以将最新数据发布到 Redis 频道,客户端订阅该频道获取实时数据。

【三】优缺点

【1】优点

(1)高性能:

Redis 基于内存操作,读写速度极快,在处理高并发的消息场景时,能快速完成消息的发布和订阅操作,响应时间短,可满足低延迟的业务需求。

(2)使用简单:

Spring Boot 与 Redis 整合较为简便,代码量少,配置相对简单。只需要添加相应依赖,配置 Redis 连接信息,就可以快速实现消息队列功能,降低了开发成本和学习成本。

(3)支持多种数据结构:

Redis 除了支持基本的发布订阅模式外,还提供了列表(List)、有序集合(Sorted Set)等数据结构来实现消息队列。例如,可以使用列表的 LPUSH 和 RPOP 命令实现简单的先进先出(FIFO)队列。

(4)适合实时性要求高的场景:

由于 Redis 的高性能和低延迟特性,非常适合实时性要求较高的场景,如实时消息通知、实时数据更新等。

【2】缺点

(1)消息可靠性低:

Redis 的发布订阅模式是无状态的,不支持消息持久化。如果订阅者在消息发布时未连接,就会错过该消息。而且在 Redis 出现故障或重启时,未处理的消息会丢失。

(2)消息处理能力有限:

虽然 Redis 性能高,但它主要基于内存存储,当消息量过大时,可能会导致内存资源紧张,甚至出现内存溢出的问题。同时,Redis 不适合处理大规模的长时间运行的任务队列。

(3)缺乏复杂的消息处理机制:

Redis 的消息队列功能相对简单,缺乏像 RabbitMQ 那样的复杂消息处理机制,如消息确认、重试机制、死信队列等,在处理复杂业务逻辑时不够灵活。

【四】与其他异步消息中间件对比

【1】与 Kafka 对比

(1)性能:Kafka 具有高吞吐量和低延迟的特性,适合处理大规模的实时数据流,如日志收集、实时数据分析等场景。而 Redis 的发布订阅在处理大规模消息时性能相对较弱
(2)消息持久化:Kafka 支持消息持久化,即使消费者暂时不可用,消息也不会丢失。Redis 的发布订阅是无状态的,不支持消息持久化,如果订阅者在消息发布时未连接,就会错过该消息
(3)使用场景:Kafka 更适合对消息顺序和可靠性有较高要求的大数据场景。Redis 的发布订阅则更适合简单的实时消息通知场景。

【2】与 RabbitMQ 对比

(1)消息模型:RabbitMQ 支持多种消息模型,如点对点、发布订阅、路由等,功能较为丰富。Redis 的发布订阅主要是简单的发布订阅模式。
(2)可靠性:RabbitMQ 提供了强大的消息确认机制和重试机制,能保证消息的可靠传递。Redis 的发布订阅没有这些机制,消息传递的可靠性较低。
(3)使用场景:RabbitMQ 适合对消息可靠性和业务逻辑复杂度要求较高的企业级应用。Redis 的发布订阅则更适合对实时性要求较高、对消息可靠性要求相对较低的场景。