答:broker 是指一个或多个 erlang node
的逻辑分组,且 node 上运行着 RabbitMQ
应用程序。cluster 是在 broker 的基础之上,增加了 node 之间共享元数据的约束。
问题二:什么是元数据?元数据分为哪些类型?包括哪些内容?与 cluster 相关的元数据有哪些?元数据是如何保存的?元数据在 cluster 中是如何分布的?
答:在非 cluster
模式下,元数据主要分为 Queue
元数据(queue
名字和属性等)、Exchange 元数据(exchange
名字、类型和属性等)、Binding 元数据(存放路由关系的查找表)、Vhost 元数据(vhost
范围内针对前三者的名字空间约束和安全属性设置)。在 cluster
模式下,还包括 cluster
中 node 位置信息和 node 关系信息。元数据按照 erlang node
的类型确定是仅保存于 RAM 中,还是同时保存在 RAM 和 disk 上。元数据在 cluster
中是全 node
分布的。
问题三:RabbitMQ 概念里的 channel、exchange 和 queue 这些东东是逻辑概念,还是对应着进程实体?这些东东分别起什么作用?
答:queue
具有自己的 erlang
进程;exchange
内部实现为保存 binding
关系的查找表;channel
是实际进行路由工作的实体,即负责按照 routing_key
将 message
投递给 queue
。由 AMQP
协议描述可知,channel
是真实 TCP
连接之上的虚拟连接,所有 AMQP
命令都是通过 channel
发送的,且每一个 channel
有唯一的 ID
。一个 channel
只能被单独一个操作系统线程使用,故投递到特定 channel
上的 message
是有顺序的。但一个操作系统线程上允许使用多个 channel
。channel
号为 0 的 channel
用于处理所有对于当前 connection
全局有效的帧,而 1-65535 号 channel
用于处理和特定 channel
相关的帧。
其中每一个 channel
运行在一个独立的线程上,多线程共享同一个 socket
。
问题四:vhost 是什么?起什么作用?
答:vhost
可以理解为虚拟 broker ,即 mini-RabbitMQ server
。其内部均含有独立的 queue
、exchange
和 binding
等,但最最重要的是,其拥有独立的权限系统,可以做到 vhost
范围的用户控制。当然,从 RabbitMQ 的全局角度,vhost
可以作为不同权限隔离的手段(一个典型的例子就是不同的应用可以跑在不同的 vhost
中)。
问题五:若 cluster 中拥有某个 queue 的 owner node 失效了,且该 queue 被声明具有 durable 属性,是否能够成功从其他 node 上重新声明该 queue ?
答:不能,在这种情况下,将得到 404 NOT_FOUND
错误。只能等 queue
所属的 node
恢复后才能使用该 queue
。但若该 queue
本身不具有 durable
属性,则可在其他 node
上重新声明。
问题六:能够在地理上分开的不同数据中心使用 RabbitMQ cluster 么?
答:不能。第一,你无法控制所创建的 queue
实际分布在 cluster
里的哪个 node
上(一般使用 HAProxy + cluster
模型时都是这样),这可能会导致各种跨地域访问时的常见问题;第二,Erlang
的 OTP 通信框架对延迟的容忍度有限,这可能会触发各种超时,导致业务疲于处理;第三,在广域网上的连接失效问题将导致经典的“脑裂”问题,而 RabbitMQ 目前无法处理(该问题主要是说 Mnesia
)。
问题七:为什么 heavy RPC 的使用场景下不建议采用 disk node ?
答:heavy RPC
是指在业务逻辑中高频调用 RabbitMQ 提供的 RPC 机制,导致不断创建、销毁 reply queue
,进而造成 disk node
的性能问题(因为会针对元数据不断写盘)。所以在使用 RPC 机制时需要考虑自身的业务场景。
问题八:Basic.Reject 的用法是什么?
答:该信令可用于 consumer
对收到的 message
进行 reject
。若在该信令中设置 requeue=true
,则当 RabbitMQ server 收到该拒绝信令后,会将该 message
重新发送到下一个处于 consume
状态的 consumer
处(理论上仍可能将该消息发送给当前 consumer
)。若设置 requeue=false
,则 RabbitMQ server 在收到拒绝信令后,将直接将该 message
从 queue
中移除。
问题九:为什么不应该对所有的 message 都使用持久化机制?
答:首先,必然导致性能的下降,因为写磁盘比写 RAM 慢的多,message
的吞吐量可能有 10 倍的差距。其次,message
的持久化机制用在 RabbitMQ 的内置 cluster
方案时会出现“坑爹”问题。矛盾点在于,若 message
设置了 persistent
属性,但 queue
未设置 durable
属性,那么当该 queue
的 owner node
出现异常后,在未重建该 queue
前,发往该 queue
的 message
将被 blackholed
;若 message
设置了 persistent
属性,同时 queue
也设置了 durable
属性,那么当 queue
的 owner node
异常且无法重启的情况下,则该 queue
无法在其他 node
上重建,只能等待其 owner node
重启后,才能恢复该 queue
的使用,而在这段时间内发送给该 queue
的 message
将被 blackholed
。所以,是否要对 message
进行持久化,需要综合考虑性能需要,以及可能遇到的问题。若想达到 100,000 条/秒以上的消息吞吐量(单 RabbitMQ 服务器),则要么使用其他的方式来确保 message
的可靠 delivery
,要么使用非常快速的存储系统以支持全持久化(例如使用 SSD
)。另外一种处理原则是:仅对关键消息作持久化处理(根据业务重要程度),且应该保证关键消息的量不会导致性能瓶颈。
问题十:RabbitMQ 中的 cluster、mirrored queue,以及 warrens 机制分别用于解决什么问题?存在哪些问题?
答:cluster
是为了解决当cluster
中的任意 node
失效后,producer
和 consumer
均可以通过其他 node
继续工作,即提高了可用性;另外可以通过增加 node
数量增加 cluster
的消息吞吐量的目的。cluster
本身不负责 message
的可靠性问题(该问题由 producer
通过各种机制自行解决);cluster
无法解决跨数据中心的问题(即脑裂问题)。另外,在 cluster
前使用 HAProxy
可以解决 node
的选择问题,即业务无需知道 cluster
中多个 node
的 ip 地址。可以利用 HAProxy
进行失效 node
的探测,可以作负载均衡。下图为 HAProxy + cluster
的模型。
Mirrored queue 是为了解决使用 cluster 时所创建的 queue 的完整信息仅存在于单一 node 上的问题,从另一个角度增加可用性。若想正确使用该功能,需要保证:
consumer
需要支持Consumer Cancellation Notification
机制;consumer
必须能够正确处理重复message
。
Warrens 是为了解决 cluster
中 message
可能被 blackholed
的问题,即不能接受 producer
不停 republish message
但 RabbitMQ server 无回应的情况。Warrens 有两种构成方式,一种模型是两台独立的 RabbitMQ server + HAProxy ,其中两个 server
的状态分别为 active
和 hot-standby
。该模型的特点为:两台 server
之间无任何数据共享和协议交互,两台 server
可以基于不同的 RabbitMQ 版本。
另一种模型为两台共享存储的 RabbitMQ server + keepalived
,其中两个 server
的状态分别为 active
和 cold-standby
。该模型的特点为:两台 server
基于共享存储可以做到完全恢复,要求必须基于完全相同的 RabbitMQ 版本。
Warrens 模型存在的问题:对于第一种模型,虽然理论上讲不会丢失消息,但若在该模型上使用持久化机制,就会出现这样一种情况,即若作为 active
的 server
异常后,持久化在该 server
上的消息将暂时无法被 consume
,因为此时该 queue
将无法在作为 hot-standby
的 server
上被重建,所以,只能等到异常的 active server
恢复后,才能从其上的 queue
中获取相应的 message
进行处理。而对于业务来说,需要具有:a.感知 AMQP 连接断开后重建各种 fabric
的能力;b.感知 active server
恢复的能力;c.切换回 active server
的时机控制,以及切回后,针对 message
先后顺序产生的变化进行处理的能力。对于第二种模型,因为是基于共享存储的模式,所以导致 active server
异常的条件,可能同样会导致 cold-standby server
异常;另外,在该模型下,要求 active
和 cold-standby
的 server
必须具有相同的 node
名和 UID
,否则将产生访问权限问题;最后,由于该模型是冷备方案,故无法保证 cold-standby server
能在你要求的时限内成功启动。
写在最后
不在在因为等一会,让自己错过一次又一次的机会,任何机遇都伴有风险,只有不断前行才能取得成功!
最后
即使是面试跳槽,那也是一个学习的过程。只有全面的复习,才能让我们更好的充实自己,武装自己,为自己的面试之路不再坎坷!今天就给大家分享一个Github上全面的Java面试题大全,就是这份面试大全助我拿下大厂Offer,月薪提至30K!
CodeChina开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频】
我也是第一时间分享出来给大家,希望可以帮助大家都能去往自己心仪的大厂!为金三银四做准备!
一共有20个知识点专题,分别是:
Dubbo面试专题
JVM面试专题
Java并发面试专题
Kafka面试专题
MongDB面试专题
MyBatis面试专题
MySQL面试专题
Netty面试专题
RabbitMQ面试专题
Redis面试专题
Spring Cloud面试专题
SpringBoot面试专题
zookeeper面试专题
常见面试算法题汇总专题
计算机网络基础专题
设计模式专题
]
计算机网络基础专题
[外链图片转存中…(img-ORRTfl57-1630490684181)]
设计模式专题
[外链图片转存中…(img-oi87icCn-1630490684182)]