你们好,我是Java最全面试题库
的提裤姐,今天这篇是中间件面试题系列的第二篇,主要总结了RocketMQ相关的面试题;在后续,会沿着第一篇开篇的知识线路一直总结下去,作到日更!若是我能作到百日百更,但愿你也能够跟着百日百刷,一百天养成一个好习惯。java
RabbitMQ
erlang开发,对消息堆积的支持并很差,当大量消息积压的时候,会致使 RabbitMQ 的性能急剧降低。每秒钟能够处理几万到十几万条消息。面试
RocketMQ
java开发,面向互联网集群化
,功能丰富,对在线业务的响应时延作了不少的优化,大多数状况下能够作到毫秒级的响应,每秒钟大概能处理几十万条消息。数据库
Kafka
Scala开发,面向日志
,功能丰富,性能最高。当你的业务场景中,每秒钟消息数量没有那么多的时候,Kafka 的时延反而会比较高。因此,Kafka 不太适合在线业务场景。服务器
ActiveMQ
java开发,简单,稳定,性能不如前面三个。不推荐。网络
Nameserver
无状态,动态列表;这也是和zookeeper的重要区别之一。zookeeper是有状态的。异步
Producer
消息生产者,负责发消息到Broker。分布式
Broker
就是MQ自己,负责收发消息、持久化消息等。性能
Consumer
消息消费者,负责从Broker上拉取消息进行消费,消费完进行ack。优化
集群消费线程
广播消费
出现缘由
正常状况下在consumer真正消费完消息后应该发送ack,通知broker该消息已正常消费,从queue中剔除
当ack由于网络缘由没法发送到broker,broker会认为词条消息没有被消费,此后会开启消息重投机制把消息再次投递到consumer。
消费模式:在CLUSTERING
模式下,消息在broker中会保证相同group的consumer消费一次,可是针对不一样group的consumer会推送屡次
解决方案
首先多个queue只能保证单个queue里的顺序,queue是典型的FIFO,自然顺序。多个queue同时消费是没法绝对保证消息的有序性的。
可使用同一topic
,同一个QUEUE,发消息的时候一个线程去发送消息,消费的时候 一个线程去消费一个queue里的消息。
Producer端
采起send()
同步发消息,发送结果是同步感知的。
发送失败后能够重试,设置重试次数。默认3次。
Broker端
修改刷盘策略为同步刷盘。默认状况下是异步刷盘的。
集群部署
Consumer端
彻底消费正常后在进行手动ack确认
一、生产者向MQ服务器发送half消息。
二、half消息发送成功后,MQ服务器返回确认消息给生产者。
三、生产者开始执行本地事务。
四、根据本地事务执行的结果(UNKNOW
、commit
、rollback
)向MQ Server发送提交或回滚消息。
五、若是错过了(可能由于网络异常、生产者忽然宕机等致使的异常状况)提交/回滚消息,则MQ服务器将向同一组中的每一个生产者发送回查消息以获取事务状态。
六、回查生产者本地事物状态。
七、生产者根据本地事务状态发送提交/回滚消息。
八、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。
一、若是能够添加消费者解决,就添加消费者的数据量二、若是出现了queue,可是消费者多的状况。可使用准备一个临时的topic,同时建立一些queue,在临时建立一个消费者来把这些消息转移到topic中,让消费者消费。