05 RabbitMQ面试题

Posted IT BOY

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了05 RabbitMQ面试题相关的知识,希望对你有一定的参考价值。

目录

Pt1 消息队列的作用与使用场景?

Pt2 RabbitMQ有哪些特性?

Pt3 Channel和VHost的作用是什么?

Pt4 多个项目公用MQ服务器时,如何实现权限隔离?

Pt5 RabbitMQ的消息有哪些路由方式?适合在什么业务场景使用?

Pt6 交换机与队列、队列与消费者是如何绑定的?

Pt7 无法被路由的消息去了哪里?

Pt8 消息在什么时候会进入死信队列?

Pt9 如果一个项目要从多个服务器接收消息如何处理?

Pt10 如果一个项目要发送消息到多个服务器如何处理?

Pt11 RabbitMQ如何实现消息延迟发送?例如15分钟未支付自动关单。

Pt12 哪些情况会导致消息丢失,如何解决呢?

Pt13 一个队列最多可以存放多少条消息?

Pt14 在秒杀场景下,可以使用x-max-length最大消息数来限流吗?

Pt15 如何提高消息的消费速率?

Pt16 如何动态创建队列和消费者?

Pt18 如何保证消息的顺序性?

Pt19 RabbitMQ的集群节点类型有哪些?区别是什么?

Pt20 如何保证RabbitMQ的高可用?

Pt21 大量消息堆积怎么办?

Pt22 生产者消息运转?

Pt23 消费者接收消息过程?


Pt1 消息队列的作用与使用场景?

MQ(消息队列),是一种跨进程的通信服务,用于上下游系统传递消息。通过提供消息传递和消息队列模型,可以在分布式环境下扩展进程通信,进行分布式系统的集成。

消息队列通常适用以下场景(作用):

  • 实现异步通信:可以补充具体案例。

  • 实现系统解耦:可以补充具体案例。

  • 实现流量消峰:可以补充具体案例。

  • 实现广播通信:可以补充具体案例。

Pt2 RabbitMQ有哪些特性?

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

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

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

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

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

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

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

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

Pt3 Channel和VHost的作用是什么?

Channel是RabbitMQ API最重要的编程接口,用于减少TCP资源的消耗。

VHost用于提高硬件资源利用率,实现资源隔离。

Pt4 多个项目公用MQ服务器时,如何实现权限隔离?

通过为每个项目建立不同的VHost进行资源隔离和权限控制。

Pt5 RabbitMQ的消息有哪些路由方式?适合在什么业务场景使用?

Exchange有3中路由方式:

  • Direct:适用于一些业务用途明确的消息,使用明确的绑定键;

  • Topic:适用于一些根据业务主题或者消息等级过滤消息的场景,比如说在业务场景中可能涉及多个分布式系统,则可以根据路由键的设置让消息被不同的系统接收。

  • Fanout:适用于一些通用业务消息,广播,通知类的。

Pt6 交换机与队列、队列与消费者是如何绑定的?

交换机与队列通过绑定键进行绑定,是多对多的关系。

消费者通过制定队列来消费,也是多对多关系

Pt7 无法被路由的消息去了哪里?

直接丢弃,或者可以设置备份交换机进行接收处理。

Pt8 消息在什么时候会进入死信队列?

  • 消息被拒(Basic.Reject /Basic.Nack) 且 requeue = false。

  • 消息TTL过期。

  • 队列满了,无法再添加。

Pt9 如果一个项目要从多个服务器接收消息如何处理?

定义多个ConnectionFactory实例,注入到消费者监听类中。

Pt10 如果一个项目要发送消息到多个服务器如何处理?

定义多个ConnectionFactory实例,注入到生产者中,建立多个Channel发送小。

Pt11 RabbitMQ如何实现消息延迟发送?例如15分钟未支付自动关单。

  • 数据库 + 定时任务;

  • 消息过期 + 死信队列;

  • 延迟队列插件;

Pt12 哪些情况会导致消息丢失,如何解决呢?

  • 生产者发送到Exchange时,发生异常或者网络问题。通过事务或者确认机制解决。

  • Exchange路由到Queue时,路由键不匹配或者发生异常。通过消息重发生产者,或者建立备用交换机进行消息处理。

  • 消息保存在Queue中未消费时发生异常,通过消息持久化,以便能够在消息发生异常,故障恢复后恢复消息数据。

  • 消息被消费者获取时异常,通过消费者发送ack确认消息已经送达。

Pt13 一个队列最多可以存放多少条消息?

可以认为是无限制,限制取决于机器的内存,但是消息过多会导致处理效率的下降。

通过Max Length和Max Length bytes可以限制队列的消息数量,但是限制方式是LRU,不是限制消息进入队列,而是将已经进入队列的消息删除,所以会导致消息丢失。

Pt14 在秒杀场景下,可以使用x-max-length最大消息数来限流吗?

不可以。x-max-length限流的手段不是组织消息进入队列,而是将已经进入队列的消息通过LRU进行删除,再将新消息入队列,明显在秒杀场景下非常不公平。

Pt15 如何提高消息的消费速率?

通过创建多个消费者,并发消费消息。不过要注意,如果消息有很强的顺序性时,多消费者很难保证消息的顺序性。

