RocketMQ高频面试题

268 阅读4分钟

欢迎关注WX公众号:“程序猿补课班”,分享Java相关技术知识,学习经验,面试经验等。小伙伴快来补课吧!

正文开始


1.为什么要使用MQ?

解耦 系统耦合度降低,没有强依赖关系

异步 不需要同步执行的远程调用可以有效提高响应时间

削峰 请求达到峰值后,后端还可以保持固定消费速率消费,不会被压垮。

2.RocketMQ如何保证消息不丢失?

首先在如下三个部分都可能会出现丢失消息的情况:

Producer端:

采取send()同步发消息,发送结果是同步感知的。

发送失败后可以重试,设置重试次数。默认3次。

Broker端:

修改刷盘策略为同步刷盘。默认情况下是异步刷盘的。

Consumer端:

完全消费正常后在进行手动ack确认。

3.RocketMQ的消息堆积如何处理?

首先要找到是什么原因导致的消息堆积,是Producer太多了,Consumer太少了导致的还是说其他情况,总之先定位问题。 然后看下消息消费速度是否正常,正常的话,可以通过上线更多consumer临时解决消息堆积问题。

4.如果Consumer和Queue不对等,上线了多台也在短时间内无法消费完堆积的消息怎么办?

  • 准备一个临时的topic;
  • queue的数量是堆积的N倍;
  • queue分布到多台broker中
  • 上线一台consumer做消息搬运工,把原来topic中的信息搬到新topic中,不做业务处理,只搬运
  • 上线N台consumer同时消费topic中的数据

5.堆积时间过长消息超时了?

RocketMQ中的消息只会在commitLog被删除的时候才会消失,不会超时。也就是说未被消费的消息不会存在超时删除这情况。

6.堆积的消息会不会进死信队列?

不会,消息在消费失败后会进入重试队列,超过一定次数才会进入死信队列。

7.那么在什么时候会变成死信?

消息拒绝并且没有设置重新入队

消息过期

消息堆积,并且队列达到最大长度,先入队的消息会变成DL。

8.消息重复消费怎么处理?

出现原因
正常情况下在consumer真正消费完消息后应该发送ack,通知broker该消息已正常消费,从queue中剔除
当ack因为网络原因无法发送到broker,broker会认为词条消息没有被消费,此后会开启消息重投机制把消息再次投递到consumer。

消费模式:在CLUSTERING模式下,消息在broker中会保证相同group的consumer消费一次,但是针对不同group的consumer会推送多次

解决方案

  • 数据库表:处理消息前,使用消息主键在表中带有约束的字段中insert
  • Map:单机时可以使用map做限制,消费时查询当前消息id是不是已经存在
  • Redis:使用分布式锁。

9.如何让RocketMQ保证消息的顺序消费?

首先多个queue只能保证单个queue里的顺序,queue是典型的FIFO,天然顺序。多个queue同时消费是无法绝对保证消息的有序性的。
可以使用同一topic,同一个QUEUE,发消息的时候一个线程去发送消息,消费的时候 一个线程去消费一个queue里的消息。

10.如果Broker宕了,NameServer是怎么感知到的?

Broker会定时(30s)向NameServer发送心跳

然后NameServer会定时(10s)运行一个任务,去检查一下各个Broker的最近一次心跳时间,如果某个Broker超过120s都没发送心跳了,那么就认为这个Broker已经挂掉了。

11.消费者获取消息有几种模式?

推送模式和拉取模式。

1. PushConsumer

推送模式(虽然 RocketMQ 使用的是长轮询)的消费者。消息的能及时被消费。使用非常简单,内部已处理如线程池消费、流控、负载均衡、异常处理等等的各种场景。

2. PullConsumer

拉取模式的消费者。应用主动控制拉取的时机,怎么拉取,怎么消费等。主动权更高。但要自己处理各种场景。

12.消费者消费模式有几种?

集群消费

消费者的一种消费模式。一个 Consumer Group 中的各个 Consumer 实例分摊去消费消息,即一条消息只会投递到一个 Consumer Group 下面的一个实例。

广播消费

消费者的一种消费模式。消息将对一 个Consumer Group 下的各个 Consumer 实例都投递一遍。即即使这些 Consumer 属于同一个Consumer Group ,消息也会被 Consumer Group 中的每个 Consumer 都消费一次。

如有错漏之处,敬请指正