SpringBoot+Redis发布订阅模式消息队列的实现

SpringBoot+Redis发布订阅模式消息队列的实现

1、前言

一般来说,消息队列有两种场景,一种是发布/订阅模式,一种是生产者/消费者模式。功能强大的Redis不仅能做缓存支持,在消息队列方面同样支持,而且两种模式都支持。

定义: 生产者消费者模式:生产者生产消息放到队列里,多个消费者同时监听队列,谁先抢到消息谁就会从队列中取走消息;即对于每个消息只能被最多一个消费者拥有。

发布者订阅者模式:发布者生产消息放到队列里,多个监听队列的消费者都会收到同一份消息;即正常情况下每个消费者收到的消息应该都是一样的。

关于Redis其他特点以及功能在这里不再啰嗦,有兴趣的可以自行去研究,下面直接进入此次正题

第一步:创建一个SpringBoot工程,引入如下jar包


        
            org.springframework.boot
            spring-boot-starter-test
            test
        

        
        
            org.springframework.boot
            spring-boot-starter-web
        

        
        
            org.springframework.boot
            spring-boot-starter-data-redis
        

        
            org.redisson
            redisson
            3.7.0
        

        
            org.springframework.boot
            spring-boot-starter-jta-atomikos
        

        
            org.mybatis.spring.boot
            mybatis-spring-boot-starter
            1.1.1
        
        
            com.alibaba
            druid
            1.1.10
        

        
            org.springframework.boot
            spring-boot-starter-data-jpa
        

        
            org.springframework.boot
            spring-boot-starter-jdbc
        
        
            mysql
            mysql-connector-java
            5.1.40
        
        
            com.oracle
            ojdbc6
            11.2.0.3
        

        
            org.springframework.boot
            spring-boot-configuration-processor
            true
        
        
        
            redis.clients
            jedis
            2.9.0
        

        
        
            com.alibaba
            fastjson
            1.2.46
        
    

2、修改application.yml配置文件

server:
  port: 8080
spring:
  redis:
    host: xxx.xx.xxx.xxx(自己redis服务ip)
    port: 6379
  primary:
    datasource:
      url: jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8
      username: xxx(数据库用户名)
      password: xxxxxx(密码)
      driver-class-name: com.mysql.jdbc.Driver
    #oracle
    # url: jdbc:oracle:thin:@localhost:1521:orcl
    # username: xxxx
    # password: xxxxxx
    # driver-class-name: oracle.jdbc.OracleDriver
    # max-idle: 10
    # max-wait: 10000
    # min-idle: 5
    # initial-size: 5
  secondary:
    datasource:
      url: jdbc:mysql://localhost:3306/xxl-kkk?useUnicode=true&characterEncoding=utf-8
      username: xxxx
      password: xxxxx
      driver-class-name: com.mysql.jdbc.Driver

因为此处为配的是主从库,所以有两个数据源,如果不需要可以直接去掉一个。

3、新建一个config,进行Redis相关bean的注入

@SpringBootConfiguration
public class RedisConfig {
@Bean
    public StringRedisTemplate getRedisTemplate(RedisConnectionFactory redisConnectionFactory){
        return new StringRedisTemplate(redisConnectionFactory);
    }
    @Bean(name="redisTemplate")
    public RedisTemplate template(RedisConnectionFactory connectionFactory){
        RedisTemplate template=new RedisTemplate<>();
        template.setKeySerializer(new StringRedisSerializer());
        template.setValueSerializer(new JdkSerializationRedisSerializer());

        template.setConnectionFactory(connectionFactory);
        return template;
    }
}

两个Redis实例选一个就好,这里我用的是 RedisTemplate

4、创建一个消息实体

public class Mqmessage implements Serializable {
    private String id;
    private String content;

    public Mqmessage(String id, String content) {
        this.id = id;
        this.content = content;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }
    @Override
    public String toString() {
        return "Mqmessage{" +
                "id='" + id + '\'' +
                ", content='" + content + '\'' +
                '}';
    }
}

5、创建发布者

这里,我将发布者包装成一个Service,方便后面的测试,当然也可以直接一个main方法也是可以的,我这里图方便,就包装一个service

