RocketMQ 使用的消息模型

队列技术模型

image.png

发布 - 订阅模型

生产者就是发布者,消费者就是订阅者,队列就是主题,并没有本质的区别。它们最大的区别其实就是,一份消息数据能不能被消费多次的问题。实际上,在这种发布 - 订阅模型中,如果只有一个订阅者,那它和队列模型就基本是一样的了。也就是说,发布 - 订阅模型在功能层面上是可以兼容队列模型的。现代的消息队列产品使用的消息模型大多是这种发布 - 订阅模型,当然也有例外

image.png

队列在 RocketMQ 中的作用是什么呢?

这就要从消息队列的消费机制说起。 几乎所有的消息队列产品都使用一种非常朴素的“请求 - 确认”机制,确保消息不会在传递过程中由于网络或服务器故障丢失。

生产者 --> 服务端

在生产端,生产者先将消息 发送给服务端,也就是Broker,服务端在收到消息并将消息写入主题或者队列中后,会给 生产者发送确认的响应。 如果生产者没有收到服务端的确认或者收到失败的响应,则会重新发送消息;

服务端 --> 消费者

在消费端,消费者在收到消息并完成自己的消费业务逻辑(比如,将数据保存到数据库中)后,也会给服 务端发送消费成功的确认,服务端只有收到消费确认后,才认为一条消息被成功消费,否则 它会给消费者重新发送这条消息,直到收到对应的消费成功确认。

这个确认机制很好地保证了消息传递过程中的可靠性,但是,引入这个机制在消费端带来了 一个不小的问题。什么问题呢?为了确保消息的有序性,在某一条消息被成功消费之前,下 一条消息是不能被消费的,否则就会出现消息空洞,违背了有序性这个原则。 也就是说,每个主题在任意时刻,至多只能有一个消费者实例在进行消费,那就没法通过水 平扩展消费者的数量来提升消费端总体的消费性能。为了解决这个问题,RocketMQ 在主 题下面增加了队列的概念。

一个主题多队列,保证水平扩展,满足高并发

每个主题包含多个队列,通过多个队列来实现多实例并行生产和消费。需要注意的是, RocketMQ 只在队列上保证消息的有序性,主题层面是无法保证消息的严格顺序的。

消费者与消费组

RocketMQ 中,订阅者的概念是通过消费组(Consumer Group)来体现的。每个消费组 都消费主题中一份完整的消息,不同消费组之间消费进度彼此不受影响,也就是说,一条消息被 Consumer Group1 消费过,也会再给 Consumer Group2 消费。 消费组中包含多个消费者,同一个组内的消费者是竞争消费的关系,每个消费者负责消费组 内的一部分消息。如果一条消息被消费者 Consumer1 消费了,那同组的其他消费者就不 会再收到这条消息。

消费位置

在 Topic 的消费过程中,由于消息需要被不同的组进行多次消费,所以消费完的消息并不会立即被删除,这就需要 RocketMQ 为每个消费组在每个队列上维护一个消费位置 (Consumer Offset),这个位置之前的消息都被消费过,之后的消息都没有被消费过, 每成功消费一条消息,消费位置就加一。这个消费位置是非常重要的概念,我们在使用消息 队列的时候,丢消息的原因大多是由于消费位置处理不当导致的。

image.png
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容