Pt16 如何动态创建队列和消费者?

使用Container动态创建消费者:

 public class DynamicConsumer 
     private SimpleMessageListenerContainer container;
  
     public DynamicConsumer(MQContainerFactory fac, String name) throws Exception 
         SimpleMessageListenerContainer container = fac.getObject();
         container.setMessageListener(new AbsMQConsumer() 
             @Override
             public boolean process(Message message, Channel channel) 
                 // TODO 业务逻辑
                 return true;
             
         );
         this.container = container;
     
  
     //启动消费者监听
     public void start() 
         container.start();
     
  
    //消费者停止监听
     public void stop() 
         container.stop();
     
  
     //消费者重启
     public void shutdown() 
         container.shutdown();
     
 

Pt18 如何保证消息的顺序性?

消息的顺序性指的是消费者消费消息的顺序跟生产者生产消息的顺序是一致的。

举例来说,业务上的操作顺序是:1、通知订单系统完成下单;2、通知支付系统完成订单支付;3、通知物流系统发货。

这种场景下消息的顺序是不能颠倒的,订单都没有支付成功不可能就发货,所以要保证这种场景下消息消费的顺序性。

在RabbitMQ中,队列本身是FIFO,能够保证消息进出队列的顺序是一致的,先入队列的消息先出队列。

当队列仅有一个消费者时,能够保证消息的顺序消费。

但是当队列有多个消费者时,消费者同时从队列获取多条消息,但是因为每个消费者处理速度不同,可能会导致消息被消费的顺序错乱。

所以,对于要保证消费顺序的队列,只能有一个消费者负责处理消息。正常来说,除非是消息负载比较高,尽量不要用多个消费者消费消息。

Pt19 RabbitMQ的集群节点类型有哪些?区别是什么?

  • 磁盘节点:将元数据(VHost、Exchange名称/属性/类型、Queue名称/属性、绑定关系)存放在磁盘中。如果不指定类型,默认是磁盘节点。集群中至少需要一个磁盘节点来负责持久化数据,否则当集群宕机时,节点在内存中的数据将全部丢失,将会导致丢失全部元数据。

  • 内存节点:将元数据存放在内存中。内存节点读写速度快,一般用来连接客户端程序,磁盘节点则用于备份数据和恢复数据。内存节点会将磁盘节点的磁盘上,用于故障时找到磁盘上的数据进行恢复。同时,如果是持久化消息,会同时存储在内存和磁盘节点上。

Pt20 如何保证RabbitMQ的高可用?

RabbitMQ 有三种模式:单机模式,普通集群模式,镜像集群模式。

  • 单机模式:一般不适用于生产环境,可用性无法保障;

  • 普通集群模式:有多个Broker节点组成集群,互相同步元数据。单节点故障时,可以保证元数据不丢失,但是无法保证消息不丢失,性能较高,可用性相对一般,适用于对消息一致性要求不是非常高的场景。

  • 镜像集群模式:RabbitMQ的高可用模式,跟普通集群模式不同的是,镜像模式下每个节点之间会同步元数据和消息数据,保证任何一个节点故障的情况下,其他节点都可以无差别替代。可用性最高。

Pt21 大量消息堆积怎么办?

如果是消费者消费能力不足,可以增加消费者,并发消费消息。

如果是消费者自身逻辑问题,需要解决修复消费者处理逻辑。

Pt22 生产者消息运转?

  1. Producer先连接到Broker,建立连接Connection,开启一个信道(Channel)。

  2. Producer声明一个交换器并设置好相关属性。

  3. Producer声明一个队列并设置好相关属性。

  4. Producer通过路由键将交换器和队列绑定起来。

  5. Producer发送消息到Broker,其中包含路由键、交换器等信息。

  6. 相应的交换器根据接收到的路由键查找匹配的队列。

  7. 如果找到,将消息存入对应的队列,如果没有找到,会根据生产者的配置丢弃或者退回给生产者。

  8. 关闭信道。

  9. 管理连接。

Pt23 消费者接收消息过程?

  1. Producer先连接到Broker,建立连接Connection,开启一个信道(Channel)。

  2. 向Broker请求消费响应的队列中消息,可能会设置响应的回调函数。

  3. 等待Broker回应并投递相应队列中的消息,接收消息。

  4. 消费者确认收到的消息,ack。

  5. RabbitMq从队列中删除已经确定的消息。

  6. 关闭信道。

  7. 关闭连接。

 本章到此结束,更多关于RabbitMQ的文章,请点击如下专栏连接。

00. 消息队列专栏开篇_Java是世界上最好的语言-CSDN博客这部分主要讲解关于消息队列的内容,包括RabbitMQ、Kafka和RocketMQ,目前主要整理了一些基本用法和组件介绍,后续会逐渐深入介绍些原理部分。目录https://blog.csdn.net/moonlight821/article/details/118068777

以上是关于05 RabbitMQ面试题的主要内容,如果未能解决你的问题,请参考以下文章

RabbitMQ 死信队列

RabbitMQ实战-死信队列

RabbitMQ一文带你搞定RabbitMQ死信队列

05 RabbitMQ面试题

05 RabbitMQ面试题

05 RabbitMQ面试题