只记录了基本的一些内容,详细参考官方文档https://github.com/apache/rocketmq/tree/master/docs/cn
1.rocketMQ基本概念
1.1消息模型
RocketMQ主要由 Producer、Broker、Consumer 三部分组成,其中Producer 负责生产消息,Consumer 负责消费消息,Broker 负责存储消息。Broker 在实际部署过程中对应一台服务器,每个 Broker 可以存储多个Topic的消息,每个Topic的消息也可以分片存储于不同的 Broker。Message Queue 用于存储消息的物理地址,每个Topic中的消息地址存储于多个 Message Queue 中。ConsumerGroup 由多个Consumer 实例构成。
1.2生产者
RocketMQ提供多种发送方式,同步发送、异步发送、顺序发送、单向发送。同步和异步方式均需要Broker返回确认信息,单向发送不需要。
1.3消费者
消费者有两种获取消息的方式,拉取式以及推动式(实时性高)
1.4生产者组
这类Producer发送同一类消息且发送逻辑一致。如果发送的是事务消息且原始生产者在发送之后崩溃,则Broker服务器会联系同一生产者组的其他生产者实例以提交或回溯消费。
1.5消费者组
消费者组的消费者实例必须订阅完全相同的Topic。RocketMQ 支持两种消息模式:集群消费(Clustering)和广播消费(Broadcasting)。
集群消费下每个实例平均分摊消息
广播模式每个实例都接收全量消息
1.6普通顺序消息
普通顺序消费模式下,消费者通过同一个消息队列( Topic 分区,称作 Message Queue) 收到的消息是有顺序的,不同消息队列收到的消息则可能是无顺序的。
1.7严格顺序消息
严格顺序消息模式下,消费者收到的所有消息均是有顺序的。
1.8标签
为消息设置的标志,用于同一主题下区分不同类型的消息
1.9 名字服务
名称服务充当路由消息的提供者。生产者或消费者能够通过名字服务查找各主题相应的Broker IP列表, 其实就是broker的注册中心,多个Namesrv实例组成集群,但相互独立,没有信息交换。
NameServer集群中就有Topic跟Broker的映射关系。
收发消息前,先创建Topic,创建Topic时需要指定该Topic要存储在哪些Broker上,也可以在发送消息时自动创建Topic。
消息生产者Producer作为客户端发送消息时候,需要根据消息的Topic从本地缓存的TopicPublishInfoTable获取路由信息。如果没有则更新路由信息会从NameServer上重新拉取,同时Producer会默认每隔30s向NameServer拉取一次路由信息。
消息生产者会从获取的路由信息选择一个队列(MessageQueue)进行消息发送,Broker作为消息的接收者接收消息并落盘存储。
2.特性
2.1消息顺序
消费顺序有全局顺序消息和分区顺序消息,全局顺序消息指的是某个topic下的消息都要保持顺序。
分区顺序 对于指定的一个 Topic,所有消息根据 sharding key 进行区块分区。 同一个分区内的消息按照严格的 FIFO 顺序进行发布和消费。 Sharding key 是顺序消息中用来区分不同分区的关键字段,和普通消息的 Key 是完全不同的概念。 适用场景:性能要求高,以 sharding key 作为分区字段,在同一个区块中(同一队列)严格的按照 FIFO 原则进行消息发布和消费的场景。
注意:顺序消费的原理解析,在默认的情况下消息发送会采取Round Robin轮询方式把消息发送到不同的queue(分区队列);而消费消息的时候从多个queue上拉取消息,这种情况发送和消费是不能保证顺序。但是如果控制发送的顺序消息只依次发送到同一个queue中,消费的时候只从这个queue上依次拉取,则就保证了顺序。当发送和消费参与的queue只有一个,则是全局有序;如果多个queue参与,则为分区有序,即相对每个queue,消息都是有序的。
一个消费者可以消费多个队列,一个消息队列同时只能被一个消费者消费(参考原理)
2.2 消息过滤
可以在BROKER端根据TAG进行过滤
2.3 保证至少投递一次
消费者消费成功后,才会向服务器返回ACK,至于为什么是至少一次,而不是一次,因为MQ的重试机制,如果因为网络等原因,ROCKET可以会重复发送消息,导致消费者重复消费
2.4 事务消息
RocketMQ事务消息(Transactional Message)是指应用本地事务和发送消息操作可以被定义到全局事务中,要么同时成功,要么同时失败。RocketMQ的事务消息提供类似 X/Open XA 的分布事务功能,通过事务消息能达到分布式事务的最终一致。
2.5 消息重试
如果消费者消费失败,rockert会针对该消费组建立一个TOPIC的重试队列,根据不同的重试级别,重试延时一次比一次久,达到最大重试次数后,若消费依然失败,会把该消息放入死信队列,可以通过控制台触发重新消费
2.6 消息重投
生产者在发送消息时,同步消息失败会重投,异步消息有重试,oneway没有任何保证(因为没有ACK)。消息重投保证消息尽可能发送成功、不丢失,但可能会造成消息重复
2.7 流量控制
生产者触发流控,消息发送失败
3.rocketMQ架构设计
3.1 消息存储
CommitLog:消息都是保存在CommitLog,顺序写入,文件满了再写入下一个。
ConsumeQueue:ConsumeQueue(逻辑消费队列)作为消费消息的索引,保存了指定Topic下的队列消息在CommitLog中的起始物理偏移量offset,消息大小size和消息Tag的HashCode值。consumequeue文件可以看成是基于topic的commitlog索引文件。
ConsumeQueue逻辑消费队列存储的数据较少,并且是顺序读取,在page cache机制的预读取作用下,Consume Queue文件的读性能几乎接近读内存,即使在有消息堆积情况下也不会影响性能。
IndexFile:提供了一种可以通过key或时间区间来查询消息的方法,IndexFile的底层存储设计为在文件系统中实现HashMap结构,故rocketmq的索引文件其底层实现为hash索引。