RabbitMQ的消息确认有两种。android
一种是消息发送确认。这种是用来确认生产者将消息发送给交换器,交换器传递给队列的过程当中,消息是否成功投递。发送确认分为两步,一是确认是否到达交换器,二是确认是否到达队列。spring
第二种是消费接收确认。这种是确认消费者是否成功消费了队列中的消息。app
(1)ConfirmCallbackspring-boot
经过实现ConfirmCallBack接口,消息发送到交换器Exchange后触发回调。3d
使用该功能须要开启确认,spring-boot中配置以下:blog
spring.rabbitmq.publisher-confirms = true接口
(2)ReturnCallbackrabbitmq
经过实现ReturnCallback接口,若是消息从交换器发送到对应队列失败时触发(好比根据发送消息时指定的routingKey找不到队列时会触发)队列
使用该功能须要开启确认,spring-boot中配置以下:ip
spring.rabbitmq.publisher-returns = true
(1)确认模式
spring-boot中配置方法:
spring.rabbitmq.listener.simple.acknowledge-mode = manual
(2)手动确认
未确认的消息数
上图为channel中未被消费者确认的消息数。
经过RabbitMQ的host地址加上默认端口号15672访问管理界面。
(2.1)成功确认
void basicAck(long deliveryTag, boolean multiple) throws IOException;
deliveryTag:该消息的index
multiple:是否批量. true:将一次性ack全部小于deliveryTag的消息。
消费者成功处理后,调用channel.basicAck(message.getMessageProperties().getDeliveryTag(), false)方法对消息进行确认。
(2.2)失败确认
void basicNack(long deliveryTag, boolean multiple, boolean requeue)
throws IOException;
deliveryTag:该消息的index。
multiple:是否批量. true:将一次性拒绝全部小于deliveryTag的消息。
requeue:被拒绝的是否从新入队列。
void basicReject(long deliveryTag, boolean requeue) throws IOException;
deliveryTag:该消息的index。
requeue:被拒绝的是否从新入队列。
channel.basicNack 与 channel.basicReject 的区别在于basicNack能够批量拒绝多条消息,而basicReject一次只能拒绝一条消息。
消息队列的基础知识能够参考:消息队列RabbitMQ基础知识详解
(1)手动确认模式,消息手动拒绝中若是requeue为true会从新放入队列,可是若是消费者在处理过程当中一直抛出异常,会致使入队-》拒绝-》入队的循环,该怎么处理呢?
第一种方法是根据异常类型来选择是否从新放入队列。
第二种方法是先成功确认,而后经过channel.basicPublish()从新发布这个消息。从新发布的消息网上说会放到队列后面,进而不会影响已经进入队列的消息处理。
void basicPublish(String exchange, String routingKey, boolean mandatory, boolean immediate, BasicProperties props, byte[] body)
throws IOException;
(2)消息确认的做用是什么?
为了防止消息丢失。消息丢失分为发送丢失和消费者处理丢失,相应的也有两种确认机制。