Springboot整合RabbitMQ

目录

消息队列三大功能:

MQ的四大核心概念:

交换机的分类:

主题交换机绑定键和路由键之间的规则:

整合到项目中需要的几个部分:

代码部分:

延迟队列:

代码部分:

手动应答:

代码:


  • 消息队列三大功能:

  1. 流量消峰:超过极限之后,后续的访问人员需要等待;可以避免宕机,但是需要更多的时间;
  2. 应用解耦:可以使系统之间解耦,一个系统调用别的系统的时候不会因为被调用的系统故障而一起发生故障;这样在调用的时候,会通过队列去访问别的系统,那么需要调用的系统只需要将这样的一个请求交给了队列则就完成了他的操作,后续的出错不会影响它。
  3. 异步处理:可以使得模块之间调用的时候,调用的模块不再需要等待被调用的模块执行结束,而是被调用的模块执行结束以后由队列去通知调用的模块;
  • MQ的四大核心概念:

  1. 生产者;
  2. 交换机:交换机和队列是绑定的关系,一个交换机可以绑定多个队列
  3. 队列:交换机和队列是MQ的重要组成部分;队列和消费者一一对应;
  4. 消费者;
  • 交换机的分类:

  1. Direct Exchange(直连型交换机):一个队列绑定到一个交换机上面的时候会赋予一个路由键routing key,消息传递的时候会根据其所携带的路由键来传递给对应的队列;
  2. Fanout Exchange(扇形交换机):该交换机没有路由键的功能,即使赋予了路由键也是无效的,此类交换机接受消息后会直接转发到绑定在它上面的所有队列;
  3. Topic Exchange(主题交换机):此类交换机类似直连型交换机,但是其路由键和绑定键之间是有规则的,规则如下;
  4. Header Exchange(头交换机)
  5. Default Exchange(默认交换机)
  6. Dead Letter Exchange(死信交换机)
  • 主题交换机绑定键和路由键之间的规则:

  • *:表示一个字母(必须出现的);
  • #:表示任意数量的字母;
  • 举例说明:队列Q1的绑定键为:*.LL.*,队列Q2的绑定键为:LL.#;
  • 那么如果一条消息携带的路由键是:A.LL.B,那么将会被队列Q1收到;
  • 如果一条消息携带的路由键是:LL.A.B,那么将会被队列Q2收到;
  • 当一个队列的绑定键为#时:那么这个队列会忽略消息所携带的路由键;
  • 当一个队列的绑定键不含有*和#时:那么此时的主题交换机就类似于直连型交换机;

  • 整合到项目中需要的几个部分:

  1. 配置类(交换机,队列,绑定);
  2. 发送消息的业务;
  3. 接收消息并消费;
  • 代码部分:

  1. Direct Exchange(直连型交换机):Springboot整合RabbitMQ_第1张图片Springboot整合RabbitMQ_第2张图片Springboot整合RabbitMQ_第3张图片
  2. Fanout Exchange(扇形交换机):Springboot整合RabbitMQ_第4张图片Springboot整合RabbitMQ_第5张图片Springboot整合RabbitMQ_第6张图片Springboot整合RabbitMQ_第7张图片
  3. Topic Exchange(主题交换机):Springboot整合RabbitMQ_第8张图片

Springboot整合RabbitMQ_第9张图片

Springboot整合RabbitMQ_第10张图片

Springboot整合RabbitMQ_第11张图片

Springboot整合RabbitMQ_第12张图片

  • 延迟队列:

  • 代码部分:

    /**
     * TTL队列
     */
    @Configuration
    public class TtlQueueConfig {
        //普通交换机
        //死信交换机
        //普通队列
        //死信队列
        public static final String NORMAL_EXCHANGE = "X";
        public static final String DEAD_EXCHANGE = "Y";
    
        public static final String QUEUE_A = "QA";
        public static final String QUEUE_B = "QB";
        public static final String DEAD_QUEUE_D = "QD";
    
        @Bean
        public DirectExchange getNormalExchange() {
            return new DirectExchange(NORMAL_EXCHANGE);
        }
    
        @Bean
        public DirectExchange getDeadExchange() {
            return new DirectExchange(DEAD_EXCHANGE);
        }
    
        @Bean
        public Queue getQueueA() {
            Map arguments = new HashMap<>(3);
            //设置死信交换机
            //设置路由键
            //设置过期时间
            arguments.put("x-dead-letter-exchange", DEAD_EXCHANGE);
            arguments.put("x-dead-letter-routing-key", "YD");
            arguments.put("x-message-ttl", 10000);
            return QueueBuilder.durable(QUEUE_A).withArguments(arguments).build();
        }
    
        @Bean
        public Queue getQueueB() {
            Map arguments = new HashMap<>(3);
            //设置死信交换机
            //设置路由键
            //设置过期时间 40s
            arguments.put("x-dead-letter-exchange", DEAD_EXCHANGE);
            arguments.put("x-dead-letter-routing-key", "YD");
            arguments.put("x-message-ttl", 40000);
            return QueueBuilder.durable(QUEUE_B).withArguments(arguments).build();
        }
    
        @Bean
        public Queue getDeadQueueD() {
            return QueueBuilder.durable(DEAD_QUEUE_D).build();
        }
    
        @Bean
        public Binding queueABindingNormalExchange() {
            return BindingBuilder.bind(getQueueA()).to(getNormalExchange()).with("XA");
        }
    
        @Bean
        public Binding queueBBindingNormalExchange() {
            return BindingBuilder.bind(getQueueB()).to(getNormalExchange()).with("XB");
        }
    
        @Bean
        public Binding queueDBindingDeadExchange() {
            return BindingBuilder.bind(getDeadQueueD()).to(getDeadExchange()).with("YD");
        }
    }
    
      @GetMapping("/SendTtlMsg")
        public String sendTtlMsg(){
            User user = new User();
            user.setUserName("rita");
            user.setSex("female");
            user.setPhoneNumber(112);
            rabbitTemplate.convertAndSend( NORMAL_EXCHANGE,"XA",JSONObject.toJSONString(user));
            rabbitTemplate.convertAndSend( NORMAL_EXCHANGE,"XB",JSONObject.toJSONString(user));
            return "ok";
        }
    
    /**
     * 队列TTL 消费者
     */
    @Component
    public class DeadLetterQueueConsumer {
        @RabbitListener(queues = "QD")
        public void receiveD(Message message, Channel channel){
            String msg=new String(message.getBody());
            System.out.println("当前收到死信队列消息:"+msg+"当前时间是"+new Date().toString());
        }
    }
  • 手动应答:

  • 代码:

  1. 首先要在配置文件中开启手动应答:Springboot整合RabbitMQ_第13张图片
  2. 消费者中进行手动应答。
@Component
@RabbitListener(queues = "TestDirectQueue")
public class DirectUserInfoReceiver {
    
    @RabbitHandler
    public void receiveUserInfo(String userInfo, Channel channel, Message message) throws IOException, InterruptedException {
        System.out.println(userInfo);
        User user = JSONObject.parseObject(userInfo, User.class);
        System.out.println(user.getSex());
        System.out.println(user.getUserName());
        System.out.println(user.getPhoneNumber());
     
        //手动应答
        try {
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
        } catch (Exception e) {
            channel.basicReject(message.getMessageProperties().getDeliveryTag(),false);
        }

    }
}

你可能感兴趣的:(rabbitmq,rabbitmq,分布式,java)