RabbitMQ 高级篇八 消费端ACK与重回队列
RabbitMQ 高级篇八 消费端ACK与重回队列
本文详细介绍了RabbitMQ消息中间件中消费端ACK与重回队列的机制。文章首先解释了自动签收和手动签收的区别,然后通过具体应用场景说明了手动Ack和Nack的使用场景。最后通过代码演示了如何实现重回队列的功能。
消费端的签收方式
消费端的签收方式分为自动签收和手动签收两种。
自动签收:在
channel.basicConsume
方法的第二个参数autoAck
设置为true
即可实现自动签收。手动签收:将
autoAck
参数设置为false
即可实现手动签收。手动签收又分为两种方式:手动Ack和Nack。
Ack与Nack的区别
Ack:表示手工签收后消息处理成功。
Nack:表示手动签收后消息处理失败。此时Broker会自动重新发送消息。
使用场景
场景一
假设我们设置的自动重复消息次数是3次,那么在Nack后,Broker会重复发送三次消息。如果三次之后,还是Nack的,这种情况下,我们不可能一直重复发送,此时就可以设置为Ack,然后在消费端进行消费的时候,如果由于业务处理而产生的异常,我们可以进行日志的记录或者给开发人员发送警报邮件,然后进行补偿。
场景二
如果由于服务器宕机等严重性的问题,此时是不可能收到ack或者Nack,这种情况下也会一直重复发送消息的,那么我们就需要手工的Ack,来保证消费端消费成功。在服务器重启之后,会自动的消费之前未消费成功的消息的。
以上两个案例,就体现了消费端ACK或者NACK的重要性。
消费端的重回队列
消费端的重回队列是为了对没有处理成功的消息,把消息重新返回给Broker。注意,在一般我们在实际的应用中,都会关闭重回队列,也就是设置未false。
代码演示
模拟需求
我们在properties的handers中设置for循环的num。假设如果num等于1,就重回队列。
生产者中,添加properties信息:
在消息处理的类:MyConsumer类中添加重回队列的判断:
我们开源看到,调用的是nack方法。参数说明:
long deliveryTag
:消息标签boolean multiple
:是否批量boolean requeue
:是否重回队列- 如果设置成true,那么失败的消息会重新放到消息的最后
channel.basicNack(envelope.getDeliveryTag(),false,true);
修改完成之后,启动消费者和生产者,查看运行效果:
我们可以看到控制台打印的,第0个不断重复被打印。说明,下标为0的被重回到队列中了。