Redis 发布订阅简介
Redis 发布订阅(Pus/Sub)是一种消息通信模式:发送者通过publish发布消息,订阅者通过subscrbe订阅接收消息或通过unsubscrbe取消订阅。包含三个部分组成:发布者、订阅者、Channel。
发布者和订阅者属于客户端,Channel 是 Redis 服务端,发布者将消息发布到频道,订阅这个频道的订阅者则收到消息。需要注意的是,发布的消息并不会持久化,消息发布之后就没有了,要是有新的订阅者订阅消息,只能接收后续发布到该频道的消息。
demo
引入pom
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
redis配置
spring:
redis:
host: 127.0.0.1
port: 6379
password:
database: 10
lettuce:
pool:
max-active: 100 # 连接池最大连接数(使用负值表示没有限制) 默认 8
max-wait: -1 # 连接池最大阻塞等待时间(使用负值表示没有限制) 默认 -1
max-idle: 10 # 连接池中的最大空闲连接 默认 8
min-idle: 4 # 连接池中的最小空闲连接 默认 0
timeout: 3000 # 连接超时时间(毫秒)
创建bean
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(redisConnectionFactory);
template.setKeySerializer(new StringRedisSerializer());
template.setValueSerializer(new GenericJackson2JsonRedisSerializer());
return template;
}
//注入redisMessageListenerContainer
@Bean
public RedisMessageListenerContainer getRedisMessageListenerContainer(RedisConnectionFactory redisConnectionFactory) {
RedisMessageListenerContainer redisMessageListenerContainer = new RedisMessageListenerContainer();
redisMessageListenerContainer.setConnectionFactory(redisConnectionFactory);
MessageListenerAdapter messageListenerAdapter = new MessageListenerAdapter(redisMessageListener);
List<Topic> topics = new ArrayList<>(Arrays.asList(new PatternTopic("testtopic")));
redisMessageListenerContainer.addMessageListener(messageListenerAdapter, topics);
return redisMessageListenerContainer;
}
redis订阅事件监听
@Component
@Slf4j
public class RedisMessageListener implements MessageListener {
@Override
public void onMessage(Message message, byte[] bytes) {
String topic = new String(bytes, Charset.defaultCharset());
log.info("topic:{}", topic);
byte[] body = message.getBody();
String value= new String(body, Charset.defaultCharset());
value= value.substring(1, value.length() - 1);
if (StringUtils.equals(topic, "testtopic")) {
//TODO 业务处理
}
//redis中放json字符串bug问题:REDIS处理后会加一堆转义字符造成json对象正常转换失败
// value= StringEscapeUtils.unescapeJava(value);
// value= data.substring(1, value.length() - 1);
log.info("Redis-监听redis事件:{}", value);
}
}
测试使用
@Autowired
private RedisTemplate<String, Object> redisTemplate;
public void publish(String value) {
redisTemplate.convertAndSend("testtopic", value);
}