RabbitMQ常见面试题

0    367    1

Tags:

👉 本文共约9394个字,系统预计阅读时间或需36分钟。

目录

MQ如何选型?

特性ActiveMQRabbitMQRocketMQKafka
客户端支持语言JAVA、C、C++、Python、PHP、Pert、net等官方支持Erlang、Java/Ruby等,社区产出多种语言API,几乎支持所有常用语言JAVA、C++(不成熟)官方支持JAVA,开源社区有多语言版本,如PHP,Python,GO,C/C++,Ruby,NodeJS等编程语言
单机吞吐量万级,吞吐量RocketMQ和Kafka要低了一个数量级万级,吞吐量比RocketMQ和Kafka要低了一个数量级10万级,RocketMQ也是可以支撑高吞吐的一种MQ10万级别,这是kafka最大的优点,就是吞吐量高。 一般配合大数据类的系统来进行实时数据计算、日志采集等场景
topic数量对吞吐量的影响topic可以达到几百,几千个的级别,吞吐量会有较小幅度的下降 这是RocketMQ的一大优势,在同等机器下,可以支撑大量的topictopic从几十个到几百个的时候,吞吐量会大幅度下降 所以在同等机器下,kafka尽量保证topic数量不要过多。如果要支撑大规模topic,需要增加更多的机器资源
时效性ms级微秒级,这是rabbitmq的一大特点,延迟是最低的ms级延迟在ms级以内
可用性高,基于主从架构实现高可用性高,基于主从架构实现高可用性非常高,分布式架构非常高,kafka是分布式的,一个数据多个副本,少数机器宕机,不会丢失数据,不会导致不可用
消息可靠性有较低的概率丢失数据经过参数优化配置,可以做到0丢失经过参数优化配置,消息可以做到0丢失
持久化内存、文件、数据库内存、文件,支持数据堆积,但数据堆积会影响生产速率磁盘文件磁盘文件,只要磁盘容量足够,可以做到无限消息堆积
功能支持MQ领域的功能极其完备基于erlang开发,所以并发能力很强,性能极其好,延时很低MQ功能较为完善,还是分布式的,扩展性好功能较为简单,主要支持简单的MQ功能,在大数据领域的实时计算以及日志采集被大规模使用,是事实上的标准
  1. 中小型公司首选 RabbitmQ:管理界面简单,高并发。
  2. 大型公司可以选择 RocketMQ:更高并发,可对 rocket进行定制化开发。
  3. 日志采集功能,首选 kafka,专为大数据准备。

RabbitMQ是什么?

RabbitMQ是实现了高级消息队列协议(AMQP)的开源消息代理软件(亦称面向消息的中间件)。RabbitMQ服务器是用Erlang语言编写的,而群集和故障转移是构建在开放电信平台框架上的。所有主要的编程语言均有与代理接口通讯的客户端库。

RabbitMQ特点

可靠性: RabbitMQ使用一些机制来保证可靠性, 如持久化、传输确认及发布确认等。

灵活的路由 : 在消息进入队列之前,通过交换器来路由消息。对于典型的路由功能, RabbitMQ 己经提供了一些内置的交换器来实现。针对更复杂的路由功能,可以将多个 交换器绑定在一起, 也可以通过插件机制来实现自己的交换器。

扩展性: 多个RabbitMQ节点可以组成一个集群,也可以根据实际业务情况动态地扩展 集群中节点。

高可用性 : 队列可以在集群中的机器上设置镜像,使得在部分节点出现问题的情况下队 列仍然可用。

多种协议: RabbitMQ除了原生支持AMQP协议,还支持STOMP, MQTT等多种消息 中间件协议。

多语言客户端 :RabbitMQ 几乎支持所有常用语言,比如 Java、 Python、 Ruby、 PHP、 C#、 JavaScript 等。

管理界面 : RabbitMQ 提供了一个易用的用户界面,使得用户可以监控和管理消息、集 群中的节点等。

令插件机制 : RabbitMQ 提供了许多插件 , 以实现从多方面进行扩展,当然也可以编写自 己的插件。

使用 RabbitmQ有什么好处?

  1. 应用解耦(系统拆分)
  2. 异步处理(预约挂号业务处理成功后,异步发送短信、推送消息、日志记录等,可以大大减小响应)
  3. 消息分发
  4. 流量削峰:将请求发送到队列中,短暂的高峰期积压是允许的。
  5. 消息缓冲

AMQP是什么

RabbitMQ就是 AMQP 协议的 Erlang 的实现(当然 RabbitMQ 还支持 STOMP2MQTT3 等协议 ) AMQP 的模型架构 和 RabbitMQ 的模型架构是一样的,生产者将消息发送给交换器,交换器和队列绑定 。

