热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

amqp协议面试_二十四个RabbitMQ消息中间件面试题及答案(双手奉上,拿走不行)...

问题一:RabbitMQ中的broker是指什么?cluster又是指什么?答:broker是指一个或多个erlangnod

问题一: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 相

关的帧。AMQP 协议给出的 channel 复用模型如下

其中每一个 channel 运行在一个独立的线程上,多线程共享同一个 socket。

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

答:vhost 可以理解为虚拟 broker ,即 mini-RabbitMQ server。其内部均含有独立的

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 类型

为 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 动作会发生什么?

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

问题十四:routing_key 和 binding_key 的最大长度是多少?

答:255 字节。

问题十五:RabbitMQ 允许发送的 message 最大可达多大?

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

能发多大的数据了。

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

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

Publisher Confirm 机制)。

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

答:当消息被 RabbitMQ server 投递到 consumer 后,但 consumer 却通过 Basic.Reject

进行了拒绝时(同时设置 requeue=false),那么该消息会被放入“dead letter”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_key key_A 绑定了 queue queue_A,但向

该 exchange 发送 message 使用的 routing_key 却是 key_B。

问题二十:如何防止出现 blackholed 问题?

答:没有特别好的办法,只能在具体实践中通过各种方式保证相关 fabric 的存在。另外,

如果在执行 Basic.Publish 时设置 mandatory=true ,则在遇到可能出现 blackholed 情况

时,服务器会通过返回 Basic.Return 告之当前 message 无法被正确投递(内含原因 312

NO_ROUTE)。

问题二十一:Consumer Cancellation Notification 机制用于什么场景?

答:用于保证当镜像 queue 中 master 挂掉时,连接到 slave 上的 consumer 可以收到自

身 consume 被取消的通知,进而可以重新执行 consume 动作从新选出的 master 出获得

消息。若不采用该机制,连接到 slave 上的 consumer 将不会感知 master 挂掉这个事

情,导致后续无法再收到新 master 广播出来的 message 。另外,因为在镜像 queue 模

式下,存在将 message 进行 requeue 的可能,所以实现 consumer 的逻辑时需要能够正

确处理出现重复 message 的情况。

问题二十二:Basic.Reject 的用法是什么?

答:该信令可用于 consumer 对收到的 message 进行 reject 。若在该信令中设置

requeue=true,则当 RabbitMQ server 收到该拒绝信令后,会将该 message 重新发送到下

一个处于 consume 状态的 consumer 处(理论上仍可能将该消息发送给当前

consumer)。若设置 requeue=false ,则 RabbitMQ server 在收到拒绝信令后,将直接将该

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 的 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 上的问题,从另一个角度增加可用性。若想正确使用该功能,需要保证:1.consumer

需要支持 Consumer Cancellation Notification 机制;2.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 能在你要求的时限内成功启动。



