zoukankan      html  css  js  c++  java
  • RabbitMQ的ack机制

    1、什么是消息确认ACK。

      答:如果在处理消息的过程中,消费者的服务器在处理消息的时候出现异常,那么可能这条正在处理的消息就没有完成消息消费,数据就会丢失。为了确保数据不会丢失,RabbitMQ支持消息确定-ACK。

    2、RabbitMQ的ACK的消息确认机制。

    1、ACK机制是消费者从RabbitMQ收到消息并处理完成后,反馈给RabbitMQ,MQ收到反馈后才将此消息从队列中删除。消息的ACK确认机制默认是打开的

    2、如果一个消费者在处理消息出现了网络不稳、服务器异常等现象,那么就不会有ACK反馈,RabbitMQ会认为这个消息没有正常消费,会将消息重新放入队列。
    3、如果在集群的情况下,RabbitMQ会立即将这个消息推送给这个在线的其他消费者。这种机制保证了在消费者服务端故障的时候,不丢失任何消息和任务。
    4、消息永远不会从RabbitMQ中删除,只有当消费者正确发送ACK反馈,RabbitMQ确认收到后,消息才会从RabbitMQ服务器的数据中删除。

    3、ACK机制的开发注意事项?

      如果消费者发生异常,ack没法送消息应答。,Message会一直重新分发。然后RabbitMQ会占用越来越多的内容,由于RabbitMQ会长时间运行,因此这个"内存泄漏"是致命的。

    4.怎么解决ack的内存泄漏问题?

     1、在程序处理中可以进行异常捕获,保证消费者的程序正常执行。

     2、使用RabbitMQ的ack的配置确认机制。(开启重试次数)

     3、手动设置消息应答。如果消费端异常,也返回应答成功,再把未消费成功的数据记录下来,进行补偿。

    # 开启重试
    32 spring.rabbitmq.listener.simple.retry.enabled=true
    33 # 重试次数,默认为3次
    34 spring.rabbitmq.listener.simple.retry.max-attempts=5
    //第二个参数值为false代表关闭RabbitMQ的自动应答机制,改为手动应答。
    channel.basicConsume(QUEUE_NAME, false, consumer);
    
    //在处理完消息时,返回应答状态。
    channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false);

    5、消费端的手工ACK与NACK?

    1、当我们设置 autoACK=false 时,就可以使用手工ACK方式了,那么其实手工方式包括了手工ACK与NACK。
    2、当我们手工 ACK 时,会发送给Broker一个应答,代表消息成功处理了,Broker就可以回送响应给生产端了。NACK 则表示消息处理失败了,如果设置重回队列,Broker端就会将没有成功处理的消息重新发送。
     
    消费端进行消费的时候,如果由于业务异常我们可以手工 NACK 并进行日志的记录,然后进行补偿!:

    使用方法:void basicNack(long deliveryTag, boolean multiple, boolean requeue):
    1、参数:requeue为true,表示deliveryTag=n之前未确认的消息都处理失败且将这些消息重新放回队列中。
    2、参数:requeue为false,表示deliveryTag=n之前未确认的消息都处理失败且将这些消息直接丢弃。

    3、如果由于服务器宕机等严重问题,那我们就需要手工进行 ACK 保障消费端消费成功!方法:void basicAck(long deliveryTag, boolean multiple)

  • 相关阅读:
    ROM、RAM、DRAM、SRAM和FLASH的区别
    寄存器读写为什么需要用位操作符
    不同变量存放在什么地方
    C语言中数据类型对变量的作用
    内存寻址、对齐,变量左值和右值
    位、字节、半字、字、内存位宽
    面试题10- II. 青蛙跳台阶问题
    509. 斐波那契数
    面试题10- I. 斐波那契数列
    面试题32
  • 原文地址:https://www.cnblogs.com/lgg20/p/12538903.html
Copyright © 2011-2022 走看看