rabbitMQ手动应答与自动应答

这篇具有很好参考价值的文章主要介绍了rabbitMQ手动应答与自动应答。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

手动应答模式(manual)

解释:
        手动应答:既是当消费者消费了队列中消息时需要给队列一个应答,告诉队列这条消息我已经消费了,可以删除了;
        若是不应答,即使消费了 队列没收到消费成功的提示 所有消息会一直在队列中;
    注意 注意 注意:重要的事情说三遍,下面说的很重要
 场景:

        当我们使用了手动应答模式,消费者若是成功消费了信息,我们给队列一个成功应答(channel.basicAck(deliveryTag,false);),然后队列收到应答后就会把此消息删除,这点时毋庸置疑的,因为我们已成功消费了这个消息,也不想让此消息继续留在队列中;
        但是,若是消费者消费消息失败了,该怎么办? 这时不能再给队列一个成功的应答(给了那这条消息不就丢失了吗),不给应答呢 消息又一直在队列中,而倘若我们给一个拒绝应答(channel.basicReject(deliveryTag,true) true会重回队列,若是false 消息就丢了,一般都会设置为true;),那么你就成功掉进坑里了,这样队列会一直循环投递消息,而消费者这边又不能成功消费,消费者又拒绝应答,队列又投递消息......
        对,此时就会进入死循环,搞不好光错误日志就会沾满内存;这时该有人会说了,不对,我们在配置文件中不是开启了重试,并且配置了最大重试次数了吗?
        如下配置:
     *                  #是否开启自动重试 默认为false 不开启
     *                  spring.rabbitmq.listener.simple.retry.enabled=true
     *                  #最大重试次数
     *                  spring.rabbitmq.listener.simple.retry.max-attempts=5
     *                  #最大重试时间间隔
     *                  spring.rabbitmq.listener.simple.retry.max-interval=20000ms
     *                  #重试时间间隔
     *                  spring.rabbitmq.listener.simple.retry.initial-interval=2000ms
     *                  # 最大重试间隔*乘数
     *                  #应用于上一重试间隔的乘数 第一次(重试时间间隔)2s 4s 8s 16s 32s 此处32s>20s 以后都以20s为间隔 总的次数为最大重试次数
     *                  spring.rabbitmq.listener.simple.retry.multiplier=2
        那么,应该会在最大重试次数试完还不成功就应该不尝试投递了啊,这样不应该走死循环了啊!
        其实这就是要特别注意的点,当我们开启了手动应答时 当消息没被成功消费并给队列拒绝时上面那些配置其实都已经失效了!!! 所以就会进入死循环!
        但是在开发中我们不想让消息丢失,那么开启自动应答显然不合理,而开启手动应答时当出现错误时(没成功消费)又会进入死循环,那该怎么解决呢?

解决:

        引入死信队列; 当消息没被成功消费时 我们把这条消息投递到私信队列中,然后我们再人为的干预处理此消息即可!

自动应答:

        顾名思义 当消费者成功消费了队列中消息,队列就会自动的把此消息从队列中删除,若是没有消费者或者消费者消费失败,队列在尝试最大重试次数后就会把此消息删除;

 注意:文章来源地址https://www.toymoban.com/news/detail-691876.html

手动模式 若消息没成功消费时,若给队列拒绝(重试机制不生效),则会进入死循环,若不给拒绝 抛出异常(重试机制生效) 则消息会堆积在队列中,后续投递的消息也会堆积并不会被消费
/**
 * 消费者
 */

