我们一起来学RabbitMQ 五:RabbitMQ 应知应会的面

2021-10-15  本文已影响0人  阿兵云原生

我们一起来学RabbitMQ 五:RabbitMQ 应知应会的面试题

MQ 是什么?

MQ(Message Queue)消息队列

用队列机制来实现软件之间的通信,消费者可以到指定队列拉取消息,或者订阅相应的队列,由MQ服务端给其推送消息

什么是队列?

是一种数据结构,遵循 FIFO (先进先出)原则

凭啥要使用 MQ , MQ 有啥优势?

将以前也不中不必要的同步操作,优化成异步操作,提高性能

将原有A模块直接调用B模块的接口,优化成,A模块的请求给到MQ,A模块的事情就做完了

MQ会主动推给B模块,或者B模块自己来拉

当某一时间大量的流量打到服务器上,服务器一时间无法承受,会宕机

这个时候,若请求都是从消息队列里面出来,则能够保证这种大流量的情况下,服务器仍然能够有序的稳定的处理请求

MQ 有啥劣势呢?

常用 MQ 性能对比

ActiveMQ RabbitMQ RocketMQ Kafka
开发语言 java erlang java scala
单机吞吐量 万级 万级 十万级 十万级
时效性 ms级 us级 ms级 ms级以内
可用性 高<br />主从架构 高<br />主从架构 非常高<br />分布式架构 非常高<br />分布式架构
消息可靠性 较低概率丢失消息 基本不丢 可以做到基本不丢 可以做到基本不丢
功能支持 支持功能全 性能好<br />延时低<br />并发能力强 MQ 功能较完善<br />支持分布式,扩展性好 主要用于大数据和日志采集

MQ 如何避免消息堆积

MQ 如何避免消费者重复消费(幂等性问题)

MQ 如何保证消息不丢失

MQ 如何保证消息顺序一致性

MQ 推与拉取架构模型是怎么样的?

mq有哪些消费模式

消费者消费消息的时候,将自动向RabbitMQ进行确认。

消费者消费消息的时候,手动调用相应函数进行ack 应答

在确认消息被接收之前,消费者可以预先要求接收一定数量的消息,在处理完一定数量的消息后,批量进行确认

当然,如果消费者应用程序在确认消息之前崩溃,则所有未确认的消息将被重新发送给其他消费者

RabbitMQ 中既然有了connections 为什么还要有 channel

connection 是什么

connection 是 生产者或消费者与 RabbitMQ Broker 建立的连接,是一个TCP连接

一旦 TCP 连接建立起来,客户端紧接着可以创建一个 AMQP 信道(Channel),每个信道都会被指派一个唯一的 ID

信道是建立在 Connection 之上的虚拟连接,多个信道复用一个TCP连接,可以减少性能开销,同时也便于管理

因为一个应用需要向RabbitMQ 中生成或者消费消息的话,都要建一个TCP连接,TCP连接开销非常大,如果遇到使用高峰,性能瓶颈也随之显现

信道复用连接优势:

image

当每个信道的流量不是很大时,复用单一的 Connection 可以在产生性能瓶颈的情况下有效地节省 TCP 连接资源

信道本身的流量很大时,这时候多个信道复用一个 Connection 就会产生性能瓶颈,进而使整体的流量被限制了,此时就需要开辟多个 Connection,将这些信道均摊到这些 Connection 中

RabbitMQ 的作用

为什么选择 RabbitMQ

现在的市面上有很多 MQ 可以选择,比如 ActiveMQ、ZeroMQ、Appche Qpid为什么要选择 RabbitMQ

RabbitMQ 的特点是什么?

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

通过交换器来路由消息

对于典型的路由功能, RabbitMQ 己经提供了一些内置的交换器来实现

针对更复杂的路由功能,可以将多个 交换器绑定在一起,这个就需要通过插件来实现了

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

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

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

RabbitMQ 几乎支持所有常用语言,比如 GO、 Java、 Python、 Ruby、 PHP等

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

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

生产者Producer和消费者Consumer 有哪些知识点?

生产者

消费者

RabbitMQ 消息持久化中的坑

默认情况下重启服务器会导致消息丢失,我们如何保证重启 RabbitMQ 不丢失数据?

那就是做持久化,持久化需要满足如下三个条件才可以恢复 RabbitMQ 的数据

持久化的工作原理

