关于java:中间件面试专题RabbitMQ高频面试问题

55次阅读

共计 3519 个字符,预计需要花费 9 分钟才能阅读完成。

开篇介绍

大家好,公众号【Java 极客思维】近期会整顿一些 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 准时推送技术文章,让你的下班路不在孤单,而且每月还有送书流动,助你晋升硬实力!

正文完
 0