RabbitMQ 消息确认机制 以及 原理解析

  • 1、场景

  1. 当消息的投送方把消息投递出去,殊不知道消息是否投递成功了。若是消息投送方无论的话,势必对系统的形成可靠性的影响。
  2. 但是若是要保证系统的可靠性,消息投靠方,如何知道消息是否投放成功了呢?
  3. 这个就须要消息的确认机制,咱们来看下rabbitMQ的消息去人机制是如何作的。

  • 2、原理:上图

    

 

  • 3、原理解析

  1. 消息的确认分两部分:rabbitMQ确认生产者投递的消息 和 消费者确认 rabbitMQ服务器的消息

  2. 首先说RabbitMQ对生产者的确认,总共分为两种模式分别为 同步模式异步模式

    (1)  同步模式分为 单条消息确认批量确认

      ①  单条消息确认: channel.waitForConfirms() 普通发送方确认模式;消息到达交换器,就会返回true

      ②  批量消息确认: channel.waitForConfirmsOrDie()批量确认模式;使用同步方式等全部的消息发送以后才会执行后面代码,只要有一个消息未到达交换器就会抛出IOException异常。

    (2) 异步模式为生产者 异步监听消息确认

服务器

      异步监听消息确认:channel.addConfirmListener()异步监听发送方确认模式

异步

    3. 其次说下消费者对RabbitMQ 消息确认。总共分为两种方式 分别为 手动确认 和 自动确认。

spa

      消费者收到的每一条消息都必须进行确认。消息确认后,RabbitMQ才会从队列删除这条消息,RabbitMQ不会为未确认的消息设置超时时间,它判断此消息是否须要从新投递给消费者的惟一依据是消费该消的消费者链接是否已经断开。设计

    这么设计的缘由是RabbitMQ容许消费者消费一条消息的时间能够好久好久。

blog

    (1) 自动确认:队列

  消费者在声明队列时,能够指定autoAck参数,当autoAck=true时,一旦消费者接收到了消息,就视为自动确认了消息。若是消费者在处理消息的过程当中,出了错,就没有什么办法从新处理这条消息,因此咱们不少时候,进程

须要在消息处理成功后,再确认消息,这就须要手动确认。

内存

  (2)  手动确认:同步

      

         ①当autoAck=false时,RabbitMQ会等待消费者显式发回ack信号后才从内存(和磁盘,若是是持久化消息的话)中移去消息。不然,RabbitMQ会在队列中消息被消费后当即删除它。

it

 

         ②采用消息确认机制后,只要令autoAck=false,消费者就有足够的时间处理消息(任务),不用担忧处理消息过程当中消费者进程挂掉后消息丢失的问题,由于RabbitMQ会一直持有消息直到消费者显式调用basicAck为止。

 

  ③当autoAck=false时,对于RabbitMQ服务器端而言,队列中的消息分红了两部分:一部分是等待投递给消费者的消息;一部分是已经投递给消费者,可是尚未收到消费者ack信号的消息。若是服务器端一直没有收到消费

者的ack信号,而且消费此消息的消费者已经断开链接,则服务器端会安排该消息从新进入队列,等待投递给下一个消费者(也可能仍是原来的那个消费者)。

 

   ④经过运行程序,启动两个消费者AB,均可以收到消息,可是其中有一个消费者A不会对消息进行确认,当把这个消费者A关闭后,消费者B又会收到原本发送给消费者A的消息。因此咱们通常使用手动确认的方法是,将消息的处理放在try/catch语句块中,成功处理了,就给RabbitMQ一个确认应答,若是处理异常了,就在catch中,进行消息的拒绝

 

 

 

  • 若是有什么不足欢迎讨论!
相关文章
相关标签/搜索