RabbitMQ 中的交换器、交换器类型、队列、绑定、路由键等都是遵循的 AMQP 协议中相 应的概念。目前 RabbitMQ 最新版本默认支持的是 AMQP 0-9-1。

AMQP协议3层

Module Layer:协议最高层,主要定义了一些客户端调用的命令,客户端可以用这些命令实现自己的业务逻辑。

Session Layer:中间层,主要负责客户端命令发送给服务器,再将服务端应答返回客户端,提供可靠性同步机制和错误处理。

TransportLayer:最底层,主要传输二进制数据流,提供帧的处理、信道服用、错误检测和数据表示等。

AMQP模型的几大组件

  • 交换器 (Exchange):消息代理服务器中用于把消息路由到队列的组件。
  • 队列 (Queue):用来存储消息的数据结构,位于硬盘或内存中。
  • 绑定 (Binding):一套规则,告知交换器消息应该将消息投递给哪个队列。

消息如何分发?

若该队列⾄少有⼀个消费者订阅,消息将以循环(round-robin)的⽅式发送给消费者。每条消息只会分发给⼀个订阅的消费者(前提是消费者能够正常处理消息并进⾏确认)。

RabbitMQ routing 路由模式

img

1、 消息生产者将消息发送给交换机按照路由判断,路由是字符串(info) 当前产生的消息携带路由字符(对象的方法),交换机根据路由的 key,只能匹配上路由 key 对应的消息队列,对应的消费者才能消费消息。

2、 根据业务功能定义路由字符串。

3、 从系统的代码逻辑中获取对应的功能字符串,将消息任务扔到对应的队列中。

4、 业务场景:error 通知、EXCEPTION、错误通知的功能、传统意义的错误通知、客户通知、利用 key 路由,可以将程序中的错误封装成消息传入到消息队列中,开发者可以自定义消费者,实时接收错误。

消息怎么路由?

消息提供方->路由->一至多个队列消息发布到交换器时,消息将拥有一个路由键(routing key),在消息创建时设定。通过队列路由键,可以把队列绑定到交换器上。消息到达交换器后,RabbitMQ 会将消息的路由键与队列的路由键进行匹配(针对不同的交换器有不同的路由规则)。

常用的交换器主要分为一下三种:

  • fanout:如果交换器收到消息,将会广播到所有绑定的队列上。
  • direct:如果路由键完全匹配,消息就被投递到相应的队列。
  • topic:可以使来自不同源头的消息能够到达同一个队列。 使用 topic 交换器时,可以使用通配符。

RabbitMQ publish/subscribe 发布订阅(共享资源)

img

每个消费者监听自己的队列。

生产者将消息发给 broker,由交换机将消息转发到绑定此交换机的每个队列,每个绑定交换机的队列都将接收到消息。

RabbitMQ 中的 broker 是指什么?cluster 又是指什么?

broker 是指一个或多个 erlang node 的逻辑分组,且 node 上运行着 RabbitMQ 应用程序。

cluster 是在 broker 的基础之上,增加了 node 之间共享元数据的约束。

什么是元数据?元数据分为哪些类型?包括哪些内容?与 cluster 相关的元数据有哪些?

在非 cluster 模式下,元数据主要分为:

Queue 元数据(queue 名字和属性等)

Exchange 元数据(exchange 名字、类型和属性等)

Binding 元数据(存放路由关系的查找表)

Vhost 元数据(vhost 范围内针对前三者的名字空间约束和安全属性设置)

在cluster 模式下,还包括: cluster 中 node 位置信息和 node 关系信息。

元数据是如何保存的?

元数据按照 erlangnode 的类型确定是仅保存于 RAM 中,还是同时保存在 RAM 和 disk 上。

img

元数据在 cluster 中是如何分布的?

元数据在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 相关的帧。其中每一个 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上重新声明。

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 CancellationNotification 机制来检测与该 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 机制时需要考虑自身的业务场景。

本人提供Oracle(OCP、OCM)、MySQL(OCP)、PostgreSQL(PGCA、PGCE、PGCM)等数据库的培训和考证业务,私聊QQ646634621或微信dbaup66,谢谢!
AiDBA后续精彩内容已被站长无情隐藏,请输入验证码解锁本文!
验证码:
获取验证码: 请先关注本站微信公众号,然后回复“验证码”,获取验证码。在微信里搜索“AiDBA”或者“dbaup6”或者微信扫描右侧二维码都可以关注本站微信公众号。

标签:

Avatar photo

小麦苗

学习或考证,均可联系麦老师,请加微信db_bao或QQ646634621

您可能还喜欢...

发表回复