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

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

【一】实现过程

(1)配置redis消息监听器

创建配置类,配置 Redis 消息监听器容器:

java 复制代码
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】创建消息接收者

java 复制代码
public class Receiver {

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

【3】发布消息

java 复制代码
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】使用示例

java 复制代码
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 的发布订阅则更适合对实时性要求较高、对消息可靠性要求相对较低的场景。

相关推荐
RunsenLIu4 分钟前
基于Django和Bootstrap开发的美食推荐系统
django·bootstrap·美食
不剪发的Tony老师7 分钟前
Redis 8.0正式发布,再次开源为哪般?
数据库·redis
极小狐27 分钟前
如何使用极狐GitLab 软件包仓库功能托管 ruby?
开发语言·数据库·人工智能·git·机器学习·gitlab·ruby
鱼儿也有烦恼2 小时前
Redis最新入门教程
数据库·redis·缓存
牛马程序小猿猴2 小时前
17.thinkphp的分页功能
前端·数据库
我科绝伦(Huanhuan Zhou)2 小时前
Oracle免费认证来袭
数据库·oracle
@CLoudbays_Martin113 小时前
CF后台如何设置TCP 和 UDP 端口?
大数据·运维·服务器·网络·数据库
步、步、为营3 小时前
.NET中使用HTTPS全解析
数据库·https·.net
漠月瑾-西安3 小时前
信创背景下的分布式数据库备份难题及解决之道
数据库·分布式·信创·数据备份
风象南4 小时前
Redis中6种缓存更新策略
redis·后端