开篇介绍
大家好,我是Java最全面试题库
的提裤姐,今天这篇是中间件面试题系列的第二篇,主要总结了RocketMQ相关的面试题;在后续,会沿着第一篇开篇的知识线路一直总结下去,做到日更!如果我能做到百日百更,希望你也可以跟着百日百刷,一百天养成一个好习惯。
多个MQ如何选型?
RabbitMQ
erlang开发,对消息堆积的支持并不好,当大量消息积压的时候,会导致 RabbitMQ 的性能急剧下降。每秒钟可以处理几万到十几万条消息。
RocketMQ
java开发,面向互联网集群化
,功能丰富,对在线业务的响应时延做了很多的优化,大多数情况下可以做到毫秒级的响应,每秒钟大概能处理几十万条消息。
Kafka
Scala开发,面向日志
,功能丰富,性能最高。当你的业务场景中,每秒钟消息数量没有那么多的时候,Kafka 的时延反而会比较高。所以,Kafka 不太适合在线业务场景。
ActiveMQ
java开发,简单,稳定,性能不如前面三个。不推荐。
RocketMQ组成部分有哪些?
Nameserver
无状态,动态列表;这也是和zookeeper的重要区别之一。zookeeper是有状态的。
Producer
消息生产者,负责发消息到Broker。
Broker
就是MQ本身,负责收发消息、持久化消息等。
Consumer
消息消费者,负责从Broker上拉取消息进行消费,消费完进行ack。
RocketMQ消费模式有几种?
集群消费
- 一条消息只会被同Group中的一个Consumer消费
- 多个Group同时消费一个Topic时,每个Group都会有一个Consumer消费到数据
广播消费
- 消息将对一个Consumer Group 下的各个 Consumer 实例都消费一遍。即即使这些 Consumer 属于同一个Consumer Group ,消息也会被 Consumer Group 中的每个 Consumer 都消费一次。
消息重复消费如何解决?
出现原因
正常情况下在consumer真正消费完消息后应该发送ack,通知broker该消息已正常消费,从queue中剔除
当ack因为网络原因无法发送到broker,broker会认为词条消息没有被消费,此后会开启消息重投机制把消息再次投递到consumer。
消费模式:在CLUSTERING
模式下,消息在broker中会保证相同group的consumer消费一次,但是针对不同group的consumer会推送多次
解决方案
- 数据库表:处理消息前,使用消息主键在表中带有约束的字段中insert
- Map:单机时可以使用map做限制,消费时查询当前消息id是不是已经存在
- Redis:使用分布式锁。
RocketMQ如何保证消息的顺序消费?
首先多个queue只能保证单个queue里的顺序,queue是典型的FIFO,天然顺序。多个queue同时消费是无法绝对保证消息的有序性的。
可以使用同一topic
,同一个QUEUE,发消息的时候一个线程去发送消息,消费的时候 一个线程去消费一个queue里的消息。
RocketMQ如何保证消息不丢失?
Producer端
采取send()
同步发消息,发送结果是同步感知的。
发送失败后可以重试,设置重试次数。默认3次。
Broker端
修改刷盘策略为同步刷盘。默认情况下是异步刷盘的。
集群部署
Consumer端
完全消费正常后在进行手动ack确认
RocketMQ如何实现分布式事务?
1、生产者向MQ服务器发送half消息。
2、half消息发送成功后,MQ服务器返回确认消息给生产者。
3、生产者开始执行本地事务。
4、根据本地事务执行的结果(UNKNOW
、commit
、rollback
)向MQ Server发送提交或回滚消息。
5、如果错过了(可能因为网络异常、生产者突然宕机等导致的异常情况)提交/回滚消息,则MQ服务器将向同一组中的每个生产者发送回查消息以获取事务状态。
6、回查生产者本地事物状态。
7、生产者根据本地事务状态发送提交/回滚消息。
8、MQ服务器将丢弃回滚的消息,但已提交(进行过二次确认的half消息)的消息将投递给消费者进行消费。
Half Message
:预处理消息,当broker收到此类消息后,会存储到RMQ_SYS_TRANS_HALF_TOPIC
的消息消费队列中
检查事务状态
:Broker会开启一个定时任务,消费RMQ_SYS_TRANS_HALF_TOPIC
队列中的消息,每次执行任务会向消息发送者确认事务执行状态(提交、回滚、未知),如果是未知,Broker会定时去回调在重新检查。
超时:如果超过回查次数,默认回滚消息。
也就是他并未真正进入Topic的queue,而是用了临时queue来放所谓的half message
,等提交事务后才会真正的将half message转移到topic下的queue。
RocketMQ的消息堆积如何处理?
1、如果可以添加消费者解决,就添加消费者的数据量
2、如果出现了queue,但是消费者多的情况。可以使用准备一个临时的topic,同时创建一些queue,在临时创建一个消费者来把这些消息转移到topic中,让消费者消费。