问题一:RabbitMQ 中的 broker 是指什么?cluster 又是指什么?
答:
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
分布的。
问题三:RAM node 和 disk node 的区别?
答:
RAM node
仅将
fabric
(即
queue
、
exchange
和
binding
等
RabbitMQ
基础构件)相
关元数据保存到内存中,但
disk node
会在内存和磁盘中均进行存储。
RAM node
上唯一
会存储到磁盘上的元数据是
cluster
中使用的
disk node
的地址。要求在
RabbitMQ cluster
中至少存在一个
disk node
。
问题四:RabbitMQ 上的一个 queue 中存放的 message 是否有数量限制?
答:可以认为是无限制,因为限制取决于机器的内存,但是消息过多会导致处理效率的下
降。
问题五: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
相
关的帧。
问题六:vhost 是什么?起什么作用?
答:
vhost
可以理解为虚拟
broker
,即
mini-RabbitMQ server
。其内部均含有独立的
queue
、
exchange
和
binding
等,但最最重要的是,其拥有独立的权限系统,可以做到
vhost
范围的用户控制。当然,从
RabbitMQ
的全局角度,
vhost
可以作为不同权限隔离
的手段(一个典型的例子就是不同的应用可以跑在不同的
vhost
中)。
问题七:在单 node 系统和多 node 构成的 cluster 系统中声明 queue、exchange ,以及进行 binding 会有什么不同?
答:当你在单
node
上声明
queue
时,只要该
node
上相关元数据进行了变更,你就会
得到
Queue.Declare-ok
回应;而在
cluster
上声明
queue
,则要求
cluster
上的全部
node
都要进行元数据成功更新,才会得到
Queue.Declare-ok
回应。另外,若
node
类型
为
RAM node
则变更的数据仅保存在内存中,若类型为
disk node
则还要变更保存在磁盘
上的数据。
问题八:客户端连接到 cluster 中的任意 node 上是否都能正常工作?
答:是的。客户端感觉不到有何不同。
问题九:若 cluster 中拥有某个 queue 的 owner node 失效了,且该 queue 被声明具有durable 属性,是否能够成功从其他 node 上重新声明该 queue ?
答:不能,在这种情况下,将得到
404 NOT_FOUND
错误。只能等
queue
所属的
node
恢复后才能使用该
queue
。但若该
queue
本身不具有
durable
属性,则可在其他
node
上重新声明。
问题十:cluster 中 node 的失效会对 consumer 产生什么影响?若是在 cluster 中创建了mirrored queue ,这时 node 失效会对 consumer 产生什么影响?
答:若是
consumer
所连接的那个
node
失效(无论该
node
是否为
consumer
所订阅
queue
的
owner node
),则
consumer
会在发现
TCP
连接断开时,按标准行为执行重连
逻辑,并根据“
Assume Nothing
”原则重建相应的
fabric
即可。若是失效的
node
为
consumer
订阅
queue
的
owner node
,则
consumer
只能通过
Consumer Cancellation
Notification
机制来检测与该
queue
订阅关系的终止,否则会出现傻等却没有任何消息来
到的问题。
问题十一:能够在地理上分开的不同数据中心使用 RabbitMQ cluster 么?
答:不能。第一,你无法控制所创建的
queue
实际分布在
cluster
里的哪个
node
上(一
般使用
HAProxy + cluster
模型时都是这样),这可能会导致各种跨地域访问时的常见问
题;第二,
Erlang
的
OTP
通信框架对延迟的容忍度有限,这可能会触发各种超时,导致
业务疲于处理;第三,在广域网上的连接失效问题将导致经典的“脑裂”问题,而
RabbitMQ
目前无法处理(该问题主要是说
Mnesia
)。
问题十二:为什么 heavy RPC 的使用场景下不建议采用 disk node ?
答:
heavy RPC
是指在业务逻辑中高频调用
RabbitMQ
提供的
RPC
机制,导致不断创建、
销毁
reply queue
,进而造成
disk node
的性能问题(因为会针对元数据不断写盘)。所以
在使用
RPC
机制时需要考虑自身的业务场景。
问题十三:向不存在的 exchange 发 publish 消息会发生什么?向不存在的 queue 执行consume 动作会发生什么?
问题十四:routing_key 和 binding_key 的最大长度是多少?
问题十五:RabbitMQ 允许发送的 message 最大可达多大?
问题十六:什么情况下 producer 不主动创建 queue 是安全的?
问题十七:“dead letter”queue 的用途?
问题十八:为什么说保证 message 被可靠持久化的条件是 queue 和 exchange 具有durable 属性,同时 message 具有 persistent 属性才行?
问题十九:什么情况下会出现 blackholed 问题?
问题二十:如何防止出现 blackholed 问题?
问题二十一:Consumer Cancellation Notification 机制用于什么场景?
问题二十二:Basic.Reject 的用法是什么?
问题二十三:为什么不应该对所有的 message 都使用持久化机制?
问题二十四:RabbitMQ 中的 cluster、mirrored queue,以及 warrens 机制分别用于解决什么问题?存在哪些问题?
答案如下:
再来看一张RabbitMQ的学习大纲,不好展示,可以直接点击这里下载原图。
更多关于Java集合、JVM、多线程并发、spring原理、微服务、Netty 与RPC 、Kafka、日记、设计模式、Java算法、数据库、Zookeeper、分布式缓存、数据结构面试解析等等可以去这个Github链接地址:https://github.com/ThinkingHan/Java-note 阅读,Star一下吧,感谢支持~