设为首页 加入收藏

TOP

MQ消息队列篇:三大MQ产品的必备面试种子题(一)
2023-08-06 07:49:48 】 浏览:62
Tags:三大

MQ有什么用?

MQ(消息队列)是一种FIFO(先进先出)的数据结构,主要用于实现异步通信、削峰平谷和解耦等功能。它通过将生产者生成的消息发送到队列中,然后由消费者进行消费。这样,生产者和消费者之间就不存在直接的耦合关系。

其中,MQ的优势主要体现在以下几个方面:

  • 异步通信:由于存在MQ这个中间件,生产者将消息发送到队列后,可以立即返回,无需等待消费者处理完毕。这样可以提高系统的响应速度和并发能力。
  • 削峰平谷:当系统出现峰值请求时,MQ可以存储大量的请求消息,将峰值数据缓冲下来,然后由消费者按照自己的处理能力逐步消费。这样可以避免系统因突发流量而崩溃,提高系统的稳定性和可靠性。
  • 解耦功能:MQ可以将生产者和消费者两端分离开来,实现系统之间的解耦。尤其在跨语言的场景下,MQ可以轻松实现不同语言程序之间的通信,简化开发和维护的复杂性。

然而,引入MQ也存在一些劣势需要注意:

  • 高可用性要求:为了保证MQ的正常运行,需要对MQ进行高可用性的设计和部署。一旦MQ宕机,整个业务流程可能会受到影响,导致系统不可用。
  • 系统复杂性提高:引入MQ后,需要专门的人员进行维护和管理,并对MQ产品有深入的了解。同时,为了保证消息的不丢失和消费幂等性,还需要进行一些额外的工作。
  • 系统一致性问题:由于MQ是异步通信的方式,当一个业务生成后,如果需要两个系统之间的一致性,就需要保证两个系统都成功执行完成。否则,可能会出现数据不一致的情况。

综上所述,MQ在提供异步通信、削峰平谷和解耦等功能的同时,也需要注意高可用性、系统复杂性和系统一致性等问题。在使用MQ时,需要综合考虑这些因素,并进行适当的设计和调优。

如何进行产品选型

目前市场上有三大主流MQ产品供选择,它们分别是kafka、rabbitmq和rocketmq。

  • kafka的性能最快,效率最高,适用于处理日志分析、大数据分析等场景。然而,kafka存在数据丢失的风险,并且功能相对单一,不保证消息的可靠性。
  • rabbitmq保证了消息的可靠性,但无法处理大数据量的消息队列。一旦数据量增大,整个MQ服务器的性能将下降。因此,rabbitmq适用于小规模场景。
  • rocketmq吸取了kafka和rabbitmq的优点,几乎可以应用于各种场景。它既具有高效率又具有高可靠性。不过需要注意的是,开源版本的rocketmq可能不如商业版本稳定和可靠。

因此,在进行产品选型时,您需要综合考虑各个MQ产品的特点和适用场景。如果您需要处理大数据量的消息队列,可以考虑kafka或者商业版本的rocketmq。如果您对消息的可靠性要求较高,可以选择rabbitmq或者商业版本的rocketmq。

如何保证消息不丢失?

首先,我们要检查可能导致消息丢失的部分:

  • 生产者将消息发送到消息队列服务器;
  • 消息队列服务器宕机;
  • 消息队列服务器未将消息刷新到磁盘;
  • 消息队列将消息发送给消费者。

image

然后根据每一步开始分析如何保证消息不丢失;

RocketMQ独有的事务消息机制:

