详解RabbitMQ消息中间件面试专题

问题一:RabbitMQ中的broker是指什么?cluster又是指什么?

:broker是指一个或多个erlangnode的逻辑分组,且node上运行着RabbitMQ应用程序。cluster是在broker的基础之上,增加了node之间共享元数据的约束。

问题二:什么是元数据?元数据分为哪些类型?包括哪些内容?与cluster相关的元数据有哪些?元数据是如何保存的?元数据在cluster中是如何分布的?

:在非cluster模式下,元数据主要分为Queue元数据(queue名字和属性等)、Exchange元数据(exchange名字、类型和属性等)、Binding元数据(存放路由关系的查找表)、Vhost元数据(vhost范围内针对前三者的名字空间约束和安全属性设置)。在cluster模式下,还包括cluster中node位置信息和node关系信息。元数据按照erlangnode的类型确定是仅保存于RAM中,还是同时保存在RAM和disk上。元数据在cluster中是全node分布的。下图所示为queue的元数据在单node和cluster两种模式下的分布图。
问题三:

RAMnode和disknode的区别?

:RAMnode仅将fabric(即queue、exchange和binding等RabbitMQ基础构件)相关元数据保存到内存中,但disknode会在内存和磁盘中均进行存储。RAMnode上唯一会存储到磁盘上的元数据是cluster中使用的disknode的地址。要求在RabbitMQcluster中至少存在一个disknode。问题四: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相关的帧。AMQP协议给出的channel复用模型如下其中每一个channel运行在一个独立的线程上,多线程共享同一个socket。

问题六:vhost是什么?起什么作用?

:vhost可以理解为虚拟broker,即mini-RabbitMQserver。其内部均含有独立的queue、exchange和binding等,但最最重要的是,其拥有独立的权限系统,可以做到vhost范围的用户控制。当然,从RabbitMQ的全局角度,vhost可以作为不同权限隔离的手段(一个典型的例子就是不同的应用可以跑在不同的vhost中)。

【cluster相关】问题七:

在单node系统和多node构成的cluster系统中声明queue、exchange,以及进行binding会有什么不同?答:当你在单node上声明queue时,只要该node上相关元数据进行了变更,你就会得到Queue.Declare-ok回应;而在cluster上声明queue,则要求cluster上的全部node都要进行元数据成功更新,才会得到Queue.Declare-ok回应。另外,若node类型为RAMnode则变更的数据仅保存在内存中,若类型为disknode则还要变更保存在磁盘上的数据。
问题八:

客户端连接到cluster中的任意node上是否都能正常工作?

:是的。客户端感觉不到有何不同。

问题九:若cluster中拥有某个queue的ownernode失效了,且该queue被声明具有durable属性,是否能够成功从其他node上重新声明该queue?

答:不能,在这种情况下,将得到404NOT_FOUND错误。只能等queue所属的node恢复后才能使用该queue。但若该queue本身不具有durable属性,则可在其他node上重新声明。
问题十:

cluster中node的失效会对consumer产生什么影响?若是在cluster中创建了mirroredqueue,这时node失效会对consumer产生什么影响?

:若是consumer所连接的那个node失效(无论该node是否为consumer所订阅queue的ownernode),则consumer会在发现TCP连接断开时,按标准行为执行重连逻辑,并根据“AssumeNothing”原则重建相应的fabric即可。若是失效的node为consumer订阅queue的ownernode,则consumer只能通过ConsumerCancellationNotification机制来检测与该queue订阅关系的终止,否则会出现傻等却没有任何消息来到的问题。
问题十一:

能够在地理上分开的不同数据中心使用RabbitMQcluster么?

:不能。第一,你无法控制所创建的queue实际分布在cluster里的哪个node上(一般使用HAProxy+cluster模型时都是这样),这可能会导致各种跨地域访问时的常见问题;第二,Erlang的OTP通信框架对延迟的容忍度有限,这可能会触发各种超时,导致业务疲于处理;第三,在广域网上的连接失效问题将导致经典的“脑裂”问题,而RabbitMQ目前无法处理(该问题主要是说Mnesia)。
【综合问题】问题十二:

