RabbitMQ消息传递的可靠性

如何保证消息的可靠性

1. 生产者 -> 队列 (可靠投递)需要经过两步
   1. 生产者 到 交换机
   2. 交换机 到 队列
2. 队列 -> 消费者 (可靠消费)

1、生产者到交换机的保障是依靠confrimCallback机制

confrimCallback:确人回调,默认是不开启的。当开启这个模式之后,生产者会给交换机发送一个消息。交换机收到消息后??

spring:
  rabbitmq:
    publisher-confirm-type: correlated # 开启confirmCallback
void testConfirmCallBack(){
    // 设置ConfimCallball, 重写其中的 confim方法
    rabbitTemplate.setConfirmCallback(new RabbitTemplate.ConfirmCallback() {
        @Override
        public void confirm(CorrelationData correlationData, boolean ack, String cause) {
			/* 
			 ack 表示消息是否到达了交换机,交换机是否确认收到消息
			 cause 存储的是没有到达交换机的原因
			*/
            if(ack==false){
                System.out.println("如果没有到达交换机,根据需要写你的业务代码");
            }
        }
    });

    Map<String,Object> message=new HashMap<>();
    message.put("product_id",10);
    message.put("num",50);
    message.put("price",600);
    rabbitTemplate.convertAndSend("abc","hello.orange.abc", JSON.toJSONString(message));
}

2、交换机到队列的消息保证

returnCallback 翻译过来就是返回回调,但是这种回调机制并不像 confirmCallback 机制一样,
confirmCallback 不管消息是否成功到达交换机都会被调用,
returnCallback 只有在交换机到达队列失败的时候才会被触发,当这个回调函数被调用的时候,
说明交换机的消息没有顺利的到达队列
void testReturnCallBack(){
    // 为rabbitTemplate设置return机制触发的方法
    rabbitTemplate.setReturnsCallback(messgae->{
        System.out.println(messgae);
    });
    Map<String,Object> message=new HashMap<>();
    message.put("product_id",10);
    message.put("num",50);
    message.put("price",600);
    rabbitTemplate.convertAndSend(
        RabbitConfiguration.exchange_name01, // 交换机名称
        "das", // routingKey
        JSON.toJSONString(message));//要发送的消息
}

3、保证消息到达消费者的可靠性

开启手动确认模式:

spring:
  rabbitmq:
    listener:
      simple:
        acknowledge-mode: manual # 使用手动确认模式

 最后在手动确认channel.basicNack。可以选择重新发送

@Component
public class MyListener {
    @RabbitListener(queues = {"springboot-topic-queue01"})
    public void message(Message message, Channel channel) throws  Exception{
        //接受消息
        System.out.println(message.getBody());
        try {
            System.out.println("业务处理");
            // 没有出现异常,手动确认该消息,消息队列会删除该消息
            channel.basicAck(
            		/// 获取消息的传送标签,queue使用该标签进行确认消息
                    message.getMessageProperties().getDeliveryTag(),
                    false // 是否把之前的消息全都确认。
            );
        }catch (Exception e){
            // 如果出现异常,不确认该消息
            channel.basicNack(
                    message.getMessageProperties().getDeliveryTag(),
                    false, // 是否确认多条
                    false // 是否重新发送
            );
        }
    }
}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值