2.RocketMQ中的Topic和JMS的queue有什么区别
  queue 就是来源于数据结构的 FIFO 队列。而 Topic 是个抽象的概念,每个 Topic 底层对应N个 queue,而数据也真实存在 queue 上的。

3.RocketMQ Broker中的消息被消费后会立即删除吗
  「不会」,每条消息都会持久化到CommitLog中,每个Consumer连接到Broker后会维持消费进度信息,当有消息消费后只是当前Consumer的消费进度(CommitLog的offset)更新了。

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

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

4.RocketMQ消费模式有几种
  消费模型由 Consumer 决定,消费维度为 Topic。

  集群消费
    一条消息只会被同Group中的一个Consumer消费
    多个Group同时消费一个Topic时,每个Group都会有一个Consumer消费到数据
  广播消费
    消息将对一 个 Consumer Group 下的各个 Consumer 实例都消费一遍。即即使这些 Consumer 属于同一个 Consumer Group ,消息也会被 Consumer Group 中的每个 Consumer 都消费一次。
5.RocketMQ消息是push还是pull
  RocketMQ没有真正意义的push,都是pull,虽然有push类,但实际底层实现采用的是「长轮询机制」,即拉取方式

  broker端属性 longPollingEnable 标记是否开启长轮询。默认开启
6.为什么要主动拉取消息而不适用事件监听方式

  事件驱动方式是建立好长连接,由事件(发送数据)的方式来实时推送

  如果Broker主动推送消息的话可能push速度快,消费速度慢的情况,那么就会造成消息在Consumer端堆积过多,同时又不能被其他consumer消费的情况。而pull的方式可以根据当前自身情况来pull,不会造成

  过多的压力而造成瓶颈。所以采用pull方式.

7. Broker如何处理拉去请求的

  Consumer首先请求Broker Broker是否有符合条件的消息

  有:相应Consumer 等待下次Consumer的请求

  没有:

  DefaultMessageStore#ReputMessageService#run方法

  PullRequesetHoldService来hold连接,每个5s执行一次检查pullRequestTable有没有消息,有点话立即推送每隔1ms检查commitLog中是否有新消息,有的话写入到pullRequestTable

  当有新消息的返回请求

  挂起consumer的请求,即不断开连接,也不返回数据

  使用consumer的offset 

8.RocketMQ如何做负载均衡

 通过Topic再多个Broker中分布式存储实现

  1.producer端

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

   a.提升写入吞吐量,当多个producer同时向一个broker写入数据的时候,性能会下降

   b.消息分布在多个broker中,为负载消费做准备

  默认策略是随机选择

    producer维护一个index

    每次取节点会自增

    index向所有broker个数取余

    自带容错策略

  2.consumer端

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

  3.其他负载均衡算法

     平均分配策略

     环形分配策略

    手动配置分配策略

    机房分配策略

    一致性哈希分配策略

    靠近机房分配策略

9.Topic创建的模式

  手动创建:

  1.集群模式:当前模式下,Broker中Queue数量相等

  2.Broker模式:当前模式下,Broker的的queue可以不一样

  自动创建topic的时候,默认是Broker模式,会为每一个Broker创建4个Queue

10.读写队列问题

  从物理上看,读写队列是相同队列,所以不会出现读写队列数据同步问题

  从逻辑上看,分为读写队列,一般数量是相等的

  例如:创建Topic的时候,读队列为4个,写队列为8个,那么系统会创建8个队列,0-7,可读队列为0-3 Producer会将消息写入0-7的Queue,Consuemr会消费0-3的队列

     创建topic的时候,读队列为8个,写队列为4个,那么系统会创建8个队列,0-7,可读的队列为0-7 procuer会将消息写入0-3的Queue,Consuemer会消费0-7的Queue,不过4-7的Queue无数据

     假设Consumer1消费0-3,Consuemer2消费4-7,那么Consuemer2没有消息消费

