RabbitMQ消息发布之发送方确认

RabbitMQ之失败确认中,我们提到失败确认只会让RabbitMQ向你通知失败,而不会通知成功。如果消息正确路由到队列,则发布者不会受到任何通知。带来的问题是无法确保发布消息一定是成功的,因为通知失败的消息可能会丢失。
在这里插入图片描述



那么我们如何能够进一步的来保证其消息的可靠性呢?这里我们就在想,要是RabbitMQ不仅仅在路由失败的时候给我们发送消息,并且能够在消息路由成功的时候也给我们发送消息就好了,这里RabbitMQ就为我们提供了该方案,即发送方确认模式


原理: 生产者将信道设置成confirm模式,一旦信道进入confirm模式,所有在该信道上面发布的消息都将会被指派一个唯一的ID(从1开始),由这个id在生产者和RabbitMQ之间进行消息的确认。




发送方确认模式需要分两种情况下列来看,首先我们先来看一看消息不可路由的情况,如下:
在这里插入图片描述
首先我们都知道,消息不可路由时,就不存在路由到队列了,所以这里只管到交换器的路径,当消息成功送到交换器后,就会进行确认操作。


另外在这过程中,生产者接受到了确认消息后,那么因为消息无法路由,所以该消息也是无效的,所以一般情况下这里会结合我们在RabbitMQ之失败确认中介绍过失败确认模式,这里一般会进行设置mandatory模式,失败则会调用addReturnListener监听器来进行处理。




发送方确认模式的另一种情况肯定就是消息可以进行路由,如下:
在这里插入图片描述

可路由的消息,要等到消息被投递到所有匹配的队列之后,broker会发送一个确认给生产者(包含消息的唯一ID),这就使得生产者知道消息已经正确到达目的队列了。


如果消息和队列是可持久化的,那么确认消息会在将消息写入磁盘之后发出,broker回传给生产者的确认消息中delivery-tag域包含了确认消息的序列号。




RabbitMQ的发送方确认模式共有三种方式:

  1. 普通发送方确认模式
    channel.waitForConfirms()普通发送方确认模式;每条消息都需要进行逐条确认,当消息到达交换器,就会返回true
    在这里插入图片描述

这里我们就在RabbitMQ之失败确认上的代码基础上进行修改了下,如上添加了发送者确认,测试结果如下:
在这里插入图片描述



  1. 批量确认模式
    使用同步方式等所有的消息发送之后才会执行后面代码,只要有一个消息未到达交换器就会抛出IOException异常。
    在这里插入图片描述
    这里我们就可以在catch中进行一些业务处理,来处理消息发送失败后的动作。



  1. 异步监听发送方确认模式
    channel.addConfirmListener()异步监听发送方确认模式
    在这里插入图片描述

上述添加的ConfirmListener中,我们实现两个方法,一个是发送成功的ack方法,另一个是发送失败的nack方法,其中都有两个参数deliveryTagmultiple,其中第一个表示消息的ID,由这个id在生产者和RabbitMQ之间进行消息的确认;第二个表示是否是批量确认。


在异步监听发送方确认模式下,将有RabbitMQ帮我们来决定是否批量发送,这里我们就是通过multiple来判断的,测试结果如下:
在这里插入图片描述
从上述结果来看,我们共发送了3条消息,第一条消息(ID=1),multiple为false,是一条消息单独发送确认的。
而第二、三条消息时批量确认的,deliveryTag返回的是最后一条消息的ID,multiple表示是多条消息批量确认。
这个结果我们多运行几次,发现是又会不同的表现的,这里就有RabbitMQ为我们进行判断。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章