rocketmq面试,有这一篇就够了~~~

1、mq如何选型

MQ描述
RabbitMQerlang开发,对消息堆积的支持并不好,当大量消息积压的时候,会导致 RabbitMQ 的性能急剧下降。每秒钟可以处理几万到十几万条消息。
RocketMQjava开发,面向互联网集群化功能丰富,对在线业务的响应时延做了很多的优化,大多数情况下可以做到毫秒级的响应,每秒钟大概能处理几十万条消息。
KafkaScala开发,面向日志功能丰富,性能最高。当你的业务场景中,每秒钟消息数量没有那么多的时候,Kafka 的时延反而会比较高。所以,Kafka 不太适合在线业务场景。
ActiveMQjava开发,简单,稳定,性能不如前面三个。小型系统用也ok,但是不推荐。推荐用互联网主流的。

2、为啥要使用?

消息队列作为高并发系统的核心组件之一,能够帮助业务系统解构提升开发效率和系统稳定性。主要具有以下优势:

  1. 削峰填谷:主要解决瞬时写压力大于应用服务能力导致消息丢失、系统奔溃等问题
  2. 系统解耦:解决不同重要程度、不同能力级别系统之间依赖导致一死全死
  3. 提升性能:当存在一对多调用时,可以发一条消息给消息系统,让消息系统通知相关系统
  4. 蓄流压测:线上有些链路不好压测,可以通过堆积一定量消息再放开来压测

3、RocketMQ由哪些角色组成

在这里插入图片描述

  1. Nameserver 无状态,动态列表;这也是和zookeeper的重要区别之一。zookeeper是有状态的。
  2. Producer 消息生产者,负责发消息到Broker。
  3. Broker 就是MQ本身,负责收发消息、持久化消息等。
  4. Consumer 消息消费者,负责从Broker上拉取消息进行消费,消费完进行ack。
4、RocketMQ Broker中的消息被消费后会立即删除吗?

不会,每条消息都会持久化到CommitLog中,每个Consumer连接到Broker后会维持消费进度信息,当有消息消费后只是当前Consumer的消费进度(CommitLog的offset)更新了。

5、那么消息会堆积吗?什么时候清理过期消息?

4.6版本默认48小时后会删除不再使用的CommitLog文件

  • 检查这个文件最后访问时间
  • 判断是否大于过期时间
  • 指定时间删除,默认凌晨4点

6、RocketMQ消费模式有几种?

消费模型由Consumer决定,消费维度为Topic。

1、集群消费

  1. 一条消息只会被同Group中的一个Consumer消费
  2. 多个Group同时消费一个Topic时,每个Group都会有一个Consumer消费到数据
    2、广播消费
    消息将对一 个Consumer Group 下的各个 Consumer 实例都消费一遍。即即使这些 Consumer 属于同一个Consumer Group ,消息也会被 Consumer Group 中的每个 Consumer 都消费一次。

7、消费消息是push还是pull?

RocketMQ没有真正意义的push,都是pull,虽然有push类,但实际底层实现采用的是长轮询机制,即拉取方式
broker端属性 longPollingEnable 标记是否开启长轮询。默认开启

8、broker如何处理拉取请求的?

Consumer首次请求Broker

Broker中是否有符合条件的消息
有 ->
响应Consumer
等待下次Consumer的请求
没有->

  • DefaultMessageStore#ReputMessageService#run方法
  • PullRequestHoldService来Hold连接,每个5s执行一次检查pullRequestTable有没有消息,有的话立即推送
  • 每隔1ms检查commitLog中是否有新消息,有的话写入到pullRequestTable
  • 当有新消息的时候返回请求挂起consumer的请求,即不断开连接,也不返回数据
  • 使用consumer的offset,

9、RocketMQ如何做负载均衡?

通过Topic在多Broker中分布式存储实现。

9.1 producer端

发送端指定message queue发送消息到相应的broker,来达到写入时的负载均衡

  1. 提升写入吞吐量,当多个producer同时向一个broker写入数据的时候,性能会下降
  2. 消息分布在多broker中,为负载消费做准备

默认策略是随机选择:

  1. producer维护一个index
  2. 每次取节点会自增
  3. index向所有broker个数取余
  4. 自带容错策略

其他实现:

  1. SelectMessageQueueByHash:hash的是传入的args
  2. SelectMessageQueueByRandom
  3. SelectMessageQueueByMachineRoom 没有实现

9.2 consumer端

采用的是平均分配算法来进行负载均衡。

其他负载均衡算法

  1. 平均分配策略(默认)(AllocateMessageQueueAveragely)
  2. 环形分配策略(AllocateMessageQueueAveragelyByCircle)
  3. 手动配置分配策略(AllocateMessageQueueByConfig)
  4. 机房分配策略(AllocateMessageQueueByMachineRoom)
  5. 一致性哈希分配策略(AllocateMessageQueueConsistentHash)
  6. 靠近机房策略(AllocateMachineRoomNearby)

10、消息重复消费

影响消息正常发送和消费的重要原因是网络的不确定性。

引起重复消费的原因

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

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

