【Redis】redis实现消息的发布和订阅
【Redis】redis实现消息的发布和订阅
- 【一】实现过程
- (1)配置redis消息监听器
- 【2】创建消息接收者
- 【3】发布消息
- 【4】使用示例
- 【二】使用场景
- (1)实时消息通知:
- (2)分布式系统解耦:
- (3)实时数据更新:
- 【三】优缺点
- 【1】优点
- (1)高性能:
- (2)使用简单:
- (3)支持多种数据结构:
- (4)适合实时性要求高的场景:
- 【2】缺点
- (1)消息可靠性低:
- (2)消息处理能力有限:
- (3)缺乏复杂的消息处理机制:
- 【四】与其他异步消息中间件对比
- 【1】与 Kafka 对比
- 【2】与 RabbitMQ 对比
【一】实现过程
(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 的发布订阅则更适合对实时性要求较高、对消息可靠性要求相对较低的场景。