当前位置: 移动技术网 > IT编程>开发语言>Java > RabbitMQ中生产者丢消息的情况

RabbitMQ中生产者丢消息的情况

2020年07月31日  | 移动技术网IT编程  | 我要评论

生产端丢消息的情况

1、连接broker失败(连接地址写错、broker宕机)

  • 通过try、catch解决

2、连接正常,不能发送到Exchange、发送到exchange但没有路由到queue(exchange写错、queue没有接受)

  • 因为消息时异步发送的,所以只能通过回调的方式判断是否发送成功,然后在通过补偿机制进行补救。

回调的代码实现

把Exchange的名称故意写错(这里就不上图了)。

虽然返回的结果是正常的,但消息并没有实际路由到Queue中,从而丢消息。

  • 解决方法:通过回调的方式判断是否发送成功、是否路由成功,如果出现了错误再通过补偿机制进行补救。
添加回调
  • 默认是不开启回调的,因为对性能有影响
  • 注入自己的RabbitTemplate,并添加回到
  • 在配置文件中开启
package com.wcong.config;

import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

/**
 * @author wcong
 * @version 1.0
 * @date 2020-07-29 22:23
 */
@Configuration
public class TemplateConfig {

    @Bean
    @Primary
    public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory){
        RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
        //设置开启Mandatory,才能触发回调函数,无论消息推送结果怎么样都强制调用回调函数
        rabbitTemplate.setMandatory(true);

//        发送到Exchange的回调,发送成功:ack为true
        rabbitTemplate.setConfirmCallback(new RabbitTemplate.ConfirmCallback() {
            @Override
            public void confirm(CorrelationData correlationData, boolean ack, String cause) {
                System.out.println("ConfirmCallback:     "+"相关数据:"+correlationData);
                System.out.println("ConfirmCallback:     "+"是否确认:"+ack);
                System.out.println("ConfirmCallback:     "+"原因:"+cause);
//            进行相关补偿机制
            }
        });
//       路由回调,只有回调了这个方法,才表示这个消息被成功路由了。
        rabbitTemplate.setReturnCallback(new RabbitTemplate.ReturnCallback() {
            @Override
            public void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) {
                System.out.println("ReturnCallback:     "+"消息:"+message);
                System.out.println("ReturnCallback:     "+"回应码:"+replyCode);
                System.out.println("ReturnCallback:     "+"回应信息:"+replyText);
                System.out.println("ReturnCallback:     "+"交换机:"+exchange);
                System.out.println("ReturnCallback:     "+"路由键:"+routingKey);
            }
        });

        return rabbitTemplate;
    }

}

在这里插入图片描述

模拟Exchange不存在

在这里插入图片描述

  • 发现只触发了ConfirmCallback回调,没有触发ReturnCallback回调
  • 你Exchange都没进,肯定不会触发ReturnCallback回调啊
    在这里插入图片描述
模拟Exchange正常,路由错误

在这里插入图片描述

  • 两个回调都触发了
  • 先触发ReturnCallback回调,在触发ConfirmCallback回调
  • 注意ReturnCallback回的状态码等值
    在这里插入图片描述
正常的情况
  • 只要回调了ReturnCallback方法,就表示这个消息路由失败了
  • 没有回调了ReturnCallback方法,而且ConfirmCallback回调的ack为false,就表示交换机都没进。

在这里插入图片描述

本文地址:https://blog.csdn.net/qq_43332570/article/details/107696260

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网