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 会带来微秒~毫秒级延迟

posted @ 2025-04-14 17:31  lwx_R  阅读(26)  评论(0)    收藏  举报