为什么heavyRPC的使用场景下不建议采用disknode?

:heavyRPC是指在业务逻辑中高频调用RabbitMQ提供的RPC机制,导致不断创建、销毁replyqueue,进而造成disknode的性能问题(因为会针对元数据不断写盘)。所以在使用RPC机制时需要考虑自身的业务场景。

问题十三:向不存在的exchange发publish消息会发生什么?向不存在的queue执行consume动作会发生什么?

:都会收到Channel.Close信令告之不存在(内含原因404NOT_FOUND)。
问题十四:

routing_key和binding_key的最大长度是多少?

:255字节。
问题十五:

RabbitMQ允许发送的message最大可达多大?

:根据AMQP协议规定,消息体的大小由64-bit的值来指定,所以你就可以知道到底能发多大的数据了。

问题十六:什么情况下producer不主动创建queue是安全的?

:1.message是允许丢失的;2.实现了针对未处理消息的republish功能(例如采PublisherConfirm机制)。

问题十七:“deadletter”queue的用途?

:当消息被RabbitMQserver投递到consumer后,但consumer却通过Basic.Reject进行了拒绝时(同时设置requeue=false),那么该消息会被放入“deadletter”queue中。该queue可用于排查message被reject或undeliver的原因。
问题十八:

为什么说保证message被可靠持久化的条件是queue和exchange具有durable属性,同时message具有persistent属性才行?

:binding关系可以表示为exchange–binding–queue。从文档中我们知道,若要求投递的message能够不丢失,要求message本身设置persistent属性,要求exchange和queue都设置durable属性。其实这问题可以这么想,若exchange或queue未设置durable属性,则在其crash之后就会无法恢复,那么即使message设置了persistent属性,仍然存在message虽然能恢复但却无处容身的问题;同理,若message本身未设置persistent属性,则message的持久化更无从谈起。
问题十九:

什么情况下会出现blackholed问题?

:blackholed问题是指,向exchange投递了message,而由于各种原因导致该message丢失,但发送者却不知道。可导致blackholed的情况:1.向未绑定queue的exchange发送message;2.exchange以binding_keykey_A绑定了queuequeue_A,但向该exchange发送message使用的routing_key却是key_B。
问题二十:

如何防止出现blackholed问题?

:没有特别好的办法,只能在具体实践中通过各种方式保证相关fabric的存在。另外,如果在执行Basic.Publish时设置mandatory=true,则在遇到可能出现blackholed情况时,服务器会通过返回Basic.Return告之当前message无法被正确投递(内含原因312NO_ROUTE)。
问题二十一:

ConsumerCancellationNotification机制用于什么场景?

:用于保证当镜像queue中master挂掉时,连接到slave上的consumer可以收到自身consume被取消的通知,进而可以重新执行consume动作从新选出的master出获得消息。若不采用该机制,连接到slave上的consumer将不会感知master挂掉这个事
情,导致后续无法再收到新master广播出来的message。另外,因为在镜像queue模式下,存在将message进行requeue的可能,所以实现consumer的逻辑时需要能够正确处理出现重复message的情况。
问题二十二:

Basic.Reject的用法是什么?

:该信令可用于consumer对收到的message进行reject。若在该信令中设置requeue=true,则当RabbitMQserver收到该拒绝信令后,会将该message重新发送到下一个处于consume状态的consumer处(理论上仍可能将该消息发送给当前consumer)。若设置requeue=false,则RabbitMQserver在收到拒绝信令后,将直接将该message从queue中移除。另外一种移除queue中message的小技巧是,consumer回复Basic.Ack但不对获取到的message做任何处理。而Basic.Nack是对Basic.Reject的扩展,以支持一次拒绝多条message的能力。
问题二十三:

为什么不应该对所有的message都使用持久化机制?

