对于每种消息队列,基本上都有自己的消息模型,像是队列 Queue 主题 Topic 分区 Partition这些概念,但是不同的消息队列中的含义还是不同的

这也是源于了不同的消息队列的架构演进之路,在早期的实现中,消息队列就是源于队列的一个概念,严格保证消息有序,并且先进先出的

生产者入队消息,消费者消费消息,中间的消息容器就是队列

图片

如果有多个生产者去生产放入消息,那么这个队列就是消息的集合

那么如果有多个消费者消费,那么彼此之间就是竞争的关系

如果需要将一份消息分发给多个消息者,要求每个消费者都能收到全量的消息,那么单个队列就需要变为多个队列,每个消费者一份

但是这样违背了消息队列解耦的设计初衷

所以另一种设计的模型出现了,”发布-订阅”模型

图片

发送方称为发布者,接收方称为订阅者,服务端存放消息的容器称为主题 Topic,发布方将消息放在一个主题的容器里,订阅者订阅这个主题,就可以接受到这个主题的所有消息

两者最大的区别就是一份消息数据中能不能被消费多次的问题

那么我们看下不同的消息对垒的模型实现

1.RabbitMQ,坚持使用队列模型,但是也实现了订阅的方式,因为内部有一个Exchange模块,Exchange位于生产者和队列之间,生产者并不关心将消息发给哪个队列,而是直接发给Exchange,Exchange来决定发给哪个队列

图片

内部也是维护了多个消息队列的

2.RocketMQ的消息模型

标准的模型,内部也是维护了队列,在其中,消息队列利用了朴素的 请求-确认机制,无论是生产者还是消费者,都需要在交互的过程中和消息队列进行确认响应

为了保证这个请求-确认能够确保并行生产和消息,所以RocketMQ内部将其进行了分区,分为了消费组,每个消费组内有份完整的消息,不同的消费组彼此不影响,但是消费组内的消费是竞争消费的关系,整体的架构如下

图片

最后是Kafka的消息模型

Kafka的消息模型和RocketMQ基本一致,只不过Kafka中的队列概念,替换为了分区 Partition,含义和功能是基本一致的

本章主要是说了消息队列中的两种模型 队列模型和发布-订阅模型

但是RabbitMQ虽然采用的队列模型,但是可以实现发布-订阅的能力

所以二者并非对立,而是可以相互转换的

问题是,是否能做到单个队列的并行消费呢?

首先说对于单个队列的并行消费,必然存在竞争,那么抛开竞争

针对这个问题,我首先想到的是借鉴TCP协议的传输方式

SACK传输加上滑动窗口协议

1.SACK传输实现简单就是消费者返回已经确认的消息序号给队列,确认已接受

2.然后再利用滑动窗口协议,我们将队列分为 已发送已确认,已发送未确认,未发送可发送,不可发送四个部分,然后通过消费的速率不断调整窗口大小,以及保证已发送和可发送的剩余来不断的进行消费

发表评论

邮箱地址不会被公开。 必填项已用*标注