RabbitMQ高频面试题

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

RabbitMQ的使用场景

  • 异步发送消息(验证码、短信、邮件…)
  • mysql、redis、es之间的数据同步
  • 分布式事务
  • 削峰填谷

面试题:RabbitMQ如何保证消息不丢失

RabbitMQ高频面试题消息丢失原因

  • 生产者发送的消息未到达交换机
  • 交换机未把消息路由到队列
  • mq服务器宕机,队列中的消息丢失
  • 消费者服务宕机,未接收到消息

发送端消息丢失解决方案

生产者确认机制
rabbitmq提供了publisher confirm机制来避免消息发送到mq过程中丢失。返回一个结果给生产者,表示消息是否接收成功。

消息接收失败后处理方案

  • 回调方法即时发送
  • 记录日志
  • 保存到数据库表定时重发,发送成功后删除表数据

交换机持久化

    @Bean
    public DirectExchange directExchange(){
        return new DirectExchange("myFanout.fanout",true,false);
    }

队列持久化

    @Bean
    public Queue simpleQueue(){
        return 
        // 使用QueueBuilder.durable创建的队列是持久化的
        QueueBuilder.durable("simpleQueue").build();
    }

消息持久化
mq默认是消息存储在内存中,开启持久化功能可以保证缓存在mq中的消息不丢失。

String message = "hello";
Message msg = MessageBuilder.withBody(message.getBytes(StandardCharsets.UTF_8)) // 设置消息体(将消息转换成byte)
               .setDeliveryMode(MessageDeliveryMode.PERSISTENT) // 将消息持久化
               .build();

消费者确认机制
rabbitmq支持消费者确认机制,消费者处理消息后向mq发送ack回执,mq收到ack后将消息删除。springAMQP则支持三种确认方式。

  • manual :手动ack,需要在业务代码执行完成后,手动调用api发送ack
  • auto : 自动ack,有spring监听代码是否发生异常,没有异常则发送ack,有异常则发送nack。(推荐使用)
  • none :关闭ack,mq假定消息者收到消息后就会处理成功,投递消息后将消息删除

我们可以利用Spring的retry机制,在消费者出现异常时利用本地重试,设置重试次数,当次数达到了以后,如果消息依然失败,将消息投递到异常交换机,交由人工处理。
RabbitMQ高频面试题

rabbitmq消息重复消费怎么解决

rabbitmq消息重复消费产生原因:

  • 网络波动
  • 消费者服务宕机

RabbitMQ高频面试题解决方案:

  • 给每条消息设置一个唯一的id标识(支付id、订单号、文章id…)
  • 幂等方案【分布式锁、数据库锁(乐观锁、悲观锁)】

**面试回答:**嗯,这个我们还真遇到过,是这样的,我们当时消费者是设置了自动确认机制,当服务还没来得及给MQ确认的时候,服务宕机了,导致服务重启之后,又消费了一次消息。这样就重复消费了。
因为我们当时处理的支付(订单|业务唯一标识),它有一个业务的唯一标识,我们再处理消息时,先到数据库查询一下,这个数据是否存在,如果不存在,说明没有处理过,这个时候就可以正常处理这个消息了。如果已经存在这个数据了,就说明消息重复消费了,我们就不需要再消费了。

rabbitmq死信交换机(延迟队列)有了解过吗

场景:超时订单、限时优惠、定时发布…

死信交换机
当一个队列中的消息满足下列情况之一时,可以成为死信(dead letter) :

  • 消费者使用basic.reject或 basic.nack声明消费失败,并且消息的requeue参数设置为false
  • 消息是一个过期消息,超时无人消费
  • 要投递的队列消息堆积满了,最早的消息可能成为死信

如果该队列配置了dead-letter-exchange属性,指定了一个交换机,那么队列中的死信就会投递到这个交换机中,而这个交换机称为死信交换机(Dead Letter Exchange,简称DLX)。

RabbitMQ高频面试题

    @Bean
    public Queue ttlQueue(){
        Map<String,Object> map = new HashMap<>();
        //设置死信队列属性
        map.put("x-dead-letter-exchange","order_exchange_delay");
        map.put("x-dead-letter-routing-key","dlx.order.get");
        map.put("x-message-ttl",5000);
        return QueueBuilder.durable("dl.queue").withArguments(map).deadLetterExchange("dl.direct").build();
    }

TTL
TTL,也就是Time-To-Live。如果一个队列中的消息TTL结束仍未消费,则会变为死信,TTL超时分为两种情况:

  • 消息所在的队列设置了存活时间
  • 消息本身设置了存活时间

如果这两种情况设置了TTL,那么以时间小的为准

消息堆积如何解决

什么是消息堆积?
当生产者发送消息的速度超过了消费者处理消息的速度,就会导致队列中的消息产生堆积,若队列存储的消息达到上限,那么队列外的消息就会成为死信,消息可能会被丢弃。
解决消息堆积的方案:

  • 增加消费者服务,提高消费者处理消息的速度
  • 在消费者服务内开启线程池加快消息处理的速度
  • 扩大消息队列的容积,提高堆积上限

