使用Redis搭建基于发布、订阅(pub/sub)模式的消息队列

420 阅读2分钟

前言

工作上需要用到消息队列,但是只是简单应用,并没有高负载的需求。基于实际需要,我使用reids搭建了一个基于发布、订阅模式的消息队列。

对比RabbitMQ等重量级消息中间件,redis搭建的中间件还是有其优势的。如果你需要一个简单、快速、轻量级的消息队列,并且对可靠性和消息持久化要求不高,那么Redis是一个不错的选择。如果你需要更丰富的消息队列功能、可靠性投递、消息持久化和高可扩展性,以及更复杂的消息模型支持,那么RabbitMQ、Kafka等是更合适的选择。

环境要求

springboot工程项目

安装并运行了reids服务

编码

  1. pom文件添加redis的依赖
   <dependency>
        <groupId>redis.clients</groupId>
        <artifactId>jedis</artifactId>
        <version>3.1.0</version>
    </dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
    <exclusions>
        <exclusion>
            <groupId>io.lettuce</groupId>
            <artifactId>lettuce-core</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
    <groupId>org.springframework.data</groupId>
    <artifactId>spring-data-redis</artifactId>
    <scope>compile</scope>
</dependency>
  1. yml文件添加redis配置
      redis:
        # 地址
        host: 127.0.0.1
        # 端口,默认为6379
        port: 6379
        # 连接超时时间
        timeout: 120s
        jedis:
          pool:
            # 连接池中的最小空闲连接
            min-idle: 0
            # 连接池中的最大空闲连接
            max-idle: 8
            # 连接池的最大数据库连接数
            max-active: 8
            # #连接池最大阻塞等待时间(使用负值表示没有限制)
            max-wait: -1m
    
  1. 添加Redis配置类

image-20230706094047694.png


@Configuration
public class RedisConfig {

    @Bean
    MessageListenerAdapter messageListener() {
        return new MessageListenerAdapter(new PushProcess1());
    }

    @Bean
    MessageListenerAdapter messageListener2() {
        return new MessageListenerAdapter(new PushProcess2());
    }


    @Bean
    RedisMessageListenerContainer redisContainer(RedisConnectionFactory factory) {
        final RedisMessageListenerContainer container = new RedisMessageListenerContainer();
        container.setConnectionFactory(factory);
        //messageListener方法监听通道1
        container.addMessageListener(messageListener(), new ChannelTopic("channel1"));
        //messageListener2监听通道2
        container.addMessageListener(messageListener2(),new ChannelTopic("channel2"));
        return container;
    }

    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
        template.setConnectionFactory(factory);
        // key采用String的序列化方式
        template.setKeySerializer(new StringRedisSerializer());
        // hash的key也采用String的序列化方式
        template.setHashKeySerializer(new StringRedisSerializer());
        // value序列化方式采用jackson
        template.setValueSerializer(new GenericJackson2JsonRedisSerializer());
        // hash的value序列化方式采用jackson
        template.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());
        template.afterPropertiesSet();
        return template;
    }


}
  1. 消息推送进消息队列

    注入RedisTemplate

    @Resource
    private RedisTemplate<String,Object> redisTemplate;
    

    在业务代码中使用redisTemplate的convertAndSend方法将数据推送进队列

    //将数据推送进不同通道,这里我把pushData对象推送进去,你们可以选择你们要推送的数据
    redisTemplate.convertAndSend("channel1",pushData);
    redisTemplate.convertAndSend("channel2",pushData);
    
  2. 实现对redis消息队列的监听

创建监听类实现消息监听方法。

  1. PushProcess1(消费者1监听通道1)
public class PushProcess1 implements MessageListener {
    @Override
    public void onMessage(Message message, byte[] bytes) {
​
        GenericJackson2JsonRedisSerializer serializer = new GenericJackson2JsonRedisSerializer();
        //这里我把推送的消息给序列化成我的目标类,你们也可以根据实际需要选择是否序列化。
        PushData pushData = serializer.deserialize(message.getBody(), PushData.class);
        //拿着监听到的消息编写业务代码
       
    }
}
  1. PushProcess2 (消费者2监听通道2)

    public class PushProcess2 implements MessageListener2 {
        @Override
        public void onMessage(Message message, byte[] bytes) {
    ​
            GenericJackson2JsonRedisSerializer serializer = new GenericJackson2JsonRedisSerializer();
            //这里我把推送的消息给序列化成我的目标类,你们也可以根据实际需要选择是否序列化。
            PushData pushData = serializer.deserialize(message.getBody(), PushData.class);
            //拿着监听到的消息编写业务代码
           
        }
    }
    

夹带私货^_^

发一张公司楼下拍的晚霞~~

501688612920_.pic_hd.jpg