美文网首页
我们一起来学RabbitMQ 五:RabbitMQ 应知应会的面

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

作者: 阿兵云原生 | 来源:发表于2021-10-15 23:03 被阅读0次

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

    MQ 是什么?

    MQ(Message Queue)消息队列

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

    什么是队列?

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

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

    • 异步通信

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

    • 业务解耦

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

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

    • 流量削峰

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

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

    MQ 有啥劣势呢?

    • 系统可用性降低,对外部有依赖了
    • 需要考虑 MQ 消息丢失,重复消费的问题
    • 需要花费精力保证消息的顺序性,一致性

    常用 MQ 性能对比

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

    MQ 如何避免消息堆积

    • 提高消费速率(集群的方式)
    • 消费者批量获取消息进行消费

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

    • 全局ID(增加标志位) + 保证业务一致性

    MQ 如何保证消息不丢失

    • 消息确认机制
    • 持久化
    • 消息 ACK

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

    • 绑定同一个消费者和队列

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

    • MQ 服务器与消费者建立长连接后,MQ 服务器会主动推数据给到消费者
    • 当消费者第一次启动的时候,会去找MQ 服务器拉数据

    mq有哪些消费模式

    • 推模式
      注册一个消费者后,RabbitMQ会在消息可用时,自动将消息进行推送给消费者。这种方式效率最高最及时。

    • 拉模式
      属于一种轮询模型,发送一次get请求,获得一个消息。如果此时RabbitMQ中没有消息,会获得一个表示空的回复。

    • 自动确认

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

    • 手动确认

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

    • qos预取模式

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

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

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

    connection 是什么

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

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

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

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

    信道复用连接优势:

    • 复用TCP连接,减少性能开销,便于管理
    • RabbitMQ 保障每一个信道的私密性
    image

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

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

    RabbitMQ 的作用

    • 削峰填谷
    • 生产者和消费者业务解耦
    • 服务间异步通信
    • 定时任务
    • 顺序消费

    为什么选择 RabbitMQ

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

    • 除了 Qpid,RabbitMQ 是唯一一个实现了 AMQP 标准的消息服务器
    • 可靠性,RabbitMQ 的持久化支持,保证了消息的稳定性
    • 高并发,RabbitMQ 使用了 Erlang 开发语言,Erlang 是为电话交换机开发的语言,天生自带高并发光环,和高可用特性
    • 集群部署简单,正是应为 Erlang 使得 RabbitMQ 集群部署变的超级简单
    • 社区活跃度高,根据网上资料来看,RabbitMQ 也是首选

    RabbitMQ 的特点是什么?

    • 可靠

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

    • 灵活的路由

    通过交换器来路由消息

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

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

    • 扩展性

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

    • 高可用性

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

    • 支持的协议多

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

    • 多语言客户端

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

    • WEB 管理界面

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

    • 命令插件机制

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

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

    生产者

    • 消息生产者,投递消息
    • 消息一般包含两个部分:消息体(payload)和标签(Label)

    消费者

    • 消费消息,接收消息

    • 消费者连接到 RabbitMQ 服务器,并订阅到队列

      消费消息时只消费消息体,丢弃标签

    RabbitMQ 消息持久化中的坑

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

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

    • 投递消息的时候 durable 设置为 true,消息持久化
    • 消息已经到达持久化交换器上
    • 消息已经到达持久化的队列上

    持久化的工作原理

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

    持久化的优缺点

    优点

    • 数据持久化,数据不丢失

    缺点

    • 对性能有影响,写硬盘比写内存性能低,从而降低服务的吞吐量

    RabbitMQ ACK 应答机制

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

    • 如果消息不太重要,丢失也没有影响,那么自动 ACK 会比较方便

    • 如果消息非常重要,不容丢失。那么最好在消费完成后手动 ACK

      否则接收消息后就自动 ACK,RabbitMQ 就会把消息从队列中删除。若此时消费者宕机或处理业务失败,那么消息就丢失了

    ACK 机制的开发注意事项

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

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

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

    • 某一时刻,生产者在 RabbitMQ 队列中堆积了很多消息,此时有一个消费者启动,大量的消息会推送到消费者上面,这种瞬时大流量会把消费者打挂
    • 生产者和消费者效率不平衡的情况,会导致消费者端性能下降,服务端卡顿或者崩溃

    RabbitMQ 的组成

    • 生产者 producer
    • 消费者 consumer
    • 交换机 exchange

    用于接受、分配消息

    • 消息 message
    • 队列 queue

    用于存储生产者的消息

    • 信道 channel AMQP

    消息推送使用的通道

    • 连接 connections

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

    • 路由键 routingKey

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

    • 绑定键 BindingKey

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

    • 连接管理器 ConnectionFactory

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

    • VHost

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

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

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

    RabbitMQ 的六种模式

    • single

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

    • work

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

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

    • publish

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

    • routing

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

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

    • topic

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

    • rpc

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

    存储机制

    • 持久化消息

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

    • 非持久化消息

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

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

    • alpha

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

    • beta

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

    • gamma

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

    • delta

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

    RabbitMQ 的队列结构?

    • rabbit_amqqueue_process

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

    • backing_queue

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

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

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

    • 当mandatory标志位设置为true时

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

    • 当mandatory设置为false时

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

    如何保证消息可靠性嘞?

    • 消息从生产者到 MQ

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

    • MQ 自身可靠性

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

    • MQ 消息到消费者

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

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

    • 内存节点

    ram,将变更写入内存。

    • 磁盘节点

    disc,磁盘写入操作

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

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

    RabbitMQ中有三种模式来保证:

    • 单机模式

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

    • 普通集群模式

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

    • 镜像集群模式

    RabbitMQ的高可用模式

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

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

    参考资料:

    RabbitMQ Tutorials

    欢迎点赞,关注,收藏

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

    image

    好了,本次就到这里

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

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

    相关文章

      网友评论

          本文标题:我们一起来学RabbitMQ 五:RabbitMQ 应知应会的面

          本文链接:https://www.haomeiwen.com/subject/vdsvoltx.html