11.当消费负载均衡consumer和queue不对等的时候会发生什么

  Consumer和Queue会优先平均分配,如果Consuemr少于queue的个数,则会存在部分Consummer消费多个queue的情况。如果Consumer等于queue的个数,那么就是一个consumer消费一个queue,如果Consumer个数大于queue的个数,那么会有部分Consumer空余出来,白白的浪费了

12.消息重复消费如何解决?

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

  【引起重复消费的原因】 

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

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

  【解决方案】

    a.数据库表  处理消息前,使用消息主键再表中带有约束字段的insert

    b.Map   单机是可以使用map ConcurrentHashMap-> putlfAbsent guava cache

    c.Redis 

      分布式锁

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

  首先多个queue只能保证单个queue里的顺序,queue是典型的FIFO,天然顺序。多个queue同时消费时无法绝对保证消息的有序性。所以总结如下:

  同一个topic,同一个Queue,发消息的时候一个线程去发送消息,消费的时候一个线程去消费一个queue里的消息

14.怎么保证消息发到同一个queue

  RocketMQ给我们提供了MessageQueueSeletor接口,可以自己重写里面的接口,实现自己的算法,举个最简单的例子:判断i/2==0,那就放到queue1里,否则放到queue2里

15.RocketMQ如何保证消息不丢失

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

  Producer端

  Broker端

  Consumer端

  1.Producer端如何保证消息不丢失

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

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

   【集群部署】,比如发送失败了的原因可能是当前Broker宕机了,重试的时候会发送到其他Broker上。

  2.Broker端如何保证消息不丢失

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

   集群部署,主从模式,高可用

      3.Consumer端如何保证消息不丢失

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

16.RocketMQ的消息堆积如何处理

  首先找打是什么原因导致消息堆积,Producer太多了,Consuemr太少了导致的还是其他情况,总之先定位原因

  然后看下消息消息速度是否正常,正常的话,可以通过上线更多的Consumer临时解决消息堆积问题

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

  1.准备一个临时的topic

  2.queue的数量是堆积的几倍

  3.queue分布到多个Broker中

  4.上线一台Consumer做消息的搬运工,把原来topic中的消息挪到新的Topic里,不做业务逻辑处理,只是挪过去

  5.上线N台Consumer同时消费临时topic中的数据

  6.改bug

    7.恢复原来的Consumer,继续消费之前的topic

18.堆积消息会超时删除吗?

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

19.堆积的消息会不会进入死信队列

  【不会】,消息在消费失败后会进入重试队列(%RETRY%+ConsumerGroup),18次才会进入死信队列(%DLQ%+ConsumerGroup)

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

  分布式系统中事务可以使用【TCC】(Try,Confirm,Cancel),【2pc】来解决分布式系统中的消息原子性  

  RocketMQ4.3+提供分布式事务功能,通过RocketMQ事务消息能达到分布式事务的最终一致

  【RocketMQ实现方式:】

    【Half message】:预处理消息,当broker收到此类消息后,会存储到RMQ_SYS_TRANS_HALF_TOPIC的消息消费队列中

    【检查事务状态】:Broker会开启一个定时任务,消费RMQ_SYS_TRANS_HALF_TOPIC队列中的消息,每次执行任务会向消息发送者确认事务执行状态(提交,回滚,未知),如果是未知,Broker会定时去回调在重新检查

    【超时】:如果超过回查次数,默认回滚消息

  也就是他并未真正进入Topic的queue,而是用了临时queue来放所谓的half message,等提交事务后,才会真正的将half message 转移到topic下的queue。

21.高吞吐量下如何优化生产者和消费者的性能

  开发

    消息批量拉去,业务逻辑批量处理,同一个group下,多机部署,并行消费,单个Consumer提高线程个数,批量消费

  运维

    网卡调优,jvm调优,多线程与cpu调优,Page Cache

22.RocketMQ是如何保证数据的高容错性的

  在不开启容错的情况下,轮询队列进行发送,如果失败了,重试的时候过滤失败的Broker

  如果开启了容错策略,会通过RocketMQ的预测机制来预测一个Broker是否可用

  如果上次失败了的Broker可用那么还是会选择该Broker的队列

  如果上述情况失败,则随机选择一个进行发送

  在发送消息的时候会记录一下调用的时间与是否报错,根据该时间去预测broker的可用时间

