开篇介绍

大家好,公众号【Java极客思维】近期会整理一些Java高频面试题分享给小伙伴,也希望看到的小伙伴在找工作过程中能够用得到!本章节主要针对Java一些消息中间件高频面试题进行分享。

Q1:

RabbitMQ 的介绍、用途、好处?

RabbitMQ是一款开源的,Erlang编写的,基于AMQP协议的消息中间件。

作用:解耦 、 异步 、 削峰 。

优点:解耦、异步、削峰;

缺点:降低了系统的稳定性:系统中使用了消息队列,如果消息队列挂了,那么系统也会挂。降低了系统可用性。

加入消息队列,要考虑很多方面的问题,比如:一致性问题 、如何保证消息不被重复消费 、 如何保证消息可靠性传输 等。因此考虑的因素有很多方面,复杂性增加。

Q2:

RabbitMQ 包括哪些要素?

  • 生产者 :消息的创建者,发送到RabbitMQ

  • 消费者 :连接到RabbitMQ,订阅到队列上,消费消息,持续订阅(basicConsumer)和单条订阅(basicGet)

  • 消息 :包含有效载荷和标签,有效载荷指要传输的数据,标签描述了有效载荷,并且RabbitMQ用它来决定谁获得消息,消费者只能拿到有效载荷,并不知道生产者是谁。

Q3:

RabbitMQ 什么是信道?

信道:是生产者、消费者与RabbitMQ通信的渠道,生产者publish或是消费者subscribe一个队列都是通过信道来通信的。信道是建立在TCP连接上的虚拟连接。就是说RabbitMQ在一条TCP上建立成百上千个信道来达到多个线程处理,这个TCP被多个线程共享,每个线程对应一个信道,信道在RabbitMQ都有一个唯一的ID,保证了信道私有性,对应上唯一的线程使用。

疑问:为什么不建立多个TCP连接?

原因是RabbitMQ需要保证性能,系统为每个线程开辟一个TCP是非常消耗性能的,美妙成百上千的建立销毁TCP会严重消耗系统性能;所以RabbitMQ选择建立多个信道(建立在TCP的虚拟连接)连接到RabbitMQ上

Q4:

RabbitMQ概念里的channel、exchange 和 queue是逻辑概念,还是对应着进程实体?作用分别是什么?

queue 具有自己的 erlang 进程;

exchange 内部实现为保存 binding 关系的查找表;

channel 是实际进行路由工作的实体,负责按照 routing_key 将 message投递给queue。

由 AMQP 协议描述可知,channel 是真实TCP连接之上的 虚拟连接 , 所有AMQP 命令都是通过 channel 发送的,且每一个 channel 有 唯一的ID 。一个 channel 只能被单独一个操作系统线程使用,所以投递到特定的 channel 上的 message 是有顺序的。单一个操作系统线程上允许使用多个channel。

Q5:

RabbitMQ消息是如何路由的?

消息路由必须有三部分:交换器路由绑定

生产者把消息发布到交换器上,绑定决定了消息如何从路由器路由到特定的队列;消息最终到达队列,并被消费者接收。

消息发布到交换器时,消息将拥有一个 路由键(routing key) , 在消息创建时设定。

通过队列路由键,可以把队列绑定到交换器上。

消息到达交换器后,RabbitMQ会将消息的路由键与队列的路由键进行匹配(针对不同的交换器有不同的路由规则)。如果能够匹配到队列,则消息会投递到相应队列中;如果不能匹配到任何队列,消息将进入"黑洞"。

常用的交换器主要分为以下三种:

  • direct :如果路由键完全匹配,消息就会被投递到相应的队列;每个AMQP的实现都必须有一个direct交换器,包含一个空白字符串名称的默认交换器。声明一个队列时,会自动绑定到默认交换器,并且以队列名称作为路由键:channel -> basic_public($msg, '', 'queue-name')

  • fanout : 如果交换器收到消息,将会广播到所有绑定的队列上;

  • topic :可以使来自不同源头的消息能够到达同一个队列。使用topic交换器时,可以使用通配符,比如:"*" 匹配特定位置的任意文本,"." 把路由键分为了几个标识符, "#" 匹配所有规则等。

特别注意:发往topic交换器的消息不能随意的设置选择键(routing_key),必须是有"."隔开的一系列的标识符组成。

Q6:

RabbitMQ消息确认过程?

消费者收到的每一条消息都必须进行确认(自动确认和自行确认)

消费者在声明队列时,可以置顶autoAck参数,当autoAck = false时,RabbitMQ会等待消费者显式发送回 ack 信号后才从内存(和磁盘,如果是持久化消息的话)中删除消息,否则RabbitMQ会在队列中消息被消费后立即删除它。