推荐阅读
  • 本文详细介绍了Java代码分层的基本概念和常见分层模式,特别是MVC模式。同时探讨了不同项目需求下的分层策略,帮助读者更好地理解和应用Java分层思想。 ... [详细]
  • 解决Bootstrap DataTable Ajax请求重复问题
    在最近的一个项目中,我们使用了JQuery DataTable进行数据展示,虽然使用起来非常方便,但在测试过程中发现了一个问题:当查询条件改变时,有时查询结果的数据不正确。通过FireBug调试发现,点击搜索按钮时,会发送两次Ajax请求,一次是原条件的请求,一次是新条件的请求。 ... [详细]
  • 如何利用Java 5 Executor框架高效构建和管理线程池
    Java 5 引入了 Executor 框架,为开发人员提供了一种高效管理和构建线程池的方法。该框架通过将任务提交与任务执行分离,简化了多线程编程的复杂性。利用 Executor 框架,开发人员可以更灵活地控制线程的创建、分配和管理,从而提高服务器端应用的性能和响应能力。此外,该框架还提供了多种线程池实现,如固定线程池、缓存线程池和单线程池,以适应不同的应用场景和需求。 ... [详细]
  • 在JavaWeb项目架构中,NFS(网络文件系统)的实现与优化是关键环节。NFS允许不同主机系统通过局域网共享文件和目录,提高资源利用率和数据访问效率。本文详细探讨了NFS在JavaWeb项目中的应用,包括配置、性能优化及常见问题的解决方案,旨在为开发者提供实用的技术参考。 ... [详细]
  • (1)前期知识:1. 单机架构:单一服务器计算机——其处理能力和存储容量有限。2. 集群架构(负载均衡器与多节点服务器)——通过增加节点数量来提升系统性能和可靠性,实现高效的任务分配和资源利用。 ... [详细]
  • 第二章:Kafka基础入门与核心概念解析
    本章节主要介绍了Kafka的基本概念及其核心特性。Kafka是一种分布式消息发布和订阅系统,以其卓越的性能和高吞吐量而著称。最初,Kafka被设计用于LinkedIn的活动流和运营数据处理,旨在高效地管理和传输大规模的数据流。这些数据主要包括用户活动记录、系统日志和其他实时信息。通过深入解析Kafka的设计原理和应用场景,读者将能够更好地理解其在现代大数据架构中的重要地位。 ... [详细]
  • 深入解析Spring Boot启动过程中Netty异步架构的工作原理与应用
    深入解析Spring Boot启动过程中Netty异步架构的工作原理与应用 ... [详细]
  • 2019年后蚂蚁集团与拼多多面试经验详述与深度剖析
    2019年后蚂蚁集团与拼多多面试经验详述与深度剖析 ... [详细]
  • 本文深入探讨了 Spring Cloud 微服务架构中 Gateway 组件的应用,详细介绍了其在实现高效请求路由与过滤方面的关键作用。文章首先从基本配置入手,逐步讲解了如何通过静态路由和动态路由实现灵活的服务访问控制。此外,还特别介绍了如何配置 Gateway 以自动从 Nacos 服务注册中心拉取服务列表,进一步提升系统的可维护性和扩展性。 ... [详细]
  • IIS 7及7.5版本中应用程序池的最佳配置策略与实践
    在IIS 7及7.5版本中,优化应用程序池的配置是提升Web站点性能的关键步骤。具体操作包括:首先定位到目标Web站点的应用程序池,然后通过“应用程序池”菜单找到对应的池,右键选择“高级设置”。在一般优化方案中,建议调整以下几个关键参数:1. **基本设置**: - **队列长度**:默认值为1000,可根据实际需求调整队列长度,以提高处理请求的能力。此外,还可以进一步优化其他参数,如处理器使用限制、回收策略等,以确保应用程序池的高效运行。这些优化措施有助于提升系统的稳定性和响应速度。 ... [详细]
  • ZeroMQ在云计算环境下的高效消息传递库第四章学习心得
    本章节深入探讨了ZeroMQ在云计算环境中的高效消息传递机制,涵盖客户端请求-响应模式、最近最少使用(LRU)队列、心跳检测、面向服务的队列、基于磁盘的离线队列以及主从备份服务等关键技术。此外,还介绍了无中间件的请求-响应架构,强调了这些技术在提升系统性能和可靠性方面的应用价值。个人理解方面,ZeroMQ通过这些机制有效解决了分布式系统中常见的通信延迟和数据一致性问题。 ... [详细]
  • 综合实训 201521440015
    Chinesepeople’publicsecurityuniversity网络对抗技术实验报告实验五综合渗透学生姓名常泽远年级15区队4指导教师高见信息技术与网络安全学院2018 ... [详细]
  • 目录RPC是什么RPC的优点RPC的缺点RPC是什么RPC(RemoteProcedureCall)isaprotocolthatoneprogramcanusetorequest ... [详细]
  • Dubbo的集群容错策略正常情况下,当我们进行系统设计时候,不仅要考虑正常逻辑下代码该如何走,还要考虑异常情况下代码逻辑应该怎么走。当服务 ... [详细]
  • 基于Net Core 3.0与Web API的前后端分离开发:Vue.js在前端的应用
    本文介绍了如何使用Net Core 3.0和Web API进行前后端分离开发,并重点探讨了Vue.js在前端的应用。后端采用MySQL数据库和EF Core框架进行数据操作,开发环境为Windows 10和Visual Studio 2019,MySQL服务器版本为8.0.16。文章详细描述了API项目的创建过程、启动步骤以及必要的插件安装,为开发者提供了一套完整的开发指南。 ... [详细]
author-avatar
手机用户2502934875
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有