多个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中,让消费者消费。

    因为项目比较大,做了分布式系统,所有远程服务调用请求都是同步执行经常出问题,所以引入了mq

    作用 描述
    解耦 系统耦合度降低,没有强依赖关系
    异步 不需要同步执行的远程调用可以有效提高响应时间
    削峰 请求达到峰值后,后端service还可以保持固定消费速率消费,不会被压垮

    问1:MQ如何集群化部署来支撑高并发访问?
    答:
    系统的流量分散在RocketMQ部署的多台机器上
    问2:RocketMQ如何分布式存储海量消息的?
    答:
    存储海量消息的机制也是分布式的存储。
    RocketMQ进程一般称为Broker,集群部署的各个Broker收到不同的消息,然后存储在自己本地的磁盘文件中。

    问3: 任何一台 Broker 突然宕机了怎么办?那不就会导致 RocketMQ 里一部分的消息就没了吗?这就会导致 MQ 的不可靠和不可用,这个问题怎么解决?
    答:
    RocketMQ的解决思路是Broker主从架构以及多副本策略。
    Master收到消息后会同步给Slave,这样一条消息就不止一份了,Master宕机了还有slave中的消息可用,保证了MQ的可靠性和高可用新。

    问4: 怎么知道有哪些 Broker ?怎么知道要连接到哪一台 Broker 上去发送和接收消息?
    答:
    有个NameServer的概念,是独立部署在几台机器上的,然后所有的Broker都会把自己注册到NameServer上去,NameServer就知道集群里有哪些Broker了!
    发送消息到Broker,会找NameServer去获取路由信息
    系统要从Broker获取消息,也会找NameServer获取路由信息,去找到对应的Broker获取消息。

    问1:RocketMQ包含了几个核心部分?
    答:
    NameServer集群、Broker集群、生产者、消费者
    NameServer
    负责管理所有的Broker消息
    让生产者和消费者鬼知道集群里有哪些Broker,然后与之通信
    Broker
    实现数据多副本存储和高可用,使用 主从架构
    生产者
    向MQ发送消息
    消费者
    从MQ获取消息
    问2:NameServer到底可以部署几台机器?为什么要集群化部署?
    答:
    部署多台,保证高可用性。

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

    问3: Broker把自己的信息注册到哪个NameServer上?
    答:
    每个Broker向所有的NameServer上注册自己的信息,即每个NameServer上有所有的Broker信息

    问4:系统如何从NameServer获取Broker信息?
    答:
    系统主动去NameServer上拉取Broker信息及其他相关信息。 //TODO 其他相关信息有哪些?

    问5:如果Broker宕了,NameServer是怎么感知到的?
    答:
    Broker会定时(30s)向NameServer发送心跳
    然后 NameServer会定时(10s)运行一个任务,去检查一下各个Broker的最近一次心跳时间,如果某个Broker超过120s都没发送心跳了,那么就认为这个Broker已经挂掉了。
    问6:Broker挂了,系统是怎么感知到的?
    答:
    主要是通过拉取NameServer上Broker的信息。
    但是,因为Broker心跳、NameServer定时任务、生产者和消费者拉取Broker信息,这些操作都是周期性的,所以不会实时感知,所以存在发送消息和消费消息失败的情况,现在 我们先知道,对于生产者而言,他是有 一套容错机制的。

    问:文中只提到生产者这有容错机制,消费者是不是应该有容错机制呢?
    答:
    //TODO

    问1:如果某个Broker没有宕机,而是该Broker和Namesrv之间的网络问题造成NameSrv认为某个Broker宕机了,Producer后续拿到新的路由信息后,其实此时Producer可以连通该Broker,此时Producer就不会给该Broker发送消息了?
    答:
    没错,就是如此

    问2:Producer发送消息到Broker,是随机选择一个Broker还是有一定的规则?
    答:
    一般是负载均衡做随机选择,但也可以走其他策略,比如根据某个字段来hash,后续会讲 //TODO

    问3:Producer是随机选择还是使用什么规则选择NameSrv获取路由信息?
    答:
    对NameSrv选择是随机的

    问4:存在这样的情况,由于网络原因Broker和部分NameSrv可以连通,会造成各个Namesrv的路由信息是不一样的,此时RocketMQ如何处理?

    问1: Master Broker 是如何将消息同步给 Slave Broker 的?
    答:
    RocketMQ自身的Master-Slave模式采取的是Pull模式拉取消息。

    问2: 消费者的系统在获取消息的时候,是从 Master Broker 获取的?还是从 Slave Broker 获取的?
    答:
    可能从Master Broker获取消息,也有可能从Slave Broker获取消息
    1、消费者的系统在获取消息的时候会先发送请求到Master Broker上去,请求获取一批消息,此时Master Broker是会返回一批消息给消费者系统的
    2、Master Broker在返回消息给消费者系统的时候,会根据当时Master Broker的 负载情况和Slave Broker的 同步情况,向消费者系统建议下一次拉取消息的时候是从Master Broker拉取还是从Slave Broker拉取。

    追问个问题:

    问题1:Master会向消费者建议下次拉取信息的地方,也就是说Master里面会监控本身的qps和slave的数据同步情况?

    问题2:Master给消费者返回数据时会带上相关负载和数据同步情况的信息,如果遵循Master的建议从slave拉取,那么后续访问slave会有这些信息么?如果没有那么消费者后续采用什么策略区拉取数据?是一直从slave一直取数据,还是说会定时再去从Master获取这些信息

    答:这个涉及到了很多源码级别的细节了,继续跟着专栏学习,后面会在底层原理剖析环节分析你的问题。


    问3: 如果 Slave Broker 挂掉了,会对整个系统有影响吗?
    答:
    有一点影响,但是影响不太大,因为消息写入全部是发送到Master Broker的,获取消息也可以Master获取,少了Slave Broker,会导致所有读写压力都集中在Master Broker

    问4: Master Broker 突然挂了,这样会怎么样?
    答:
    RocketMQ 4.5版本之前,用Slave Broker同步数据,尽量保证数据不丢失,但是一旦Master故障了,Slave是没法自动切换成Master的。
    所以在这种情况下,如果Master Broker宕机了,这时就得手动做一些运维操作,把Slave Broker重新修改一些配置,重启机器给调整为Master Broker,这是有点麻烦的,而且会导致中间一段时间不可用。

    问5: 基于 Dledger 实现 RocketMQ 高可用自动切换
    RocketMQ 4.5之后支持了一种叫做Dledger机制,基于Raft协议实现的一个机制。
    我们可以让一个Master Broker对应多个Slave Broker, 一旦 Master Broker 宕机了,在多个 Slave 中通过 Dledger 技术 将一个 Slave Broker 选为新的 Master Broker 对外提供服务。
    在生产环境中可以是用Dledger机制实现自动故障切换,只要10秒或者几十秒的时间就可以完成


    问:从上文描述感觉是从哪读是Master来决定的,那么 Master宕机后,slave还可读么?
    答:可读

    问:Master宕机了, 修改slave为Master, 此时如果有的消息没有同步到slave,这个时候要丢失部分数据,丢失的数据如何处理呢?
    答:
    对的,master挂了应该让slave提供读,同时修复master,但4.5以后通常建议用dledger自动切换
    //TODO
    问:Master宕机了,修改slave为Master,有段时间读写都不可用,为什么不修复Master?这样至少可以保证可以从slave读数据,而且修复Master后不会丢已经写入的数据
    答:
    master宕机了,读可以继续从slave走,并不是读写都不可用, 后续会深入剖析如何保证数据不丢,要同时设置刷盘策略和副本同步相关配置

    问:现在Broker slave主动从Master拉取消息,一旦Master宕机,是不就会丢失一部分消息?不是说RocketMQ可以保证不丢消息么?
    答:
    是的,后续会深入剖析如何保证数据不丢,要同时设置刷盘策略和副本同步相关配置。//TODO