redis监听
1.依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<version>3.0.5</version>
</dependency>
2.配置类
- 消费方法名为
receiveMessage
@Configuration
public class RedisMessageConfig {
/**
* 这个地方 是给messageListenerAdapter 传入一个消息接受的处理器,利用反射的方法调用“receiveMessage”
* 也有好几个重载方法,这边默认调用处理器的方法 叫handleMessage 可以自己到源码里面看
*
* @param receiver
* @return
*/
@Bean
public MessageListenerAdapter listenerAdapter(MessageReceiver receiver) {
return new MessageListenerAdapter(receiver, "receiveMessage");
}
@Bean
public RedisMessageListenerContainer container2(RedisConnectionFactory factory,
MessageListenerAdapter adapter) {
RedisMessageListenerContainer container = new RedisMessageListenerContainer();
container.setConnectionFactory(factory);
// 一次订阅多个匹配的频道
container.addMessageListener(adapter, new PatternTopic(MessageTopic.TOPIC));
return container;
}
}
@Configuration
public class RedisTemplateConfig {
@Primary
@Bean("customStringRedisTemplate")
public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory factory) {
StringRedisTemplate template = new StringRedisTemplate();
template.setConnectionFactory(factory);
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
// key采用String的序列化方式
template.setKeySerializer(stringRedisSerializer);
// hash的key也采用String的序列化方式
template.setHashKeySerializer(stringRedisSerializer);
// value序列化方式采用jackson
template.setValueSerializer(stringRedisSerializer);
// hash的value序列化方式采用jackson
template.setHashValueSerializer(stringRedisSerializer);
template.afterPropertiesSet();
return template;
}
}
2.发送
redisTemplate.convertAndSend(MessageTopic.TOPIC, JSON.toJSONString(msg));
3.消费
@Component
public class MessageReceiver {
@Autowired
private TerminalChannel terminalChannel;
/**
* 接收redis订阅消息
*
* @param message
* @param channel
*/
public void receiveMessage(String message, String channel) {
log.info("---频道---: {}", channel);
log.info("---消息内容---: {}", message);
message = message.replace("\"{", "{").replace("}\"", "}").replace("\\", "");
TerminalMessage terminalMessage = JSON.parseObject(message, TerminalMessage.class);
terminalChannel.sendText(terminalMessage.getShopId(), terminalMessage.getMessage());
}
}
4.比较MQ
Redis 的 convertAndSend(Pub/Sub 模式)与传统消息队列(如 RabbitMQ、Kafka)的核心差异点如下:
一、通信模式差异
Redis Pub/Sub
纯广播模式(Fire-and-Forget)
无消息存储:订阅者离线时消息直接丢失
无消费者组概念:所有订阅同一 Channel 的客户端均会收到相同消息
消息队列 (MQ)
队列存储机制:消息持久化到磁盘(如 Kafka)或内存(如 RabbitMQ)
支持点对点(Queue)和发布订阅(Topic)模式
消费者组:同一消费者组内多个实例竞争消费(负载均衡)
二、可靠性保障
特性
Redis:
瞬时存储,服务重启即丢失
消息重试 无ACK机制
事务消息 不支持
MQ:
支持持久化(根据配置)
支持重试、死信队列
事务消息 部分支持(如 RocketMQ)
三、典型应用场景
Redis Pub/Sub 适用场景 ✔️ 实时通知(如聊天室、状态广播) ✔️ 轻量级事件触发(无需保障可靠性的场景)
MQ 适用场景 ✔️ 订单处理、支付等业务关键型消息 ✔️ 削峰填谷、异步解耦 ✔️ 需要 Exactly-Once 语义的场景
四、性能对比
Redis Pub/Sub 低延迟(μs级),适合高频小消息,但吞吐量受单线程模型限制
MQ 吞吐量更高(如 Kafka 可达百万级 TPS),但引入 Broker 会带来微秒~毫秒级延迟

浙公网安备 33010602011771号