RabbitMq相关面试题

消息队列有没有接触过 简单介绍一下

了解消息队列中间件是分布式系统中重要的组件主要解决应用解耦异步消息流量削锋等问题实现高性能高可用可伸缩和最终一致性架构目前使用较多的消息队列有 ActiveMQRabbitMQZeroMQKafkaMetaMQRocketMQ

消息中间件模式分类

  • 点对点P2P
    一条消息只能被一个消费者消费。
  • 发布、订阅
    一条消息可以同时被多个消费者消费生产者和消费者有时间上的依赖性生产者在生产的消息的时候应该至少有一个
    消费者处于在线状态。

使用MQ有什么好处

流量削锋
把消息压入RabbitMQ中可以缓冲系统压力。比如现在系统只能接受2000请求但是一下子有10000个请求过来那么这个请求就会压在RabbitMQ中那么就可以慢慢进行消费了。

异步消息
以前是先去发短信再去发邮件。引入RabbitMQ之后我们就可以进行在发短信的同时再去发邮箱。

应用解耦
当多个系统耦合在一起的时候系统的消息会发送给连在一起的系统但是这个消息有些系统可能是不需要的。所以引入了之后很方便将这个系统进行解耦每个系统需要的就在消息队列解耦。

MQ如何选型

在这里插入图片描述

中⼩型公司⾸选RabbitMQ管理界⾯简单⾼并发。

⼤型公司可以选择RocketMQ更⾼并发可对Rocketmq进⾏定制化开发。
⽇志采集功能⾸选kafka专为⼤数据准备。

你们项目中用到过 MQ 吗谈谈你对 MQ 的理解

我们项目中使用 MQ 主要是做一些异步的操作比如说我们的接口是属于 http 协议接口
它是同步调用如果说接口响应比较慢的情况下会导致客户端同步阻塞等待客户
端同步阻塞等待的情况下会引发客户端超时客户端一旦发生超时就会导致客户端触发
一些重试的策略而在触发重试的策略过程中会导致业务可能会发生重复执行所以我们就
需要注意一些幂等性问题而接口因为它执行比较耗时所以呢我们会将一些执行比较耗
时的业务逻辑代码把他直接改成使用 mq 异步去实现能够提高就是我们的 http 协议接口
的响应速度比如说异步的去扣库存呢异步的去发短信呢这些场景下我们都是使用到 MQ
来进行实现落地的。

MQ消费者消费消息的顺序一致性问题

生产者投递消息过程当中可以设定一个消息 key相同的业务逻辑呢可以设定一个相同的消息 key 在做 hash 的时候最终都会落地到同一个分区来就行存放最终就被同一个消费者进行消费所以想解决消息顺序这些问题它的核心思想就是让我们的这个消息投递存放到同一个分区里面最终被同一个消费者消费。

RabbitMQ如何保证数据⼀致性

  1. ⽣产者确认机制消息持久化后异步回调通知⽣产者保证消息已经发出去
  2. 消息持久化设置消息持久化
  3. 消费者确认机制消费者成功消费消息之后⼿动确认保证消息已经消费。

你们如何解决消息堆积问题

消息堆积呢是一种常见的问题尤其是在高并发的场景下可以说是经常遇到了生产者投递消息的这个速率比我们的消费者消费速率明显不匹配比如说我们最高峰的时候 生产者 它投递消息的时候一次性的 1s 内可能投递到将近几万条消息但是我们的消费者他只有一个而消费者消费消息的过程中是单个消费者的消费的速率比较慢所以当时我们为了解决这个问题我们第一是先将我们的消费者做成集群的形式来进行消费第二呢每个消费者他一般都是批量的形式来进行消费这样的话就可以提高我们的消费者他的消费速率如果以后我们跟不上的情况呢我们可以不断的横向扩张对于我们的消费者不断的做集群然后批量消费这样就可以增加我们消费者的消费速率从而可以解决我们的消息堆积的问题。

RabbitMQ消费者自动扩展数量

SimpleMessageListenerContainer可根据RabbitMQ消息堆积情况⾃动扩展消费者数量。

上千万条消息在mq中积压了几个小时还没解决

  1. 先修复consumer的问题确保其恢复消费速度然后将现有consumer都停掉
  2. 新建⼀个topicpartition是原来的10倍临时建⽴好原先10倍或者20倍的queue数量
  3. 然后写⼀个临时的分发数据的consumer程序这个程序部署上去消费积压的数据消费之后不做
    耗时的处理直接均匀轮询写⼊临时建⽴好的10倍数量的queue
  4. 接着临时征⽤10倍的机器来部署consumer每⼀批consumer消费⼀个临时queue的数据
  5. 这种做法相当于是临时将queue资源和consumer资源扩⼤10倍以正常的10倍速度来消费数据
  6. 等快速消费完积压数据之后得恢复原先部署架构重新⽤原先的consumer机器来消费消息。

如何确保消息正确地发送⾄RabbitMQ