@Component
@Slf4j
public class DirectConsumer {



/**
     * 手动应答模式(manual)
     * 解释:
     *   手动应答:既是当消费者消费了队列中消息时需要给队列一个应答,告诉队列这条消息我已经消费了,可以删除了;
     *       若是不应答,即使消费了 队列没收到消费成功的提示 所有消息会一直在队列中;
     *    注意 注意 注意:重要的事情说三遍,下面说的很重要
     *        场景:当我们使用了手动应答模式,消费者若是成功消费了信息,我们给队列一个成功应答(channel.basicAck(deliveryTag,false);),
     *            然后队列收到应答后就会把此消息删除,这点时毋庸置疑的,因为我们已成功消费了这个消息,也不想让此消息继续留在队列中;
     *            但是,若是消费者消费消息失败了,该怎么办? 这时不能再给队列一个成功的应答(给了那这条消息不就丢失了吗),不给应答呢 消息又一直在队列中
     *            而倘若我们给一个拒绝应答(channel.basicReject(deliveryTag,true) true会重回队列,若是false 消息就丢了,一般都会设置为true;)
     *            那么你就成功掉进坑里了,这样队列会一直循环投递消息,而消费者这边又不能成功消费,消费者又拒绝应答,队列又投递消息......
     *            对,此时就会进入死循环,搞不好光错误日志就会沾满内存;这时该有人会说了,不对,我们在配置文件中不是开启了重试,并且配置了最大重试次数了吗?
     *            如下配置:
     *                  #是否开启自动重试 默认为false 不开启
     *                  spring.rabbitmq.listener.simple.retry.enabled=true
     *                  #最大重试次数
     *                  spring.rabbitmq.listener.simple.retry.max-attempts=5
     *                  #最大重试时间间隔
     *                  spring.rabbitmq.listener.simple.retry.max-interval=20000ms
     *                  #重试时间间隔
     *                  spring.rabbitmq.listener.simple.retry.initial-interval=2000ms
     *                  # 最大重试间隔*乘数
     *                  #应用于上一重试间隔的乘数 第一次(重试时间间隔)2s 4s 8s 16s 32s 此处32s>20s 以后都以20s为间隔 总的次数为最大重试次数
     *                  spring.rabbitmq.listener.simple.retry.multiplier=2
     *             那么,应该会在最大重试次数试完还不成功就应该不尝试投递了啊,这样不应该走死循环了啊!
     *             其实这就是要特别注意的点,当我们开启了手动应答时 当消息没被成功消费并给队列拒绝时上面那些配置其实都已经失效了!!! 所以就会进入死循环!
     *             但是在开发中我们不想让消息丢失,那么开启自动应答显然不合理,而开启手动应答时当出现错误时(没成功消费)又会进入死循环,那该怎么解决呢?
     *
     *             解决: 引入死信队列; 当消息没被成功消费时 我们把这条消息投递到私信队列中,然后我们再人为的干预处理此消息即可!
     *
     *
     *   自动应答:顾名思义 当消费者成功消费了队列中消息,队列就会自动的把此消息从队列中删除,若是没有消费者或者消费者
     *        消费失败,队列在尝试最大重试次数后就会把此消息删除;
     *
     * 注解含义:
     *   1、@RabbitHandler  handler真正的执行者
     *   2、@RabbitListener 监听DirectQueue-01这个队列
     *
     * @param user 接受的消息类型为user(生产者发送的为user类型)
     * @param message
     * @param channel
     * @throws IOException
     */
    @RabbitHandler
    @RabbitListener(queues = RabbitConfig.QUEUE_KEY_03)
    public void process2(User user, Message message, Channel channel) throws IOException {
//        long deliveryTag = message.getMessageProperties().getDeliveryTag();
       try {
           //业务开始
           if (user.getId().equals(5)) {
               int a=1/0;
           }
           System.out.println("接受到消息,并正常处理结束"+ JSONUtil.toJsonStr(user));
           //业务结束

           /**
            * 确认应答
            * basicAck(long deliveryTag, boolean multiple)
            * deliveryTag:当前消息在队列中的的索引;
            * multiple:为true的话就是批量确认 是消费一个就应答还是一批处理完再应答;通常都是false 一个一个应答
            */

//           channel.basicAck(deliveryTag,false);
       }catch (Exception ex){
           System.out.println(ex.getMessage());
           System.out.println("接受到消息,发生异常"+ JSONUtil.toJsonStr(user));
           System.out.println(user);
           throw ex;
              //拒绝    true的时候拒绝,false时消息就丢了
//           channel.basicReject(deliveryTag,true);
       }
    }
}
                    