23.任何一台Broker突然宕机了怎么办?

  Broker主从架构以及多副本策略。Master收到消息后会同步Slave,这样一条消息就不止一份了,Master宕机了还有slave中消息可用,保证了MQ的可靠性和高可用性。而且RocketMQ4.5.0开始支持Dlegder模式,基于raft的,做了真正意义的HA. 

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

  每个Broker会向所以的NameServer上注册自己的信息。即每个NameServer上有所有的Broker信息

25.RocketMQ如何分布式存储海量消息的

 Rocketmq进程一般称为Broker,集群部署的各个Broker收到不同的消息,然后存储再自己本地的磁盘文件中

26.任何一台Broker突然宕机了怎么办?还能使用吗?消息会不会丢

  RocketMQ的解决思路是Broker主从架构以及多副本策略。

  Master收到消息后会同步给slave,这样一条消息不止一份了,Master宕机了还有slave中消息可用,保证了MQ的可靠性和高可用性

27.怎么知道有哪些Broker?如何知道连接那个broker?

  有个NameServer的概念,是独立部署在几台机器上的,然后所有的Broker都会把自己注册到NameServer上去,NameServer就知道集群有哪些Broker

  发送消息到Broker,会找到NameServer去获取路由信息,系统要从Broker获取信息,也会找NameServer获取路由信息,去找到对应的Broker获取消息

28.NameServer到底可以部署几台机器?为什么要集群化部署?

  部署多台,保证高可用性。

  集群化部署是为了高可用性,NameServer是集群里非常关键的一个角色,如果部署一台NameServer,宕机会导致RocketMQ集群出现故障,所以NameServer一定会多机器部署,实现一个集群,起到高可用的效果

29.系统如何从NameServer获取Broker信息?

  系统主动去NameServer上拉去Broker信息及其他相关信息

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

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

31.Broker挂了,系统怎么感知的?

  主要是通过拉去NameServer上Broker的信息。但是,因为Broker心跳,NameServer定时任务,生产者和消费者拉去Broker信息,这些操作都是周期性的,所以不会实时感知,所以存在发送消息和消费消息失败的情况,

  对于生产者而言,他是有一套容错机制的

32.Master Broker 是如何将消息同步给Slave Broker的?

  RocketMQ自身的Master-Slave 模式采取Pull模式拉取消息.

33.消费消息时是从Master获取还是Slave获取?

  可能从Master Broker获取也可能从slave获取消息

  a.消费者的系统在获取消息的时候会先发送请求到Master Broker上去,请求获取一批消息,此时Master Broke是返回一批消息给消费者系统的

  b.Master Broker 在返回消息给消费者系统的时候,会根据当时Master Broker的负载情况和slave Broker 的同步情况,向消费者系统建议下一次拉去消息的时候是从Master Broker 拉取还是从Slave Broker拉取

34.如果Slave Broker 挂掉了,会对整个系统有影响吗?

  有一点影响,但是影响不太大,因为消息写入全部是发送到Master Broker的,获取消息也可以master获取,少了Slave Broker ,会导致所以读写压力集中在Master Broker

35.Master Broker 突然挂了,这样会怎么样?

 [RocketMQ4.5版本之前],用slave Broker 同步数据,尽量保证数据不丢失,但是一旦Master故障了,Slave是没发自动切换成Master的,所以在这种情况下,如果Master Broker宕机了,这时就得手动做一些运维操作,

 把Slave Broker 重新配置修改一些配置,重启机器给调整为Master Broker 这是有点麻烦,而且会导致中间一段时间不可用

 【RocketMQ4.5之后】支持了一种叫做Dledger机制,基于Raft协议实现了一个机制,我们可以让一个Master Broker对应多个Slave Broker,一旦Master Broker宕机了,在多个Slave中通过Dledger技术将一个Slave Broker选为新的Master Broker对外

 提供服务。在生产环境中可以是用Dledger机制实现自动故障切换,只要10s或者几十秒的时间就可以完成