Rabbit 会将持久化消息写入磁盘上的持久化日志文件,等消息被消费之后,Rabbit 会把这条消息标识为等待垃圾回收

持久化的优缺点

优点

缺点

RabbitMQ ACK 应答机制

ACK 应答分为手动和自动,各有优劣

ACK 机制的开发注意事项

如果忘记了 ACK,那么后果很严重

当 Consumer 退出时候,Message 会一直重新分发。然后 RabbitMQ 会占用越来越多的内容,由于 RabbitMQ 会长时间运行,这个” 内存泄漏” 是致命的

为什么需要限流,消费者流量控制

RabbitMQ 的组成

用于接受、分配消息

用于存储生产者的消息

消息推送使用的通道

生成者或者消费者与Rabbit 建立的TCP 连接

用于把生成者的数据分配到交换器上

用于把交换器的消息绑定到队列上

应用程序与 Rabbit 之间建立连接的管理器,程序代码中使用

vhost 可以理解为虚拟 broker,即虚拟机

其内部均含有独立的 queue、exchange 和 binding 等

拥有独立的权限系统,做到资源隔离,资源高效利用

RabbitMQ 的六种模式

简单的生产者生产消息,放入队列,消费者消费消息

当生产者生产消息的速度大于消费者消费的速度,就要考虑用 work 工作模式,这样能提高处理速度提高负载

work 模式与 single 模式类似, 只是work 模式比 single 模式多了一些消费者

应用场景:简单消息队列的使用,一个生产者一个消费者

消息生产者将消息发送给交换机按照路由判断,路由是字符串(info) 当前产生的消息携带路由字符(对象的方法),交换机根据路由的key

只能匹配上路由key对应的消息队列,对应的消费者才能消费消息

话题模式,一个消息被多个消费者获取,消息的目标 queue 可用 BindingKey 以通配符

通过远程过程调用的方式实现

存储机制

持久化的消息在到达队列时就被写入磁盘,持久化的消息也会在内存中保存一份备份,这样可以提高一定的性能,当内存吃紧的时候会从内存中清除

一般只保存在内存中,在内存吃紧的时候会被换入到磁盘中,以节省内存空间

RabbitMQ中消息可能有的几种状态

消息内容(包括消息体、属性和 headers) 和消息索引都存储在内存中

消息内容保存在磁盘中,消息索引保存在内存中

消息内容保存在磁盘中,消息索引在磁盘和内存中都有

消息内容和索引都在磁盘中

RabbitMQ 的队列结构?

负责协议相关的消息处理,即接收生产者发布的消息、向消费者交付消息、处理消息的确认等

是消息存储的具体形式和引擎,并向 rabbit_amqqueue_process 提供相关的接口以供调用

交换器无法根据自身类型和路由键找到符合条件队列时,会如何处理?

我们对交换机设置参数的时候,有一个标志叫做 mandatory

如果exchange根据自身类型和消息routingKey无法找到一个合适的queue存储消息,那么broker就会调用basic.return方法将消息返还给生产者

前置条件和上述保持一致,此时 broker会直接将消息丢弃

如何保证消息可靠性嘞?

由事务机制,确认机制 来保障

由持久化、集群、普通模式、镜像模式来保证

由basicAck机制、死信队列、消息补偿等机制来保证

集群中的节点类型有哪些?

ram,将变更写入内存。

disc,磁盘写入操作

RabbitMQ中 要求最少有一个磁盘节点

如何保证 RabbitMQ 消息队列的高可用?

RabbitMQ中有三种模式来保证:

一般是本地启动,自己学习和测试使用,不会用在生产环境上

在多台机器上启动多个 RabbitMQ 实例,每个机器启动一个

RabbitMQ的高可用模式

跟普通集群模式不一样的是,创建的 queue,无论元数据(元数据指 RabbitMQ 的配置数据)还是 queue 里的消息都会存在于多个实例上,

然后每次写消息到 queue 的时候,都会自动把消息到多个实例的 queue 里进行消息同步

参考资料:

RabbitMQ Tutorials

欢迎点赞,关注,收藏

朋友们,你的支持和鼓励,是我坚持分享,提高质量的动力

image

好了,本次就到这里

技术是开放的,我们的心态,更应是开放的。拥抱变化,向阳而生,努力向前行。

我是小魔童哪吒,欢迎点赞关注收藏,下次见~

上一篇 下一篇

猜你喜欢

热点阅读