Java常见面试题之RabbitMQ

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

为什么要使用RabbitMQ

        RabbitMQ是一款非常优秀的消息中间件,它可以实现各个模块之间的松耦合,提高程序的灵活性,可扩展性,使用RabbitMQ主要有以下优点:

  1. 异步消息传递,RabbitMQ支持异步消息传递,可以实现异步处理消息,提高程序的执行效率.
  2. 消息队列排队服务,RabbitMQ可以将消息暂存到消息队列中,有效缓解生产者和消费者的压力.
  3. RabbitMQ支持基于消息的路由机制,发布订阅/机制,工作模式等多重模式,灵活性较高.
  4. RabbitMQ非常容易扩展,对于大数据量或者高并发的程序的帮助非常大.
  5. 可靠性,RabbitMQ有非常可靠的消息确认机制,如:ACK确认机制和消息的持久性等.确保消息不会丢失..

说一下你在项目中使用RabbitMQ的场景

        我们的项目使用RabbitMQ的场景非常多,我也在很多场景使用过RabbitMQ,例如:

        在用户选择调整上课时间之后,会从原直播间的白名删除,再加入到新的直播间白名单中,并且通知对应的分管教师.在这个流程中,最核心的业务功能是从原直播间的白名单中删除,再加入到新的直播间白名单中.其次不是很重要的是通知对应的分管教师.在这个场景下,我们同步完成的业务就是刚才提到的核心业务.在核心业务处理完之后,会从知音楼、教师后台、短信同时通知对应的分管教师.这三个通知我们会使用RabbitMQ进行异步处理,这样可以提高整个业务逻辑功能的执行速度,提高用户体验.这个场景主要也是使用了RabbitMQ的异步处理功能.

        还是上面的例子.由于我们的项目是分布式的项目,各个模块之间是相互独立的,从接受到请求的controller层到service层再到dao层,其实都是一些独立的子项目,在子项目中相互交流,我们会使用RabbitMQ进行消息传递,这样既可以降低各个模块之间的耦合度,也可以确保消息不会丢失.

        而且由于我们的项目要求所有的操作日志都要存放在相应的日志表里,并且同时要落盘到本地的日志文件中,所以为了提高效率,我们会将日志信息存放到RabbitMQ中,由专门负责处理日志的模块去从消息队列中获取消息并处理.这样不会因为处理日志信息导致核心业务的处理效率收到日志处理的影响.

如何确保消息正确的发送到RabbitMQ?如何确保消息接收方接收到了消息

        在使用RabbitMQ时,我们要首先确认程序和RabbitMQ的连接状态和信道状态

        之后就要确保生产者的消息可以到达Exchange,这一环节RabbitMQ是提供了ACK消息确认机制的,当我们开启ACK消息确认机制.消息从生产者发送到交换机,会有一个confirm回调函数,如果交换机正确的接收了方法,ACK为true,如果交换机没有接收到消息,ACK就是false,同时还会返回对应的错误信息.

        要确保消息接收方能够接收到消息,我们要做一下分析,使用RabbitMQ之后,生产者会将消息先发送至Exchange,Exchange再将消息发送到相应的Queue,消费者从Queue中获取消息,其中第一个环节我们已经可以确保它可以发送过去。最后的消费者从Queue获取消息,我们需要检查消费者监听的队列是否正确。

        重点在第二步,从Exchange到Queue,这个环节RabbitMQ提供了Return确认机制,如果消息从Exchange成功到达了Queue,不会执行回调,如果发送失败,就会执行ReturnCallback回调,同时返回消息本体,错误状态码,错误信息,交换机和发生错误的路由。

如何确认消息不会被重复消费

        按照正常逻辑来说,消费者在消费一条消息之后会向MQ发送一条消息,MQ会在收到消息之后删除该消息.但是可能由于一些原因,消费者在获取到消息之后在给MQ发送消息时宕机之类的就会导致消息被消费但是没有从队列中移除.再次被消费时就会导致消息重复消费的问题.

        解决方式

        我们消息的生产者在发送消息时,给每条消息添加一个唯一的消息ID,同时在redis中以id为key添加一条针对消费状态的数据,在消费者收到消息先根据消息ID去redis中查询是否被消费了,如果消费的话后面的业务逻辑就不再执行.如果没有消费就继续执行后面的业务.在执行完业务之后将该条消息在redis中的状态修改为已消费.

        这样的话如果当前的消息被消费并且业务执行完成了,但是队列中没有移除消息.当消费者再次消费当前消息时,还会去redis中查询消费状态,如果,被消费了,就不去执行后面的业务,这样就不会重复消费.虽然消息还是被消费了两次,但是对业务不会造成影响.文章来源地址https://www.toymoban.com/news/detail-490417.html

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

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

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

