环境: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;@Autowiredpublic 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 {@Beanpublic 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;@Autowiredpublic RedisConfig(RedisSubscriber redisSubscriber) {this.redisSubscriber = redisSubscriber;}@BeanRedisMessageListenerContainer container(RedisConnectionFactory connectionFactory) {RedisMessageListenerContainer container = new RedisMessageListenerContainer();//设置 Redis 连接工厂container.setConnectionFactory(connectionFactory);//添加消息监听器,监听 Constant.REDIS_CACHE 频道container.addMessageListener(listenerAdapter(), new PatternTopic(Constant.REDIS_CACHE));return container;}@BeanMessageListenerAdapter listenerAdapter() {return new MessageListenerAdapter(redisSubscriber, "onMessage");}
}
- redisTemplate是用来解决中文乱码问题的
- RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory):定义一个 RedisMessageListenerContainer,用于监听 Redis 消息。
- MessageListenerAdapter listenerAdapter():定义一个 MessageListenerAdapter,将 redisSubscriber 的 onMessage 方法适配为消息处理方法。
使用建议
对于实时性要求高、系统之间解耦要求高的场景,且可以容忍一定的消息丢失,Redis 发布订阅是一个很好的选择。
对于需要消息可靠性、持久化、复杂的消息路由和大规模消息处理能力的场景,建议使用专业的消息队列系统,如 Kafka、RabbitMQ 等。