为什么选择RocketMQ
Apache RocketMQ 自诞生以来,因其架构简单、业务功能丰富、具备极强可扩展性等特点被众多企业开发者以及云厂商广泛采用。历经十余年的大规模场景打磨,RocketMQ 已经成为业内共识的金融级可靠业务消息首选方案,被广泛应用于互联网、大数据、移动互联网、物联网等领域的业务场景。
想要深入理解RocketMQ架构设计可以从以下链接了解:
1.RocketMQ官网
2.github源码地址
可以从docs目录中去了解rocketMQ的设计,阅读源码最好从宏观上去理解,一行一行去理解效果不佳
RocketMQ设计目的
RocketMQ主要面向高性能、高可靠性的分布式消息中间件,而同样是消息队列的RabbitMQ更多地关注开发者友好、适用于各种不同场景的消息中间件。
领域模型
消息的生产
由生产者(Producer)负责生产消息,消息可以是任意类型,此外还可以设置多种发送机制,比如同步,异步,批量发送
消息存储
-
Topic(主题)
在RocketMQ中消息由生产者发送之后会传递到Topic队列中,Broker管理所有Topic,Topic默认有四个队列,这个可以通过可视化工具或者源码等手段查看,说实话我在源码中没看到是哪定义的,只看到默认读写队列数量是16个
Topic是消息存储的顶层容器,用于标识同一类业务逻辑的消息。根据不同的业务逻辑把业务消息传递到合适的Topic中,Topic下还可以通过tag属性来过滤消息,让消费者更细粒度订阅消费消息。 -
MessageQueue(队列)
RocketMQ 基于队列的存储模型可确保消息从任意位点读取任意数量的消息,以此实现类似聚合读取、回溯读取等特性,这些特性是RabbitMQ、ActiveMQ等非队列存储模型不具备的。
-
队列的主要作用如下:
存储顺序性:
队列天然具备顺序性,即消息按照进入队列的顺序写入存储,同一队列间的消息天然存在顺序关系,队列头部为最早写入的消息,队列尾部为最新写入的消息。消息在队列中的位置和消息之间的顺序通过位点(Offset)进行标记管理。
流式操作:
流式操作是指对一组数据进行一系列的处理操作,不断地产生新的结果数据,并且这些操作之间是连续不断的,像流水线一样不断进行。例如过滤、转换、排序、聚合等操作,以及将这些处理后的消息再发送给下一个处理步骤。
-
-
Message(消息):
消息是 Apache RocketMQ 中的最小数据传输单元。有以下两个特点:
1. 消息不可变性
消息本质上是已经产生并确定的事件,一旦产生后,消息的内容不会发生改变。5.x版本中,消息本身不可编辑,消费端获取的消息都是只读消息视图。 但在历史版本3.x和4.x版本中消息不可变性没有强约束。
2.消息持久化
RocketMQ 会默认对消息进行持久化,即将接收到的消息存储到一个名为CommitLog的文件中。
队列还有四种类型:Normal:普通消息。FIFO:顺序消息。Delay:定时/延时消息。Transaction:事务消息。
在顺序消息这点上RocketMQ跟RabbitMQ不同的是RocketMQ的顺序消息可以通过设置同步刷盘或异步刷盘来保证消息的可靠性;而RabbitMQ的顺序消息需要保证每个消息只被一个消费者消费,否则可能会导致消息的重复消费或丢失,RabbitMQ想要提高可靠性需要通过消息确认或死信队列等特殊手段。
消息消费
消费者分组(ConsumerGroup):
RocketMQ 发布订阅模型中定义的独立的消费身份分组,用于统一管理底层运行的多个消费者(Consumer)。同一个消费组的多个消费者必须保持消费逻辑和配置一致,共同分担该消费组订阅的消息,实现消费能力的水平扩展,而不是同一组消费者消费不同的消息。
消费者(Consumer):
根据不同的业务场景设置不同的消费者类型,消费者必须关联一个指定的消费者分组,以获取分组内统一定义的行为配置和消费状态。
整个架构的流程是由生产者(Producer)生产消息,然后会持久化到CommitLog文件中,通过同步刷盘或异步刷盘的方式写入到broker中存储消息,值得注意的是在这过程中使用了MMAP零拷贝技术提升性能,此外还会将CommitLogOffset、msgSize、tagsCode写入到ConsumerQueue中,相当于存储了消息的索引,消费者通过索引可以更快找到消息消费