image

  1. 对于使用Kafka、RocketMQ、RabbitMQ的情况,它们都有消息确认机制。例如,消息只有在到达消息队列后才会返回确认信息。RocketMQ还有独有的事务消息机制,可以确认消息是否成功发送到消息队列服务器,并与相关业务进行关联。当消息队列服务器监听到生产者服务器未返回成功时,会持续回调生产者服务器,直到成功或超时。
  2. 如果消息队列服务器宕机,说明需要保证消息队列的高可用性。因此,必须使用集群环境。对于RocketMQ来说,它的节点分为主节点和从节点。一旦主节点宕机,从节点会立即启动,确保消息不丢失。但是主从同步是异步进行的,因此需要使用Dledger集群的两阶段提交来确保超过半数的机器同步成功后才能返回给生产者。对于RabbitMQ集群,普通集群是分散存储的,即所有集群的总和等于队列的总数,没有备份。这可能导致机器宕机后丢失部分数据,所以RabbitMQ有一个镜像集群,会主动在节点之间进行同步,解决了数据丢失的问题。至于Kafka,本身允许丢失数据的情况,因此不需要对Kafka进行大量的消息可靠性优化以减少效率问题。但它有一个ack确认机制。
  3. 对于RocketMQ,可以采用异步刷盘来确保效率,但如果要确保消息的可靠性,就需要使用同步刷盘机制,即损失一部分效率。对于RabbitMQ,可以设置队列持久化来确保消息刷盘。
  4. 当消息队列将消息投递给消费者时,消费者自己需要采取相应的策略。对于RocketMQ、RabbitMQ和Kafka,都应将消息的偏移量设置为手动提交,而不是自动提交。否则,如果某个消费者消费失败,该条消息将会丢失。

如何保证消息消费的幂等性?

为了保证消息消费的幂等性,我们可以采取以下策略。首先,在生产者端,我们需要为每条消息设置一个唯一的业务ID,确保消息的唯一性。这可以通过生成全局唯一的UUID或者使用分布式ID生成算法来实现。

然后,在消费端,我们可以利用一些中间件,比如Redis,来记录已经消费过的消息。这可以通过将消费过的消息的业务ID存储在Redis中来实现。在消费端处理消息之前,我们首先查询Redis,判断当前消息的业务ID是否已经存在。如果存在,说明该消息已经被消费过,可以直接忽略。如果不存在,说明该消息是新的,可以进行消费处理。

通过以上的策略,我们可以确保消息的幂等性,避免重复消费同一条消息。同时,使用中间件来记录已经消费过的消息,可以提高查询效率和降低存储空间的占用。这样,即使消费端出现异常或者重启,也能够保证消息的消费状态不会丢失,从而保证消息消费的可靠性。

如何保证消息的顺序

如何保证消息的顺序呢?虽然消息队列(MQ)本身可以保证局部的消息顺序,但并不能保证全局的消息顺序。这是因为在实际的系统中,为了提高可用性,通常会使用多个队列来存储消息,而无法将同一个业务的消息全部放入同一个队列中。因此,需要了解各种MQ的特性。

image

RocketMQ提供了有序队列的实现机制。它在主题(Topic)和队列(Queue)之间引入了一个Message Select机制,可以将同一个业务的消息发送到同一个队列中,从而保证消息的有序性。在消费端,如果你使用OrderMessageListen监听器来消费消息,它会在获取消息时,锁定一个队列,将该队列中的消息全部消费完,然后再获取下一个队列的消息。这样就能够保证消息的有序消费。

相比之下,RabbitMQ和Kafka并没有专门提供对消息顺序的支持。如果你确实需要保证消息的顺序,你可以将队列和消费者设置成一个,这样就能够保证有序性。但是这种方式效率较低,因此在实际应用中,需要仔细考虑是否真的需要使用有序性。

总之,在设计消息消费时,需要根据实际情况来选择是否需要保证消息的顺序。如果确实需要有序性,可以考虑使用RocketMQ等支持有序队列的MQ,或者将队列和消费者设置成一个。但需要注意,有序性可能会牺牲一定的性能,因此需要权衡利弊来做出决策。


如何保证消息的高效读写

传统文件复制方式: 需要对文件在内存中进行四次拷贝。

image

读写操作涉及到IO操作,而有关IO操作的优化,我们会想到零拷贝技术。在这方面,Kafka和RocketMQ都采用了零拷贝技术

首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇quarkus依赖注入之三:用注解选择.. 下一篇面试再也不怕问ThreadLocal了

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目