RabbitMQ如何保证消息可靠性

首先确定消息可能在哪些位置丢失---不同的位置可以有不同的解决方案。

1.从生产者--交换机

2.从交换机--队列

3.队列里面

4.消费者消费时

 

1.保证消息从生产者到交换机

comfirm确认机制

* 1. 手动开启确认机制spring.rabbitmq.publisher-confirm-type=correlated

* 2. 为rabbitTemplate设置确认回调函数

/**
     * 1. 手动开启确认机制spring.rabbitmq.publisher-confirm-type=correlated
     * 2. 为rabbitTemplate设置确认回调函数
     */
    @Test
    public void testConfirm(){

        //为rabbitTemplate设置确认回调函数
        rabbitTemplate.setConfirmCallback(new RabbitTemplate.ConfirmCallback() {
            //不管是否到达交换机 都会触发该方法
            @Override
            public void confirm(CorrelationData correlationData, boolean b, String s) {
                 if(b==false){
                     //根据自己的业务完成相应的代码
                     System.out.println("消息发送失败---订单回滚");
                 }
            }
        });
        rabbitTemplate.convertAndSend("testX2","a","Hello Springboot2");
    }

2 保证消息可以从交换机到队列

returning机制: 如果消息无法到达队列,则会触发returning机制。如果能从交换机到队列则不会触发returning机制。

默认rabbitMQ不开启该机制。

 * 1.开启returning机制 spring.rabbitmq.publisher-returns=true
  * 2.为rabbitTemplate设置returning回调函数

/**
     * 1.开启returning机制 spring.rabbitmq.publisher-returns=true
     * 2.为rabbitTemplate设置returning回调函数
     */
    @Test
    public void testReturning(){
        rabbitTemplate.setReturnsCallback(new RabbitTemplate.ReturnsCallback() {
            //该方法只要从交换机到队列失败时才会触发
            @Override
            public void returnedMessage(ReturnedMessage returned) {
                System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~");
            }
        });
        rabbitTemplate.convertAndSend("testX","ax","Hello Springboot2");
    }

3 如何保证消息在队列

  1. 队列持久化--->

  2. 搭建rabbitmq集群--保证高可用

4 消费者可靠的消费消息

1.修改为手动确认模式

#改为自动确认spring.rabbitmq.listener.simple.acknowledge-mode=manual

2.当业务处理完毕后在确认消息给队列让其删除该消息

@RabbitListener(queues = "test01")
    public void test01(Message message, Channel channel){
        byte[] body = message.getBody();
        long deliveryTag = message.getMessageProperties().getDeliveryTag();
        System.out.println("接受到消息"+new String(body));
        try {

            System.out.println("处理业务代码");

            System.out.println("业务处理完毕");
            //手动确认---队列会把该信息移除。
            //long deliveryTag,消息的标记
            // boolean multiple: 是否把之前没有确认的消息以前确认掉。
            channel.basicAck(deliveryTag,true);
        }catch (Exception e){
            //1.让队列在给我发一次。
            //long deliveryTag, boolean multiple,
            // boolean requeue: 继续发给我 还是直接
            try {
                channel.basicNack(deliveryTag,true,true);
            } catch (IOException ioException) {
                ioException.printStackTrace();
            }

        }


    }

如何保证消息的可靠性。

  1. 设置confirm和returning机制

  2. 设置队列和交互机的持久化

  3. 搭建rabbitMQ服务集群

  4. 消费者改为手动确认机制。

5.如何限制消费者消费消息的条数

  1. 设置消费者消费消息的条数

  2. 消费者端必须为手动确认模式。

#设置消费者最多一次消费的消息个数spring.rabbitmq.listener.simple.prefetch=5
 @RabbitListener(queues = "test03")
    public void test03(Message message, Channel channel) throws IOException {
        byte[] body = message.getBody();
        System.out.println("消息的内容:"+new String(body));
      // channel.basicAck(message.getMessageProperties().getDeliveryTag(),true);
    }

6.设置过期时间

TTL:time to live

可以为整个队列设置也可以单独为某条信息设置

7.单独为消息设置过期时间

 @Test
    public void test02() {
        MessagePostProcessor messagePostProcessor=new MessagePostProcessor() {
            @Override
            public Message postProcessMessage(Message message) throws AmqpException {
                message.getMessageProperties().setExpiration("10000");
                return message;
            }
        };
        rabbitTemplate.convertAndSend("testX", "d", "Hello Springboot",messagePostProcessor);
    }

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
RabbitMQ 通过持久化和确认机制来保证消息可靠性。 在发送消息时,可以设置消息的 delivery mode 为 2,表示消息需要被持久化。持久化的消息会被写入磁盘,即使 RabbitMQ 服务器宕机或重启,消息也不会丢失。 在接收消息时,可以使用确认机制。当消费者成功处理了一条消息后,会向 RabbitMQ 发送确认消息。如果 RabbitMQ 收到确认消息,就会将该消息从队列中删除,否则该消息会被重新发送。通过确认机制,可以保证消息不会被重复消费。 以下是一个简单的 RabbitMQ 发送和接收消息的示例代码: ``` import pika connection = pika.BlockingConnection(pika.ConnectionParameters(host='localhost')) channel = connection.channel() # 声明队列 channel.queue_declare(queue='hello', durable=True) # 发送消息 channel.basic_publish(exchange='', routing_key='hello', body='Hello World!', properties=pika.BasicProperties(delivery_mode=2)) print(" [x] Sent 'Hello World!'") # 接收消息 def callback(ch, method, properties, body): print(" [x] Received %r" % body) ch.basic_ack(delivery_tag=method.delivery_tag) channel.basic_qos(prefetch_count=1) channel.basic_consume(queue='hello', on_message_callback=callback) print(' [*] Waiting for messages. To exit press CTRL+C') channel.start_consuming() ``` 在这个示例中,我们设置了队列的 durable 属性为 True,表示队列需要被持久化。在发送消息时,我们设置了消息的 delivery mode 为 2,表示消息需要被持久化。在接收消息时,我们使用了确认机制,通过调用 ch.basic_ack() 方法确认消息已经被消费。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值