Redis 发布订阅模式介绍,Java 使用 Redis 实现广播

N 人看过

介绍:

Redis发布订阅(Publish / Subscribe)模式是Redis提供的一种消息通信方式,它基于消息中间件的设计思想,实现了消息的生产者和消费者的解耦。Redis 发布订阅模式的工作原理类似于消息队列,不同之处在于 Redis 发布订阅模式是一种多对多的消息通信方式,一个消息可以被多个消费者接收。

在Redis发布订阅模式中,消息的生产者将消息发布到指定的频道,而消费者则通过订阅对应的频道来接收消息。当消息生产者发布了一条消息到某个频道时,所有订阅了该频道的消费者都可以接收到这条消息。

Redis发布订阅模式包括两个核心的命令:PUBLISH 和 SUBSCRIBE。PUBLISH 命令用于向指定的频道发布一条消息,而 SUBSCRIBE 命令则用于订阅指定的频道。

原理:

  1. Redis 服务器维护了一个”订阅者列表”,该列表记录了所有订阅了至少一个频道的客户端。
  2. 当一个客户端订阅一个或多个频道时,Redis服务器会将该客户端添加到对应频道的”订阅者列表”中。
  3. 当一个客户端发布消息到某个频道时,Redis服务器会将该消息发送给该频道的所有订阅者。
  4. 当一个客户端取消订阅一个频道时,Redis服务器会将该客户端从该频道的”订阅者列表”中移除。

在 Redis 发布订阅模式中,Redis 服务器起到了一个消息中心的作用,它负责维护订阅者列表和消息发布、转发的机制。同时,Redis提供了一系列API,使得客户端可以方便地进行订阅和发布操作。

在 SpringBoot 中使用

创建监听器

@Component
public class RedisMessageListener implements MessageListener {

    @Override
    public void onMessage(Message message, byte[] pattern) {
        String s = new String(message.getBody());
        System.out.println("收到消息:" + s);
    }

}

配置监听器

@Configuration
public class RedisMessageConfig {

    /**
     * 消息监听器适配器
     * @return org.springframework.data.redis.listener.adapter.MessageListenerAdapter
     */
    @Bean
    public MessageListenerAdapter listenerAdapter(RedisMessageListener receiver) {
        //这个地方是给 messageListenerAdapter 传入一个消息接受的处理器,利用反射的方法调用“onMessage”
        return new MessageListenerAdapter(receiver, "onMessage");
    }
    
    /**
     * redis消息监听器容器
     * @return org.springframework.data.redis.listener.RedisMessageListenerContainer
     */
    @Bean
    public RedisMessageListenerContainer redisMessageListenerContainer(RedisConnectionFactory connectionFactory, MessageListenerAdapter listenerAdapter) {
        RedisMessageListenerContainer container = new RedisMessageListenerContainer();
        container.setConnectionFactory(connectionFactory);
        // 订阅了一个叫 my-channel 的频道
        container.addMessageListener(listenerAdapter, new PatternTopic("my-channel"));
        // 这个container 可以添加多个 messageListener
        return container;
    }
  
}

测试方法

    @GetMapping(value = "/testRedis")
    public void testRedis() {
        redisTemplate.convertAndSend("my-channel", JsonUtil.toJsonStr(new Student(1L, "张三")));
    }

效果

在这里插入图片描述