环境:windows10、jdk17、springboot3
Redis有两种发布订阅模式:频道发布订阅、模式发布订阅
频道就是消息发到指定频道,订阅此频道的客户端都能收到消息;模式发布订阅就是匹配以xxx为开头的多个频道;我们这里用的是频道发布订阅,模式发布订阅不做讨论
1.具体实现
redis依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<version>3.0.2</version>
</dependency>
配置
spring:
data:
redis:
# 连接地址
host: 127.0.0.1
# 端口
port: 6379
# 数据库
database: 0
# 用户名,如果有
# username:
# 密码,如果有
password:
# 连接超时
connect-timeout: 5s
# 读超时
timeout: 5s
1.1 redis 消息发布
创建redis消息发布者
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
/**
* @author luobei
* redis发布者
*/
@Service
public class RedisPublisher {
private final StringRedisTemplate redisTemplate;
@Autowired
public RedisPublisher(StringRedisTemplate redisTemplate) {
this.redisTemplate = redisTemplate;
}
public void publish(String channel, String message) {
redisTemplate.convertAndSend(channel, message);
}
}
业务中发布消息
@Resource
RedisPublisher redisPublisher;
@PostConstruct //依赖注入后自动调用方法
public void cache() {
redisPublisher.publish(Constant.REDIS_CACHE, "refresh");
}
1.2 redis 消息订阅
创建redis消息订阅者
import org.springframework.stereotype.Service;
/**
* @author luobei
* redis订阅者
*/
@Service
public class RedisSubscriber {
public void onMessage(String message) {
// 处理收到的消息
System.out.println("Received message: " + message);
}
}
配置配置文件
/**
* @author luobei
* redis配置类
*/
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<String, String> redisTemplate(LettuceConnectionFactory redisConnectionFactory) {
RedisTemplate<String, String> redisTemplate = new RedisTemplate<>();
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(new StringRedisSerializer());
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
redisTemplate.setHashValueSerializer(new StringRedisSerializer());
redisTemplate.setConnectionFactory(redisConnectionFactory);
return redisTemplate;
}
private final RedisSubscriber redisSubscriber;
@Autowired
public RedisConfig(RedisSubscriber redisSubscriber) {
this.redisSubscriber = redisSubscriber;
}
@Bean
RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory) {
RedisMessageListenerContainer container = new RedisMessageListenerContainer();
//设置 Redis 连接工厂
container.setConnectionFactory(connectionFactory);
//添加消息监听器,监听 Constant.REDIS_CACHE 频道
container.addMessageListener(listenerAdapter(), new PatternTopic(Constant.REDIS_CACHE));
return container;
}
@Bean
MessageListenerAdapter listenerAdapter() {
return new MessageListenerAdapter(redisSubscriber, "onMessage");
}
}
- redisTemplate是用来解决中文乱码问题的
- RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory):定义一个 RedisMessageListenerContainer,用于监听 Redis 消息。
- MessageListenerAdapter listenerAdapter():定义一个 MessageListenerAdapter,将 redisSubscriber 的 onMessage 方法适配为消息处理方法。
使用建议
对于实时性要求高、系统之间解耦要求高的场景,且可以容忍一定的消息丢失,Redis 发布订阅是一个很好的选择。
对于需要消息可靠性、持久化、复杂的消息路由和大规模消息处理能力的场景,建议使用专业的消息队列系统,如 Kafka、RabbitMQ 等。