:首先,必然导致性能的下降,因为写磁盘比写RAM慢的多,message的吞吐量可能有10倍的差距。其次,message的持久化机制用在RabbitMQ的内置cluster方案时会出现“坑爹”问题。矛盾点在于,若message设置了persistent属性,但queue未设置durable属性,那么当该queue的ownernode出现异常后,在未重建该queue前,发往该queue的message将被blackholed;若message设置了persistent属性,同时queue也设置了durable属性,那么当queue的ownernode异常且无法重启的情况下,则该queue无法在其他node上重建,只能等待其ownernode重启后,才能恢复该queue的使用,而在这段时间内发送给该queue的message将被blackholed。所以,是否要对message进行持久化,需要综合考虑性能需要,以及可能遇到的问题。若想达到100,000条/秒以上的消息吞吐量(单RabbitMQ服务器),则要么使用其他的方式来确保message的可靠delivery,要么使用非常快速的存储系统以支持全持久化(例如使用SSD)。另外一种处理原则是:仅对关键消息作持久化处理(根据业务重要程度),且应该保证关键消息的量不会导致性能瓶颈。

问题二十四:RabbitMQ中的cluster、mirroredqueue,以及warrens机制分别用于解决什么问题?存在哪些问题?

:cluster是为了解决当cluster中的任意node失效后,producer和consumer均可以通过其他node继续工作,即提高了可用性;另外可以通过增加node数量增加cluster的消息吞吐量的目的。cluster本身不负责message的可靠性问题(该问题由producer通过各种机制自行解决);cluster无法解决跨数据中心的问题(即脑裂问题)。另外,在cluster前使用HAProxy可以解决node的选择问题,即业务无需知道cluster中多个node的ip地址。可以利用HAProxy进行失效node的探测,可以作负载均衡。下图为HAProxy+cluster的模型。Mirroredqueue是为了解决使用cluster时所创建的queue的完整信息仅存在于单一node上的问题,从另一个角度增加可用性。若想正确使用该功能,需要保证:1.consumer需要支持ConsumerCancellationNotification机制;2.consumer必须能够正确处理重复message。

  • Warrens是为了解决cluster中message可能被blackholed的问题,即不能接受producer不停republishmessage但RabbitMQserver无回应的情况。Warrens有两种构成方式,一种模型是两台独立的RabbitMQserver+HAProxy,其中两个server的状态分别为active和hot-standby。该模型的特点为:两台server之间无任何数据共享和协议交互,两台server可以基于不同的RabbitMQ版本。

  • 另一种模型为两台共享存储的RabbitMQserver+keepalived,其中两个server的状态分别为active和cold-standby。该模型的特点为:两台server基于共享存储可以做到完全恢复,要求必须基于完全相同的RabbitMQ版本。

  • Warrens模型存在的问题:对于第一种模型,虽然理论上讲不会丢失消息,但若在该模型上使用持久化机制,就会出现这样一种情况,即若作为active的server异常后,持久化在该server上的消息将暂时无法被consume,因为此时该queue将无法在作为hot-standby的server上被重建,所以,只能等到异常的activeserver恢复后,才能从其上的queue中获取相应的message进行处理。而对于业务来说,需要具有:a.感知AMQP连接断开后重建各种fabric的能力;b.感知activeserver恢复的能力;c.切换回activeserver的时机控制,以及切回后,针对message先后顺序产生的变化进行处理的能力。对于第二种模型,因为是基于共享存储的模式,所以导致activeserver异常的条件,可能同样会导致cold-standbyserver异常;另外,在该模型下,要求active和cold-standby的server必须具有相同的node名和UID,否则将产生访问权限问题;最后,由于该模型是冷备方案,故无法保证cold-standbyserver能在你要求的时限内成功启动。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 222,104评论 6 515
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,816评论 3 399
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 168,697评论 0 360
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,836评论 1 298
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,851评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,441评论 1 310
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,992评论 3 421
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,899评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,457评论 1 318
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,529评论 3 341
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,664评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,346评论 5 350
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 42,025评论 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,511评论 0 24
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,611评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 49,081评论 3 377
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,675评论 2 359

推荐阅读更多精彩内容