采用消息确认机制后,只要使 autoAck = false,消费者就有足够的时间处理消息(任务),不用担心处理消息过程中消费者进程挂掉后消息丢失的问题,因为RabbitMQ会一直持有消息直到消费者显式调用basicAck为止。

当autoAck = false时,对于RabbitMQ服务器端而言,队列中的消息分成了两部分:一部分是等待投递给消费者的消息;一部分是已经投递给消费者,但是还没有收到消费者ack信号的消息。如果服务器端一直没有收到消费者的ack信号,并且消费此消息的消费者已经断开连接,则服务器端会安排该消息 重新进入队列,等待投递给下一个消费者(也可能还是原来的那个消费者)。

RabbitMQ不会为 ack消息设置超时时间,它判断此消息是否需要重新投递给消费者的唯一依据是消费该消息的消费者连接是否已经断开。这么设计的原因是RabbitMQ允许消费者消费一条消息的时间可以很久很久。

Q7:

如何保证RabbitMQ不被重复消费?

正常情况下,消费者在消费消息的时候,消费完毕后,会发送一个确认信息给消息队列,消息队列就知道该消息被消费了,就会将该消息从消息队列中删除。

但是因为网络传输等故障,确认信息没有传送到消息队列,导致消息队列不知道自己已经消费过该消息了,再次将消息分发给其他的消费者。

解决思路:

保证消息的唯一性,就算是多次传输,不要让消息的多次消费带来影响;

保证消息幂等性;

比如:在写入消息队列的数据做唯一标识,消费消息时,根据唯一标识判断该消息是否被消费过。

Q8:

如何保证RabbitMQ消息的可靠传输?

消息不可靠的情况可能是消息丢失,劫持等原因;

丢失可能又分为:

  • 生产者丢失消息

  • 消息队列丢失消息

  • 消费者丢失消息

生产者丢失消息

从生产者弄丢数据来看,RabbitMQ提供了 transaction 机制 和 confirm 模式 来确保生产者不丢失消息;

  • transaction机制: 发送消息前,开启事务(channel.exSelect()),然后发送消息,如果发送过程中出现异常,事务就会回滚(channel.txRollback()),如果发送成功则提交事务(channel.txCommit())。

  • confirm模式:一般这种模式居多,一旦channel进入confirm模式,所有在该信道上发布的消息都将会被指派一个唯一的ID(从1开始),一旦消息被投递到所有匹配的队列后;RabbitMQ就会发送一个ACK给生产者(包含消息的唯一ID),这就使得生产者知道消息已经正确到达目的队列了。

如果RabbitMQ没能处理该消息,则会发送一个Nack消息回来,这样可以进行重试操作。

消息队列丢失消息

针对消息队列丢失数据的情况,一般是开启持久化磁盘的配置:

将队列的持久化标识 durable 设置为 true , 则代表是一个持久的队列,发送消息的时候讲 deliveryMode=2 这样设置以后,即使RabbitMQ挂了,重启后也能恢复数据。

消费者丢失消息

消费者丢失消息一般是因为采用了自动确认消息模式,改为手动确认消息即可。

消费者在收到消息之后,处理消息之前,会自动回复RabbitMQ已收到消息;如果这时候处理消息失败,就会丢失该消息;

解决方案:处理消息成功后,手动回复确认消息。


点关注、不迷路

如果觉得文章不错,欢迎关注点赞收藏,你们的支持是我创作的动力,感谢大家。

如果文章写的有问题,请不要吝啬,欢迎留言指出,我会及时核查修改。

如果你还想更加深入的了解我,可以微信搜索「Java极客思维」进行关注。每天8:00准时推送技术文章,让你的上班路不在孤独,而且每月还有送书活动,助你提升硬实力!

