浅谈消息队列的几种消息模型实现

MQ发展到现在共有两种模型:队列模型、发布-订阅模型

队列模型

它允许多个生产者往同一个队列发送消息。但多个消费者之间是竞争的关系,也就是说一条消息只能被其中一个消费者接收到,读完即被删除。

https://raw.githubusercontent.com/Joker-5/image-host/master/img/20220520120357.png

发布-订阅模型

如果需要将一份消息数据分发给多个消费者,并且每个消费者都要求收到全量的消息,队列模型是无法满足这个需求的。

一个可行的方案是:为每个消费者创建一个单独的队列,让生产者发送多份。这种做法比较笨,而且同一份数据会被复制多份,也很浪费空间。而且还有一个问题,生产者必须要知道有多少个消费者,为每个消费者单独发送一份消息,这实际上违背了消息队列「解耦」这个设计初衷。

为了解决这个问题,就演化出了另外一种消息模型:发布-订阅模型。

在发布-订阅模型中,消息的发送方称为发布者(Publisher),消息的接收方称为订阅者(Subscriber), 服务端存放消息的容器称为主题(Topic)。发布者将消息发送到主题中,订阅者在接收消息之前需要先「订阅主题」。「订阅」在这里既是一个动作,同时还可以认为是主题在消费时的一个逻辑副本,每份订阅中,订阅者都可以接收到主题的所有消息。

实际上,在这种发布-订阅模型中,如果只有一个订阅者,那它和队列模型就基本是一样的了。也就是说,发布-订阅模型在功能层面上是可以兼容队列模型的。(这两种消息模型其实并没有本质上的区别,都可以通过一些扩展或者变化来互相替代。)

发布-订阅模型和队列模型的唯一不同点在于:一份消息数据是否可以被多次消费。

https://raw.githubusercontent.com/Joker-5/image-host/master/img/20220520120414.png

主流MQ的消息模型实现

现在主流消息队列使用的消息模型大多是发布-订阅模型,除了RabbitMQ。

RabbitMQ

RabbitMQ采用的消息模型是「队列模型」。那么他如何实现同一消息被多个消费者消费呢?

实际上,RabbitMQ引入了「交换机」(exchange)这一概念来解决这一问题。

在RabbitMQ中,exchange位于生产者和队列之间,生产者并不关心将消息发送给哪个队列,而是将消息发送给exchange,由exchange上配置的策略来决定将消息投递到哪些队列中。这样RabbitMQ就可以实现发表-订阅的功能了。

在这里插入图片描述

RocketMQ

RocketMQ采用的是「发布-订阅」模型。

为了保证消息消费时的可靠性,需要引入ACK机制,而ACK又要求有序,这就意味着在第一条消费被成功消费前,下一条消息是不能被消费的。为了解决这一问题,RocketMQ引入了队列(queue)的概念。

每个主题包含多个队列,通过多个队列来实现多实例并行的生产和消费。

从这里也可以看出,RocketMQ只能在队列层面上保证消息的有序性,主题层面是无法保证消息的严格顺序的。

在RocketMQ中,订阅者的概念是通过消费组(Consumer Group)来体现的。每个消费组都消费Topic中一份完整的消息,不同消费组之间消费进度彼此不受影响。也就是说,一条消息被消费组A消费过,也会再给消费组B消费。

在消费组中包含多个消费者,同一个组内的消费者是竞争消费的关系,每个消费者负责消费组内的一部分消息。如果一条消息被消费者C1消费了,那同组的其他消费者就不会再收到这条消息。

在Topic的消费过程中,由于消息需要被不同的组进行多次消费,所以消费完的消息并不会被删除,这就需要RocketMQ为每个消费组在每个队列上维护一个 offset ,这个 offset 之前的消息都被消费过,之后的消息都没有被消费过,每成功消费一条消息, offset 就加一。

这个消费位置是非常重要的概念,我们在使用消息队列的时候,丢消息的原因大多是由于消费位置处理不当导致的。

https://raw.githubusercontent.com/Joker-5/image-host/master/img/20220520122156.png

Kafka

Kafka采用的是「发布-订阅」模型。

Kafka的消息模型和RocketMQ是完全一样的(因为RocketMQ就是借鉴了Kafka的设计理念)唯一的区别是,在Kafka 中,队列这个概念的名称不一样,Kafka中对应的名称是分区(Partition),含义和功能是没有任何区别的。
https://raw.githubusercontent.com/Joker-5/image-host/master/img/20220520122156.png

参考自李玥老师《消息队列高手课》极客时间专栏,跟着老师一套学下来收获很大,墙裂推荐==

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值