到了这里,关于rabbitMQ手动应答与自动应答的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • RabbitMQ消息应答

    1.概念 消费者完成一个任务可能需要一段时间,如果其中一个消费者处理一个长的任务并仅只完成了部分突然它挂掉了,会发生什么情况,RabbitMQ一旦向消费者传递了一条消息,便立即将该消息标记为删除。在这种情况下,突然有个消费者挂掉了,我们将丢失正在处理的消息

    2024年02月07日
    浏览(37)
  • rabbitmq的消息应答

    消费者完成一个任务可能需要一段时间,如果其中一个消费者处理一个长的任务并仅只完成 了部分突然它挂掉了,会发生什么情况。RabbitMQ 一旦向消费者传递了一条消息,便立即将该消 息标记为删除。在这种情况下,突然有个消费者挂掉了,我们将丢失正在处理的消息。以

    2024年02月13日
    浏览(112)
  • RabbitMQ 消息应答与发布

    目录 一、消息应答 1、自动应答(默认) 2、手动消息应答的方法  ​编辑 3、消息重新入队 4、手动应答案列与效果演示 二、RabbitMQ持久化 1、队列持久化 2、消息持久化 三、不公平分发(能者多劳,弱者少劳) 1、介绍 2、效果演示 四、预取值分发 1、介绍 五、发布确认 六

    2024年02月06日
    浏览(38)
  • RabbitMQ 消息应答

    物是人非事事休,欲语泪先流。 为了保证消息在发送过程中不丢失,RabbitMQ引入了消息应答机制, 消费者在接收到消息并且处理该消息后,告诉RabbitMQ它已经处理了,RabbitMQ可以把消息删除了。 消息发送后立即被认为已经传送成功, 这种模式需要在高吞吐量和数据传输安全性

    2024年02月08日
    浏览(39)
  • 消息队列-RabbitMQ:workQueues—工作队列、消息应答机制、RabbitMQ 持久化、不公平分发(能者多劳)

    Work Queues— 工作队列 (又称任务队列) 的主要思想是避免立即执行资源密集型任务,而不得不等待它完成 。 我们把任务封装为消息并将其发送到队列,在后台运行的工作进程将弹出任务并最终执行作业。当有多个工作线程时,这些工作线程将一起处理这些任务 。 轮训分发消

    2024年02月21日
    浏览(56)
  • RabbitMQ (HelloWord 消息应答 持久化 不公平分发 预取值)

    在下图中,“P”是我们的生产者,“C”是我们的消费者。中间的框是一个队列-RabbitMO.代表使用者保留的消息缓冲区 第一步:导入依赖 第二步:创建生产者 第三步:创建消费者 因为你为了确保同一条消息被其中一个工作线程接收到了之后,其它工作就不能消费的到了 三者

    2023年04月14日
    浏览(43)
  • RabbitMQ手动签收消息

    这里讲解SpringBoot使用RabbitMQ进行有回调的用法和消费者端手动签收消息的用法。

    2024年02月11日
    浏览(28)
  • RabbitMq 手动ACK

    如果我们设置的是自动确认的话,那么就会有当接收到消息,去处理消息的时候生成异常,那么就会有消息丢失的情况。这种异常可能是网络波动,服务器宕机等情况都会发生。 并且如果没有ACK 的话会导致mq 中的unacked 的数量飙升,可能会撑爆内存 所以大部分项目中都会去

    2024年02月12日
    浏览(45)
  • python rabbitmq 手动ack

    Centos 安装 RabbitMQ rabbitmq-doc

    2024年02月13日
    浏览(33)
  • 手动清除RabbitMQ队列的消息缓存

           在个人的springboot项目中使用到了rabbitmq作为消息队列中间件,但是在项目的调试过程中出现了某些错误,导致rabbitmq的生产者端循环产生了多条消息给消费者,而消费者又因为该错误无法及时将消息处理掉,所以在消费端积压了多条消息;在修复了错误重启项目后

    2024年02月11日
    浏览(40)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包