文章目录

  • 一、文章序言
  • 二、代码分析



一、文章序言

面试中常会问到为什么使用消息队列

面试官更期望的回答是你项目的真实应用场景,使用MQ解决了什么问题,带来什么好处,如果不用有什么弊端等。

C 消息队列 模式 消息队列demo_面试

消息队列最核心的三个点:解耦、异步、削峰。

参考文章:消息队列作用(解耦、异步、削峰)图详解

消息队列也设计到生产者,消费者原理可以简单的了解一下

参考文章:生产者消费者问题-代码详解(Java多线程)


二、代码分析

rabbitmq如何使用呢

首先创建一个配置类,创建一些队列,并且赋予队列名称

@Configuration
public class RabbitMqConfig {

   @Bean
    public Queue queue1(){
        return new Queue("test1");
    }
   @Bean
    public Queue queue2(){
        return new Queue("test2");
    }

    @Bean
    public Queue queue3(){
       return new Queue("test3");
    }
}

在controller层创建一个amqpTemplate对象,这个对象就可以传递相关信息,它可以将信息发送给相关的队列

进而有监听该队列的消费者就可以消费发送的信息

@RestController
public class SendDemoController {
    @Autowired
    private AmqpTemplate amqpTemplate;
    
    @RequestMapping("/multiSend")
    public String multiSend(){
        StringBuilder times=new StringBuilder();
        for(int i=0;i<10;i++){
            long time=System.nanoTime();
            amqpTemplate.convertAndSend("test1","第"+i+"次发送的时间:"+time);
            times.append(time+"<br>");
        }
        return times.toString();
    }

    @RequestMapping("/multi2MultiSend")
    public String mutil2MutilSend(){
        StringBuilder times=new StringBuilder();
        for(int i=0;i<10;i++){
            long time=System.nanoTime();
            amqpTemplate.convertAndSend("test1","第"+i+"次发送的时间:"+time);
            amqpTemplate.convertAndSend("test2","第"+i+"次发送的时间:"+time);
            times.append(time+"<br>");
        }
        return times.toString();
    }
   //测试发送string类型的消息
    @RequestMapping("/sendTest3")
    public void sendTestString(){
        StringBuilder a = new StringBuilder();
        for (int i=0;i<10;i++){
            String uuid = UUID.randomUUID().toString();
            amqpTemplate.convertAndSend("test3","第"+i+"次发送的时间:"+uuid);
            a.append(uuid+"<br>");
        }
    }

  //测试发送int类型的消息
    @RequestMapping("/sendTest33")
    public void sendTestInteger(){
        StringBuilder a = new StringBuilder();
        for (int i=0;i<10;i++){
            amqpTemplate.convertAndSend("test3",1);
        }
    }

}

消费者1 监听队列test1 消费后输出在控制台

@RabbitListener 可以标注在类上面,需配合 @RabbitHandler 注解一起使用
@RabbitListener 标注在类上面表示当有收到消息的时候,就交给 @RabbitHandler 的方法处理,

@Component
@RabbitListener(queues = "test1")
public class Receiver1 {

    @RabbitHandler
    public void  recevier(String msg){
        System.out.println("Test1 receiver1:"+msg);
    }

}

首先测试我们的第一个访问路径

C 消息队列 模式 消息队列demo_java_02


控制台的输出如下

Test1 receiver1:第0次发送的时间:88337654992000
Test1 receiver1:第1次发送的时间:88337661695100
Test1 receiver1:第2次发送的时间:88337663620800
Test1 receiver1:第3次发送的时间:88337664685500
Test1 receiver1:第4次发送的时间:88337671656700
Test1 receiver1:第5次发送的时间:88337673557700
Test1 receiver1:第6次发送的时间:88337675688700
Test1 receiver1:第7次发送的时间:88337676873100
Test1 receiver1:第8次发送的时间:88337679355700
Test1 receiver1:第9次发送的时间:88337681630300

消费者2 监听

@Component
@RabbitListener(queues = "test2")
public class Receiver2 {

    @RabbitHandler
    public void receiver(String msg){
        System.out.println("Test2 receiver2:"+msg);
    }
}

测试访问第二个路径,同时给队列test1和test2发送信息

C 消息队列 模式 消息队列demo_面试_03


控制台消费者1和消费者2输出 代表消费者成功消费

C 消息队列 模式 消息队列demo_C 消息队列 模式_04

如果在一个监听队列中给不同的方法重载,如下即可以消费string类型的,也可以消费Integer 类型的

此时队列进行监听 不同类型的消息可以自己识别 —>进而不同的输出语句

具体使用哪个方法处理,根据 MessageConverter 转换后的参数类型

@Component
@RabbitListener(queues="test3")
public class Receiver3 {

    @RabbitHandler
    public void receiver3(String msg){
        System.out.println("消费者3接受的消息是"+msg);
    }

    @RabbitHandler
    public void receiver3(Integer msg){
        System.out.println(msg);
    }
}

测试访问第三个路径,给队列test3发送信息 观察到controller层该信息给String类型

C 消息队列 模式 消息队列demo_经验分享_05


测试访问第四个路径,给队列test3发送信息 观察到controller层该信息给Integer类型

C 消息队列 模式 消息队列demo_C 消息队列 模式_06


控制台的输出如下 可以看到依次消费出string类型 和 integer类型的相关信息

C 消息队列 模式 消息队列demo_队列_07


项目配置文件:如上代码建议初学者自己实践一遍

server.port=8099
spring.rabbitmq.host=127.0.0.1
spring.rabbitmq.port=5672
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest

相信你一定看懂了整个项目的基本运行流程,本篇仅仅是一个基础应用实践案例,其实rabbitmq还有很多细节和基础值得我们深度学习 ,下期见!


The best investment is to invest in yourself.