RabbitMQ养成记 (8. 消费者接受消息可靠性 consumer Ack)

Consumer Ack

ack 指的是acknowledge 确认, 指的是消费端收到消息后的确认方式。
有三种确认方式:

  • 自动确认
  • 手动确认 (根据业务情况 手动确认是否成功发送)
  • 根据异常情况确认

我们在消费端用代码实践一下:
首先我们定义监听器来获取消息:

@Component
public class RabbitMQListener {
    @RabbitListener(queues = "boot_queue")
    public void ListenerQueue(Message message){
        System.out.println(Arrays.toString(message.getBody()));
    }

}

你只需要指定 queues 队列 就可以了 这是最简答的一种方式。

有些新手可能会问? 拿到消息 不是要实现MessageListener接口并重写onMessage方法吗???

这种也可以 不过这是一种 比较传统的方法:
这里解释一下:


当你不使用@RabbitListener注解时,需要实现MessageListener接口并重写onMessage方法,是因为这是一种传统的方式来定义 RabbitMQ 的消息监听器。
MessageListener接口定义了一个用于处理消息的方法onMessage,当消息到达监听容器时,容器会调用该方法,并将消息作为参数传递给方法。
当你使用SimpleMessageListenerContainer或其他类似的监听容器来配置 RabbitMQ 的消息监听器时,需要显式地指定一个实现了MessageListener接口的对象作为消息监听器。容器会负责接收消息,并将其传递给监听器的onMessage方法进行处理。
而使用@RabbitListener注解的方式,是Spring AMQP提供的一种更简化和方便的方式,用于声明消息监听器的方法。通过注解标记的方法会被框架自动识别为消息监听器,并处理消息的接收和转换。
使用@RabbitListener注解的方法不需要显式实现MessageListener接口,是因为框架会自动处理消息的转换,并将消息内容作为方法的参数传递进去。
总结起来,使用@RabbitListener注解的方式是Spring AMQP提供的一种便捷方式,可以更轻松地定义和配置消息监听器。而不使用注解的情况下,需要显式实现MessageListener接口并重写onMessage方法,是一种传统的方式来定义 RabbitMQ 的消息监听器。


在yml中设置手动ack:

spring:
  rabbitmq:
    host: ***********
    username: guest
    password: guest
    virtual-host: /
    port: 5672
    listener:
      simple:
        acknowledge-mode: manual

代码:

@Component
public class RabbitMQListener {

    @RabbitListener(queues = "boot_queue")
    public void ListenerQueue(Message message,
                              @Header(AmqpHeaders.DELIVERY_TAG) long deliveryTag,
                              Channel channel) throws IOException {
        try {
            System.out.println("收到消息为"+new String(message.getBody()));

            System.out.println("处理业务逻辑。。");

            channel.basicAck(deliveryTag,true);

        }catch (IOException e){
            //拒绝签收
            //这里的第三个参数表示 如果为true 消息重回到queue broker会重新发送该消息给消费端
            channel.basicNack(deliveryTag,true,true);
           
           //从系统解耦的角度上讲这个地方 应该为false 因为你业务失败了 上游是不会再给你发一次的

        }
    }

}

然后我们把原来的代码扩充一下 在这里实现 手动的ack。

这里有一个大坑 卡了我半天。 网上好多教程里面 这个ackmode设置直接可以在@RabbitListener注解里面设置,但是我的spring版本里面 RabbitListener接口就没有这个 ack这个属性 西巴
最后发现在yml里面配置就好了

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
RabbitMQ通过以下几种机制来保证消费端的消息可靠性: 1. 确认机制(Ack机制):消费端在成功消费一条消息后,会向Broker端发送Ack确认报文,告知自己已完成消费。如果Broker没有收到确认报文,那么消息不会被标为已消费,从而避免了消息的丢失。然而,如果消费者在发送确认报文时由于网络断开等原因无法成功发送,会导致消息重复消费的问题。 2. 发布者确认(Publisher Confirm):生产者在发送消息后可以等待RabbitMQ返回确认通知。如果生产者接收到确认通知,就可以判断消息已被成功发送到Broker。如果网络断开或其他异常情况导致确认通知无法及时返回,生产者可以选择重新发送消息,以确保消息可靠性。然而,这可能会导致RabbitMQ中存在两条相同的消息,从而可能导致重复消费的问题。 3. QoS机制(Quality of Service):RabbitMQ提供了QoS保证机制,可以限制消费端在一个Channel上未被Ack消息数量。如果超过了这个数量限制,RabbitMQ将不再向消费端推送消息,以避免消费端因大量消息瞬时到达而产生巨大压力。这是一种流控手段,能够保护消费端的可靠性。但需要注意的是,QoS机制仅对消费端的推模式有效,对拉模式无效;同时,QoS机制不支持NONE Ack模式。 综上所述,RabbitMQ通过Ack机制、发布者确认和QoS机制来保证消费端的消息可靠性。然而,由于网络断开和其他异常情况的存在,无法完全避免消息的重复消费。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值