解决方案

  1. 数据库表:处理消息前,使用消息主键在表中带有约束的字段中insert
  2. Map:单机时可以使用map ConcurrentHashMap-> putIfAbsent guava cache
  3. Redis:分布式锁搞起来。

11、RocketMQ如何保证消息不丢失

11.1、Producer端如何保证消息不丢失
  1. 采取send()同步发消息,发送结果是同步感知的。
  2. 发送失败后可以重试,设置重试次数。默认3次。
  3. 集群部署,比如发送失败了的原因可能是当前Broker宕机了,重试的时候会发送到其他Broker上。
11.2 Broker端如何保证消息不丢失
  1. 修改刷盘策略为同步刷盘。默认情况下是异步刷盘的。
  2. 集群部署,主从模式,高可用。
11.3 Consumer端如何保证消息不丢失

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

12 RocketMQ在分布式事务支持这块机制的底层原理?

12.1概念
  1. Half(Prepare) Message——半消息(预处理消息):半消息是一种特殊的消息类型,该状态的消息暂时不能被Consumer消费。当一条事务消息被成功投递到Broker上,但是Broker并没有接收到Producer发出的二次确认时,该事务消息就处于"暂时不可被消费"状态,该状态的事务消息被称为半消息。
  2. Message Status Check——消息状态回查:由于网络抖动、Producer重启等原因,可能导致Producer向Broker发送的二次确认消息没有成功送达。如果Broker检测到某条事务消息长时间处于半消息状态,则会主动向Producer端发起回查操作,查询该事务消息在Producer端的事务状态(Commit 或 Rollback)。可以看出,Message Status Check主要用来解决分布式事务中的超时问题。
12.2 执行流程

在这里插入图片描述
下面对具体流程进行分析:

  1. Step1:Producer向Broker端发送Half Message;
  2. Step2:Broker ACK,Half Message发送成功;
  3. Step3:Producer执行本地事务;
  4. Step4:本地事务完毕,根据事务的状态,Producer向Broker发送二次确认消息,确认该Half Message的Commit或者Rollback状态。Broker收到二次确认消息后,对于Commit状态,则直接发送到Consumer端执行消费逻辑,而对于Rollback则直接标记为失败,一段时间后清除,并不会发给Consumer。正常情况下,到此分布式事务已经完成,剩下要处理的就是超时问题,即一段时间后Broker仍没有收到Producer的二次确认消息;
  5. Step5:针对超时状态,Broker主动向Producer发起消息回查;
  6. Step6:Producer处理回查消息,返回对应的本地事务的执行结果;
  7. Step7:Broker针对回查消息的结果,执行Commit或Rollback操作,同Step4。

13 Broker把自己的信息注册到哪个NameServer上?

这么问明显在坑你,因为Broker会向所有的NameServer上注册自己的信息,而不是某一个,是每一个,全部!

14 Rebalance

14.1 定义
  • 将一个Topic下的多个队列(或称之为分区),在同一个消费者组(consumer group)下的多个消费者实例(consumer instance)之间进行重新分配。
  • Rebalance机制本意是为了提升消息的并行处理能力。例如,一个Topic下5个队列,在只有1个消费者的情况下,那么这个消费者将负责处理这5个队列的消息。如果此时我们增加一个消费者,那么可以给其中一个消费者分配2个队列,给另一个分配3个队列,从而提升消息的并行处理能力
14.2 Rebalance限制:

由于一个队列最多分配给一个消费者,因此当某个消费者组下的消费者实例数量大于队列的数量时,多余的消费者实例将分配不到任何队列。

14.3 Rebalance危害:

除了以上限制,更加严重的是,在发生Rebalance时,存在着一些危害,如下所述:

  1. 消费暂停:考虑在只有Consumer 1的情况下,其负责消费所有5个队列;在新增Consumer 2,触发Rebalance时,需要分配2个队列给其消费。那么Consumer1就需要停止这2个队列的消费,等到这两个队列分配给Consumer 2后,这两个队列才能继续被消费。
  2. 重复消费:Consumer 2 在消费分配给自己的2个队列时,必须接着从Consumer1之前已经消费到的offset继续开始消费。然而默认情况下,offset是异步提交的,如consumer 1当前消费到offset为10,但是异步提交给broker的offset为8;那么如果consumer2从8的offset开始消费,那么就会有2条消息重复。也就是说,Consumer 2 并不会等待Consumer1提交完offset后,再进行Rebalance,因此提交间隔越长,可能造成的重复消费就越多。
  3. 消费突刺:由于rebalance可能导致重复消费,如果需要重复消费的消息过多;或者因为rebalance暂停时间过长,导致积压了部分消息。那么都有可能导致在rebalance结束之后瞬间可能需要消费很多消息。
14.4 Broker端Rebalance协调机制

A、队列信息变化

  1. broker宕机
  2. broker升级等运维操作
  3. 队列扩容/缩容

B、消费者组信息变化

  1. 日常发布过程中的停止与启动
  2. 消费者异常宕机
  3. 网络异常导致消费者与Broker断开连接
  4. 主动进行消费者数量扩容/缩容
  5. Topic订阅信息发生变化
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值