RabbitMQ使⽤发送⽅确认模式确保消息正确地发送到RabbitMQ。
发送⽅确认模式将信道设置成confirm模式发送⽅确认模式则所有在信道上发布的消息
都会被指派⼀个唯⼀的ID。⼀旦消息被投递到⽬的队列后或者消息被写⼊磁盘后可持久化
的消息信道会发送⼀个确认给⽣产者包含消息唯⼀ID。如果RabbitMQ发⽣内部错误
从⽽导致消息丢失会发送⼀条nacknot acknowledged未确认消息。
发送⽅确认模式是异步的⽣产者应⽤程序在等待确认的同时可以继续发送消息。当确认消息
到达⽣产者应⽤程序⽣产者应⽤程序的回调⽅法就会被触发来处理确认消息。

如何确保消息接收⽅消费了消息

接收⽅消息确认机制消费者接收每一条消息后都必须进行确认消息接收和消息确认是两个不同操
作。只有消费者确认了消息RabbitMQ才能安全地把消息从队列中删除。
这⾥并没有⽤到超时机制RabbitMQ仅通过Consumer的连接中断来确认是否需要重新发送消息。也
就是说只要连接不中断RabbitMQ给了Consumer⾜够⻓的时间来处理消息。
特殊情况

  1. 如果消费者接收到消息在确认之前断开了连接或取消订阅RabbitMQ会认为消息没有被分发
    然后重新分发给下一个订阅的消费者。可能存在消息重复消费的隐患需要根据bizId去重
  2. 如果消费者接收到消息却没有确认消息连接也未断开则RabbitMQ认为该消费者繁忙将不会
    给该消费者分发更多的消息。

如何避免消息重复投递或重复消费

在消息⽣产时MQ内部针对每条⽣产者发送的消息⽣成⼀个inner-msg-id作为去重和幂等的依
据消息投递失败并重传避免重复的消息进⼊队列在消息消费时要求消息体中必须要有
⼀个bizId对于同⼀业务全局唯⼀如⽀付ID、订单ID、帖⼦ID等作为去重和幂等的依据避
免同⼀条消息被重复消费。

rabbitmq设置过期时间部分消息丢失

采取批量重导⽅法将丢失的那批数据查询导⼊到mq⾥⾯。

如何确保消息不丢失

消息持久化的前提是将交换器/队列的durable属性设置为true表示交换器/队列是持久交换器/
队列在服务器崩溃或重启之后不需要重新创建交换器/队列交换器/队列会⾃动创建。
如果消息想要从Rabbit崩溃中恢复那么消息必须

  1. 在消息发布前通过把它的 “投递模式” 选项设置为2持久来把消息标记成持久化
  2. 将消息发送到持久交换器
  3. 消息到达持久队列
    RabbitMQ确保持久性消息能从服务器重启中恢复的⽅式是将它们写⼊磁盘上的⼀个持久化⽇志
    ⽂件当发布⼀条持久性消息到持久交换器上时Rabbit会在消息提交到⽇志⽂件后才发送响应
    如果消息路由到了⾮持久队列它会⾃动从持久化⽇志中移除。⼀旦消费者从持久队列中消
    费了⼀条持久化消息RabbitMQ会在持久化⽇志中把这条消息标记为等待垃圾收集。如果持久化
    消息在被消费之前RabbitMQ重启那么Rabbit会⾃动重建交换器和队列以及绑定并重播持
    久化⽇志⽂件中的消息到合适的队列或者交换器上。

消息怎么路由

从概念上来说消息路由必须有三部分交换器、路由、绑定。⽣产者把消息发布到交换器上绑定决
定了消息如何从交换器路由到特定的队列消息最终到达队列并被消费者接收。

  1. 消息发布到交换器时消息将拥有⼀个路由键routing key在消息创建时设定。
  2. 通过队列路由键可以把队列绑定到交换器上。
  3. 消息到达交换器后RabbitMQ会将消息的路由键与队列的路由键进行匹配针对不同的交换器有
    不同的路由规则。
  4. 如果能够匹配到队列则消息会投递到相应队列中如果不能匹配到任何队列消息将进⼊ “⿊
    洞”。

RabbitMQ结构

在这里插入图片描述
Broker简单来说就是消息队列服务器实体。
Exchange消息交换机它指定消息按什么规则路由到哪个队列。
Queue消息队列载体每个消息都会被投⼊到⼀个或多个队列。
Binding绑定它的作⽤就是把exchange和queue按照路由规则绑定起来。
Routing Key路由关键字exchange根据这个关键字进⾏消息投递。
vhost虚拟主机⼀个broker⾥可以开设多个vhost⽤作不同⽤户的权限分离。
producer消息⽣产者就是投递消息的程序。
consumer消息消费者就是接受消息的程序。
channel消息通道在客户端的每个连接⾥可建⽴多个channel每个channel代表⼀个会话

RabbitMQ交换器有哪些类型

direct如果路由键完全匹配消息就被投递到相应的队列
fanout如果交换器收到消息将会⼴播到所有绑定的队列上
topic可以使来⾃不同源头的消息能够到达同⼀个队列。 使⽤topic交换器时可以使⽤通配
符⽐如“*” 匹配特定位置的任意⽂本 “.” 把路由键分为了⼏部分“#” 匹配所有规则等。特别
注意发往topic交换器的消息不能随意的设置选择键routing_key必须是由"."隔开的⼀系列
的标识符组成
headers交换器根据发送消息内容的headers属性进⾏匹配由于性能很差不实⽤

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
标签: RabbitMQ