相关文章

  • 【JAVA】为什么要使用封装以及如何封装

    个人主页:【😊个人主页】 系列专栏:【❤️初识JAVA】 Java的封装指的是在一个类中将数据和方法进行封装,使其可以保护起来,只能在该类内部访问,而不允许外部直接访问和修改。这是Java面向对象编程的三个基本特性之一,另外两个是继承和多态。在此之前我们已经学

    2024年02月08日
    浏览(60)
  • Java开发手册中为什么禁止使用BigDecimal的equals方法做等值比较已经为什么禁止使用double直接构造BigDecimal

    阿里Java开发手册嵩山版中明确指出: 1、BigDecimal的等值比较应使用compareTo()方法,而不是equals()方法 equals()方法会比较值和精度(1.0与1.00返回结果为false),而compareTo()则会忽略精度 2、禁止使用构造方法BigDecimal(double)的方式把double值转换为BigDecimal对象 BigDecimal(double)存在精度损

    2024年02月07日
    浏览(56)
  • Java面试题:为什么HashMap不建议使用对象作为Key?

    HashMap 是一种基于哈希表的动态数据结构,它允许使用任意不可变对象作为键(key)来存储和检索数据。然而,在某些情况下,使用对象作为 HashMap 的键可能会遇到一些问题。   首先,我们需要明确对象作为 HashMap 的键需要满足一些条件: 不可变性:对象的属性不能被修改,

    2024年04月22日
    浏览(55)
  • 什么是 Java 中的数据库连接池?为什么使用连接池来管理数据库连接?

    数据库连接池(database connection pool)是在 Java 中用于管理数据库连接的一种技术。它的主要目的是提高数据库连接的重用性和性能。在传统的数据库连接方式中,每次与数据库建立连接时都需要进行一系列的网络通信和身份验证操作,这样的开销较大并且会影响应用程序的性

    2024年02月06日
    浏览(63)
  • 在Java中使用FileReader.read()进行读取文件时,为什么乱码?两个方法解决

     以上代码是有可能出现代码输出混乱的情况的,输出效果如下: 可能会出现乱码的问题: 原因可能是文件编码与程序读取时使用的编码不一致。在创建 FileReader 对象时,没有指定文件的编码格式,因此默认使用的是系统默认的编码格式。如果文件中包含非系统默认编码格式

    2024年02月03日
    浏览(44)
  • java常见面试题:什么是迭代器模式(Iterator Pattern)?如何实现迭代器模式?

    迭代器模式(Iterator Pattern)是设计模式中的一种,它提供了一种顺序访问一个聚合对象(如列表、集合等)中各个元素的方法,而又不需要暴露该对象的内部表示。使用迭代器模式,可以方便地遍历一个聚合对象的所有元素,而不需要了解该对象的底层结构。 迭代器模式主

    2024年01月18日
    浏览(55)
  • Java开发手册中为什么不建议在for循环中使用“+“进行字符串操作

    java开发手册中对于循环体中进行字符串的拼接要求如下: 【推荐】循环体内,字符串的连接方式,使用 StringBuilder 的 append 方法进行扩展。 说明:下例中,反编译出的字节码文件显示每次循环都会 new 出一个 StringBuilder 对象,然后进行 append操作, 最后通过 toString 方法返回

    2024年02月08日
    浏览(55)
  • RabbitMQ 常见面试题

    流量削峰 代码解耦 异步处理 简单消息模型 功能:一个生产者P发送消息到队列Q,一个消费者C接收。实现了基本的消息的生产和消费。一对一。 工作队列 功能:一个生产者,多个消费者。写法与基本消息模型类似,只不过原来是一个消费者,现在是多个消费者。多个消费者处

    2024年02月07日
    浏览(33)
  • java的springboot框架中使用logback日志框架使用RabbitHandler注解为什么获取不到消费的traceId信息?

    当使用 Logback 日志框架和 RabbitMQ 的 @RabbitHandler 注解时,如果无法获取消费的 traceId 信息,可能是因为在处理 RabbitMQ 消息时,没有正确地将 traceId 传递到日志中。 为了将 traceId 传递到日志中,你可以利用 MDC(Mapped Diagnostic Context)机制。MDC 是一个线程绑定的上下文容器,允许

    2024年02月09日
    浏览(48)
  • java常见面试题:如何使用Java进行单元测试?

    单元测试是软件开发中的一个重要环节,它确保每个单独的代码单元都能按照预期工作。以下是如何使用Java进行单元测试的详细说明: JUnit : JUnit是Java中最流行的单元测试框架。 首先,添加JUnit依赖到你的项目中。如果你使用Maven,可以在 pom.xml 中添加以下依赖: 复制代码

    2024年02月02日
    浏览(54)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包