共计 3075 个字符,预计需要花费 8 分钟才能阅读完成。
开篇介绍
大家好,我是 Java 最全面试题库
的提裤姐,明天这篇是中间件面试题系列的第一篇,次要总结了 RabbitMQ 相干的面试题;在后续,会沿着第一篇开篇的常识线路始终总结上来,做到日更!如果我能做到百日百更,心愿你也能够跟着百日百刷,一百天养成一个好习惯。
什么是 RabbitMQ?为什么应用 RabbitMQ?有什么益处?
RabbitMQ 是一款开源的,Erlang 编写的,基于 AMQP 协定的,消息中间件;
能够用它来:解耦
、 异步
、 削峰
。
- 长处:解耦、异步、削峰;
- 毛病:升高了零碎的稳定性:零碎中应用了音讯队列,如果音讯队列挂了,那么零碎也会挂掉。因而,零碎可用性会升高;
退出了音讯队列,要多思考很多方面的问题,比方:一致性问题、如何保障音讯不被反复生产、如何保障音讯可靠性传输等。因而,须要思考的货色更多,复杂性增大。
RabbitMQ 基本概念有哪些?
Broker
:音讯队列服务器实体Exchange
:音讯交换机,它指定音讯按特定规定,路由到哪个队列Queue
:音讯队列载体,每个音讯都会被投入到一个或多个队列Binding
:绑定,它的作用就是把 exchange 和 queue 依照路由规定绑定起来Routing Key
:路由关键字,exchange 依据这个关键字进行音讯投递VHost
:vhost 能够了解为虚构 broker,即 mini-RabbitMQ server。其外部均含有独立的 queue、exchange 和 binding 等,领有独立的权限零碎,能够做到 vhost 范畴的用户管制。Producer
:音讯生产者Consumer
:音讯消费者Channel
:音讯通道,在客户端的每个连贯里,可建设多个 channel,每个 channel 代表一个会话工作
如何保障 RabbitMQ 不被反复生产?
失常状况下,消费者在生产音讯的时候,生产结束后,会发送一个确认音讯给音讯队列,音讯队列就晓得该音讯被生产了,就会将该音讯从音讯队列中删除;
然而因为网络传输等等故障,确认信息没有传送到音讯队列,导致音讯队列不晓得本人曾经生产过该音讯了,再次将音讯分发给其余的消费者。
解决思路:
保障音讯的唯一性,就算是屡次传输,不要让音讯的屡次生产带来影响;保障音讯等幂性;
比方:在写入音讯队列的数据做惟一标识,生产音讯时,依据惟一标识判断是否生产过;
RabbitMQ 概念里的 channel、exchange 和 queue 是逻辑概念,还是对应着过程实体?别离起什么作用?
queue 具备本人的 erlang
过程;
exchange 外部实现为保留 binding
关系的查找表;
channel 是理论进行路由工作的实体,即负责依照 routing_key 将 message 投递给 queue。
由 AMQP 协定形容可知,channel
是实在 TCP 连贯之上的 虚构连贯
,所有 AMQP 命令都是通过 channel 发送的,且每一个 channel 有 惟一的 ID
。一个 channel 只能被独自一个操作系统线程应用,故投递到特定 channel 上的 message 是有程序的。但一个操作系统线程上容许应用多个 channel。
rabbitmq 音讯是如何路由的?
从概念上来说,音讯路由必须有三局部:交换器、路由、绑定。
生产者把音讯公布到交换器上;绑定决定了音讯如何从路由器路由到特定的队列;音讯最终达到队列,并被消费者接管。
音讯公布到交换器时,音讯将领有一个 路由键(routing key)
,在音讯创立时设定。
通过队列路由键,能够把队列绑定到交换器上。
音讯达到交换器后,RabbitMQ 会将音讯的路由键与队列的路由键进行匹配(针对不同的交换器有不同的路由规定)。如果可能匹配到队列,则音讯会投递到相应队列中;如果不能匹配到任何队列,音讯将进入“黑洞”。
罕用的交换器次要分为一下三种:
direct
:如果路由键齐全匹配,音讯就被投递到相应的队列fanout
:如果交换器收到音讯,将会播送到所有绑定的队列上topic
:能够使来自不同源头的音讯可能达到同一个队列。应用 topic 交换器时,能够应用通配符,比方:“*”
匹配特定地位的任意文本,“.”
把路由键分为了几局部,“#”
匹配所有规定等。
特地留神:发往 topic 交换器的音讯不能随便的设置选择键(routing_key),必须是由 ”.” 隔开的一系列的标识符组成。
如何保障 RabbitMQ 音讯的牢靠传输?
音讯不牢靠的状况可能是音讯失落,劫持等起因
失落又分为:
- 生产者失落音讯
- 音讯列表失落音讯
- 消费者失落音讯
生产者失落音讯:
从生产者弄丢数据这个角度来看,RabbitMQ 提供 transaction 机制
和confirm 模式
来确保生产者不丢音讯;
- transaction 机制:发送音讯前,开启事务(channel.txSelect()),而后发送音讯,如果发送过程中呈现什么异样,事务就会回滚(channel.txRollback()),如果发送胜利则提交事务(channel.txCommit())。
- confirm 模式(用的居多):一旦 channel 进入 confirm 模式,所有在该信道上公布的音讯都将会被指派一个惟一的 ID(从 1 开始),一旦音讯被投递到所有匹配的队列之后;RabbitMQ 就会发送一个 ACK 给生产者(蕴含音讯的惟一 ID),这就使得生产者晓得音讯曾经正确达到目标队列了;
如果 RabbitMQ 没能解决该音讯,则会发送一个 Nack 音讯给你,你能够进行重试操作。
音讯队列丢数据:
音讯长久化,解决音讯队列丢数据的状况,个别是开启长久化磁盘的配置:
将队列的长久化标识 durable
设置为true
,则代表是一个长久的队列 发送音讯的时候将 deliveryMode=2
这样设置当前,即便 RabbitMQ 挂了,重启后也能复原数据
消费者失落音讯:
消费者丢数据个别是因为采纳了主动确认音讯模式,改为手动确认音讯
消费者在收到音讯之后,解决音讯之前,会主动回复 RabbitMQ 已收到音讯;如果这时解决音讯失败,就会失落该音讯;
解决方案:解决音讯胜利后,手动回复确认音讯。
如何保障 RabbitMQ 音讯的程序性?
1、单线程
生产保障音讯的程序性;
2、对音讯进行 编号
,消费者解决音讯是依据编号解决音讯;
死信队列和提早队如何应用?
死信队列:
死信,顾名思义就是无奈被生产的音讯,字面意思能够这样了解,一般来说,producer 将音讯投递到 broker 或者间接到 queue 里了,consumer 从 queue 取出音讯进行生产,但某些时候因为特定的起因导致 queue 中的某些音讯无奈被生产,这样的音讯如果没有后续的解决,就变成了死信,有死信,天然就有了死信队列;
死信音讯:
1、音讯被回绝(Basic.Reject
或Basic.Nack
)并且设置 requeue 参数的值为 false
2、音讯过期了
3、队列达到最大的长度
过期音讯:
在 rabbitmq 中存在 2 种方可设置音讯的过期工夫,
- 第一种通过对队列进行设置,这种设置后,该队列中所有的音讯都存在雷同的过期工夫,
- 第二种通过对音讯自身进行设置,那么每条音讯的过期工夫都不一样。
如果同时应用这 2 种办法,那么以过期工夫小的那个数值为准。当音讯达到过期工夫还没有被生产,那么那个音讯就成为了一个 死信 音讯。
队列设置:在队列申明的时候应用 x-message-ttl
参数,单位为 毫秒
单个音讯设置:是设置音讯属性的 expiration
参数的值,单位为 毫秒
延时队列:在 rabbitmq 中不存在延时队列,然而咱们能够通过设置音讯的过期工夫和死信队列来模拟出延时队列。消费者监听死信交换器绑定的队列,而不要监听音讯发送的队列。