惰性队列
惰性队列的特点如下:文章来源地址https://www.toymoban.com/news/detail-467936.html

  • 消息保存到磁盘
  • 消费者要消费时才会从磁盘读取加载到内存,效率会降低
  • 支持数百万的消息存储
    @Bean
    public Queue simpleQueue(){
        return 
        // 使用QueueBuilder.durable创建的队列是持久化的
        QueueBuilder.durable("simpleQueue")
        // 开启 x-queue-mode为lazy 
        .lazy()
        .build();
    }

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

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

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

相关文章

  • Java开发面试题目场景业务提问第十六章:常问日常必备_JAVA_面试题集(含答案)【王大师】

    往期文章   第 十 章 日常_JAVA_面试题集10(含答案)  第十三章:日常_JAVA_面试题集13(含答案)  第十二章:日常_JAVA_面试题集12(含答案)  第十一章:日常_JAVA_面试题集11(含答案)  往期文章大全……

    2024年02月08日
    浏览(54)
  • Unity 3D开发--SceneManager场景管理(异步使用同一个过渡场景)

    在U3D开发过程中经常使用到多场景的切换,有同步SceneManager.LoadScene()和异步SceneManager.LoadSceneAsync()两种方法,同步的话一般就会卡住界面直到加载完成,使用异步的话一般都做一个加载的进度条,每次切换的时候都需要一个加载动画,所以需要建一个专门的过渡加载场景来进

    2024年02月14日
    浏览(44)
  • 在C中使用Socket实现多线程异步TCP消息发送

    在本篇文章中,我们会探讨如何在C语言中使用socket来实现多线程,异步发送TCP消息的系统。虽然C标准库并没有原生支持异步和多线程编程,但是我们可以结合使用POSIX线程(pthread)库和socket来达到目的。 TCP (Transmission Control Protocol) 是一种面向连接的、可靠的、基于字节流的

    2024年02月11日
    浏览(43)
  • 使用 Vert.x 异步发送HTTP长阻塞请求来提高并发响应

    假设我们开发了一个必须与其他HTTP服务来交互的服务。不幸的是,这些HTTP服务速度慢且是阻塞的。 它可能是一个非常慢的遗留HTTP服务或我们必须使用的一些阻塞 API。无论如何,我们无法控制它。在这里,我们将调用两个HTTP API。其中一个将阻塞2秒钟,另一个将阻塞5秒钟。

    2024年02月03日
    浏览(65)
  • 如何使用RabbitMQ发送和接收消息

    本文介绍了如何使用RabbitMQ的Python客户端库pika来发送和接收消息,并提供了示例代码。读者可以根据自己的需求修改代码,例如修改队列名称、发送不同的消息等。 RabbitMQ 是一个开源的消息队列软件,可以用于在应用程序之间传递消息。下面是一个使用 RabbitMQ 的流程和代码

    2024年02月15日
    浏览(46)
  • AJAX 使用 JavaScript 的 `XMLHttpRequest` 对象来向服务器发送异步请求

    AJAX 是一种使用异步 HTTP (Ajax) 请求获取和发送数据的技术。它使得网页能够进行异步更新,而不需要重新加载整个页面。通过使用 AJAX,可以在不重新加载整个页面的情况下,与服务器交换数据并更新部分网页内容。 AJAX 使用 JavaScript 的 XMLHttpRequest 对象来向服务器发送异步请

    2024年01月16日
    浏览(55)
  • Java中如何使用消息队列实现异步(ActiveMQ,RabbitMQ,Kafka)

    在 Java 中,可以使用消息队列实现异步处理。下面是一个简单的示例代码,用于说明如何使用 ActiveMQ 实现消息队列异步处理: 添加 ActiveMQ 依赖 在 pom.xml 文件中添加以下依赖: 创建消息队列 创建一个名为 “TestQueue” 的消息队列,并配置 ActiveMQ 连接信息: 创建消息消费者

    2024年02月16日
    浏览(57)
  • 如何使用 RabbitMQ 进行消息的发送和接收

    1、创建连接工厂: 2、创建交换器和队列: 3、发送消息: 4、接收消息: 在上述示例中,我们创建了一个连接工厂,并通过它建立与 RabbitMQ 服务器的连接和通道。然后,我们声明了一个直连型交换器和一个队列,并将它们绑定在一起。接下来,我们使用basicPublish方法发送消

    2024年04月22日
    浏览(50)
  • 使用RabbitMQ控制台查看和发送消息

    控制台发消息 点击queues -- Publish message 发送消息 Headers 设置contentType application/json Payload里填上发送内容,点击Publish message 就可以 控制台查看消息 点击queues -- Get Message(s) -- Payload里查看内容 get message只是查看消息,不会消费该条消息

    2024年02月10日
    浏览(59)
  • 使用C#和RabbitMQ发送和接收消息

    通过NuGet安装 RabbitMQ.Client 以下是一个简单的示例代码,演示如何使用 C# 和 RabbitMQ 客户端库来发送和接收消息: durable持久化 durable 参数用于指定队列是否是持久化的。 当 durable 参数设置为 true 时,表示队列是持久化的。持久化的队列会在RabbitMQ服务器重启后仍然存在,确保

    2024年02月11日
    浏览(43)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包