中间件面试专题:RabbitMQ高频面试问题的更多相关文章

  1. 字节跳动上传了一份“面试官版Android面试小册”,不讲一句废话,全是精华

    前言 金三银四马上就到了,很多粉丝朋友私信希望我出一篇面试专题或者分享面试相关的笔记来学习,这不今天就给大家安排上了?(都是干货,错过就是亏.) 下面的面试笔记都是精心整理好免费分享给大家的,希望新朋 ...

  2. 手撕面试官系列(八):分布式通讯ActiveMQ+RabbitMQ+Kafka面试专题

    ActiveMQ专题 (面试题+答案领取方式见主页) 什么是 ActiveMQ? ActiveMQ 服务器宕机怎么办? 丢消息怎么办? 持久化消息非常慢. 消息的不均匀消费. 死信队列. Active ...

  3. php面试专题---MySQL分表

    php面试专题---MySQL分表 一.总结 一句话总结: 分库分表要数据达到一定的量级才用,这样才有效率,不然利不一定大于弊,可能会增加一次I/O消耗 1.分库分表的使用量级是多少? 单表行数超过 ...

  4. php面试专题---MySQL分区

    php面试专题---MySQL分区 一.总结 一句话总结: mysql的分区操作还比较简单,好处是也不用自己动手建表进行分区,和水平分表有点像 1.mysql分区简介? 一个表或索引-->N个物 ...

  5. 2019前端面试系列——JS高频手写代码题

    实现 new 方法 /* * 1.创建一个空对象 * 2.链接到原型 * 3.绑定this值 * 4.返回新对象 */ // 第一种实现 function createNew() { let obj ...

  6. 手撕面试官系列(六):并发+Netty+JVM+Linux面试专题

    并发面试专题 (面试题+答案领取方式见侧边栏) 现在有 T1.T2.T3 三个线程,你怎样保证 T2 在 T1 执行完后执行,T3 在 T2 执行完后执行? 在 Java 中 Lock 接口比 syn ...

  7. php面试专题---22、网站优化 总结

    php面试专题---22.网站优化 总结 一.总结 一句话总结: 主要从前端.后端.数据库.资源四个方面开始发散 前端浏览器缓存和数据压缩前端优化(减少HTTP请求次数) 资源流量优化(防盗链处理)C ...

  8. php面试专题---21、MVC框架基本工作原理考察点

    php面试专题---21.MVC框架基本工作原理考察点 一.总结 一句话总结: 会的东西快速过,不要浪费时间,生命有限,都是一些很简单的东西. 1.mvc框架单一入口的 优势 是什么? 可以进行统一的 ...

  9. php面试专题---20、MySQL的安全性考点

    php面试专题---20.MySQL的安全性考点 一.总结 一句话总结: 还是得多看视频,教程看的浮光掠影,容易get不到重点:比如预处理防sql注入之前是挺熟,后面就忘记了,而且看文章get不到点 ...

随机推荐

  1. .NET5都来了,你还不知道怎么部署到linux?最全部署方案,总有一款适合你

    随着2020进入4季度,.NET5正式版也已经与大家见面了.不过,尽管 .NET Core发布已经有四五年的时间,但到目前为止,依旧有很多.NET开发者在坚守者.NET4,原因不尽相同,但最大的问题可 ...

  2. ESP8266 鼓捣记 - 入门(环境搭建)

    一.前言 以前没怎么接触过硬件开发,ESP8266 这个名字还是从朋友处得知,用它做了许多好玩的东西,便想着自己也来玩一玩.定了一个小目标,做一个温度计.本文介绍从0到 "Hello Wor ...

  3. cephfs元数据池故障的恢复

    前言 cephfs 在L版本已经比较稳定了,这个稳定的意义个人觉得是在其故障恢复方面的成熟,一个文件系统可恢复是其稳定必须具备的属性,本篇就是根据官网的文档来实践下这个恢复的过程 实践过程 部署一个c ...

  4. 快速安装jumpserver开源堡垒机

    一 安装centos 7.X操作系统 二.选择极速安装(注意配置需要是4G2核) https://jumpserver.readthedocs.io/zh/master/install/setup_b ...

  5. vue项目中echarts属性总结

    <div id="echarts" style="width: 600px;height: 400px;margin-top: 100px;margin-left: ...

  6. 面试BAT问的最多的27道MyBatis 面试题(含答案和思维导图总结)

    前言 关于MyBatis总结了一个思维导图希望对大家有帮助 什么是 Mybatis? Mybatis 是一个半 ORM(对象关系映射)框架,它内部封装了 JDBC,开发时只需要关注 SQL 语句本身, ...

  7. 面试官:小伙子,你给我说一下Java中什么情况会导致内存泄漏呢?

    概念 内存泄露:指程序中动态分配内存给一些临时对象,但对象不会被GC回收,它始终占用内存,被分配的对象可达但已无用.即无用对象持续占有内存或无用对象的内存得不到及时释放,从而造成的内存空间浪费. 可达 ...

  8. list scheduling algorithm 指令调度 —— 笔记

    作者:Yaong 出处:https://www.cnblogs.com/yaongtime/articles/14033444.html 版权:本文版权归作者和博客园共有 转载:欢迎转载,但未经作者同 ...

  9. CorelDRAW 里面如何将文字调整成半透明的颜色

    早在几年前,平面设计师在做设计时会遇到关于印刷的难题,那就是为了降低印刷成本,必须减少他们的颜色数量.随着印刷方法的进步,特别是数字出版物的兴起,我们生活在一个主要是通过屏幕观看图形的时代,一个可以显 ...

  10. 一 HTML基础入门

    HTML概念 HTML是标记语言,由W3C组织提供的一套标记标签组成.其使用标记标签来描述网页,一个网页除了由大量的标签组成,还有后续要学习的css样式和JavaScript脚本组合而成. 网页与网站 ...