import java.util.logging.Logger;
@Service
public class RedisProducerServiceImpl implements RedisProducerService {
    private static Logger logger= Logger.getLogger(RedisProducerServiceImpl.class.getName());
    @Autowired
    RedisTemplate redisTemplate;
    /**
     * 发布消息
     * @param chanal
     * @param mqmessage
     */
    @Override
    public void sendMessage(String chanal, String mqmessage) {

         redisTemplate.convertAndSend(chanal,mqmessage);
    }
}

发布消息使用**redisTemplate.convertAndSend(chanal,mqmessage);**此处省略了接口层RedisProducerService 的代码,比较简单,就是一个方法,就不贴出来了。

6、创建监听,当发布者发布消息,就进行监听并消费

在开始创建的config中加入如下bean,

@Bean
    public RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory,
                                                   MessageListenerAdapter adapter,MessageListenerAdapter adapter1){
        RedisMessageListenerContainer container=new RedisMessageListenerContainer();
        container.setConnectionFactory(connectionFactory);
        container.addMessageListener(adapter,new PatternTopic("wang"));
        container.addMessageListener(adapter1,new PatternTopic("cheng"));
        return container;
    }
    @Bean
    public MessageListenerAdapter adapter(RedisLinterMeaage meaage){
        MessageListenerAdapter messageListenerAdapter=new MessageListenerAdapter(meaage,"redisLinterMeaage");
       // messageListenerAdapter.setSerializer(new JdkSerializationRedisSerializer());
        return messageListenerAdapter;
    }
    @Bean
    public MessageListenerAdapter adapter1(RedisLinterMeaage meaage){
        MessageListenerAdapter messageListenerAdapter=new MessageListenerAdapter(meaage,"redisLinterMeaage1");
       // messageListenerAdapter.setSerializer(new JdkSerializationRedisSerializer());
        return messageListenerAdapter;
    }

7、创建订阅者,并设置两个topic

public class RedisLinterMeaage   {
    private static Logger logger=Logger.getLogger(RedisLinterMeaage.class.getName());
    
   public void redisLinterMeaage(String jsonMsg){
       logger.info("开始消费【wang】的消息");
       try{
             Mqmessage mqmessage=JSONObject.parseObject(jsonMsg,Mqmessage.class);
             System.out.println(mqmessage.getContent()+",,"+mqmessage.getId());
           logger.info("消费完毕");
       }catch (Exception e){
           logger.info("消费失败");
       }
   }
    public void redisLinterMeaage1(String jsonMsg){
        logger.info("开始消费【cheng】的消息");
        try{
            Mqmessage mqmessage=JSONObject.parseObject(jsonMsg,Mqmessage.class);
            System.out.println(mqmessage.getContent()+",,"+mqmessage.getId());
            logger.info("消费完毕");
        }catch (Exception e){
            logger.info("消费失败");
        }
    }
}

在第6步中指定了两个Topic,并写入监听,所以我在订阅者中也加了两个方法,分别对应一个Topic。

8、新建一个Controller,进行消息发布

@RestController
public class HelloWorldController {
    @Autowired
    private RedisProducerService redisProducerService;
    @RequestMapping("/getAllList")
    public Object getAllList(){
        Mqmessage mqmessage=new Mqmessage("1000","测试的");
        Mqmessage mqmessage1=new Mqmessage("10001","成的消息");
        try{
            redisProducerService.sendMessage("wang", JSON.toJSONString(mqmessage));
            redisProducerService.sendMessage("cheng",JSON.toJSONString(mqmessage1));
            return “发布消息成功”;
        }catch (Exception e){
            throw new RuntimeException(e.getMessage());
        }
    }
}

至此,Redis的消息队列发布订阅模式代码完毕,启动服务,访问localhost:8080/getAllList,就可看到控制台输出的信息,如下图
SpringBoot+Redis发布订阅模式消息队列的实现_第1张图片

如有错误还请指正,毕竟还是只小菜鸟,需要努力飞翔。

你可能感兴趣的:(Redis,SpringBoot)