现在的位置: 首页 > 综合 > 正文

队列模型、主题模型和消息模型是什么

2020年02月12日 综合 ⁄ 共 1805字 ⁄ 字号 评论关闭

  ​首先,我要问一个问题:为什么消息队列被称为消息队列?

  你可能认为它很弱智。这不就是一个存储消息的队列吗?消息队列的名称是什么?

  事实上,早期的消息中间件是通过排队模型实现的,这可能是一个历史原因。我们习惯于将消息中间件作为消息队列。

  然而,现在,像rocketmq和Kafka这样优秀的消息中间件不仅通过队列存储消息。

  队列模型

  正如我们对队列的理解一样,消息中间件的队列模型实际上只是一个队列。让我画张图让你明白:

  一开始,我提到了“广播”的概念。也就是说,如果我们此时需要向多个消费者发送消息(例如,我此时需要将消息发送到SMS系统和email系统),那么单个队列无法满足需求。

  当然,您可以将生产者生产消息放入多个队列,然后每个队列对应于每个消费者。这个问题可以解决。创建多个队列和复制多条消息将极大地影响资源和性能。而且,这样,生产者需要知道消费者的具体数量,然后复制相应数量的消息队列,这违背了我们的消息中间件分离的原则。

  主题模型

  有解决这个问题的好办法吗?是的,它是主题模型或发布和订阅模型。

  感兴趣的学生可以在设计模式中学习观察者模式并手动实现。我相信你会有所收获的。

  在主题模型中,消息的生产者称为发布者,消息的使用者称为订阅者,存储消息的容器称为主题。

  其中,发布者将消息发送到指定主题,订阅者需要提前订阅该主题才能接受特定主题的消息。

  rocketmq中的消息模型

  rockermq中的消息模型是根据主题模型实现的。你可能想知道这个主题是如何实现的。你上面没提过!

  事实上,对于主题模型的实现,每个消息中间件的底层设计是不同的,如Kafka中的分区、rocketmq中的队列和rabbitmq中的交换。我们可以理解,主题模型/发布/订阅模型是一个标准,而那些中间件只能根据这个标准来实现。

  那么,rocketmq中的主题模型是如何实现的呢?首先,我要画一幅画,你可以试着理解它。

  我们可以看到,在整个数字中有生产者群体、话题群体和消费者群体。让我分别介绍一下。

  生产者组生产者组:它代表某种生产者。例如,我们有多个seckill系统作为生产者,它们一起是生产者组生产者组。它们通常产生相同的信息。

  消费者群体消费者群体:它代表某种类型的消费者。例如,我们有多个作为消费者的SMS系统,它们一起是一个消费者组消费者组。它们通常会使用相同的消息。

  主题:表示一种消息类型,如订单消息、物流消息等。

  可以看到,图中producer组中的生产者向主题发送消息,并且主题中有多个队列。生产者在每个生产消息之后向指定主题中的特定队列发送消息。

  每个主题中都有多个队列(此处不涉及代理)。在集群消费模式下,一个消费者集群中的多台机器消费一个主题的多个队列,而只有一个消费者消费一个队列。如果一个消费者挂断电话,该组中的其他消费者将继续消费,而不是挂断电话的消费者。与上图一样,consumer1和consumer2分别对应于两个队列,而consumer3不对应于一个队列,因此通常需要控制consumer组中的consumer数和subject中的队列数。

  当然,消费者的数量可以小于队列的数量,但不建议这样做。

  每个消费组在每个队列上维护一个消费位置。为什么?

  因为我们刚才画的只是一个消费群,我们知道在发布订阅模式下,一般涉及多个消费群,每个消费群在每个队列中的消费位置是不同的。如果此时存在多个消费者组,则消息在被一个消费者组消费后将不会被删除(因为其他消费者组也需要它)。它只为每个消费群体保持一个消费位移(抵消)。每次消费组消费完成后,都会返回一个成功的响应,然后队列将维护的消费置换添加一个,这样刚刚消费的消息就不会再次消费。

  也许您还有一个问题,为什么需要在一个主题中维护多个队列?

  答案是提高并发性。实际上,每个主题可能只有一个队列。您认为如果每个主题中只有一个队列,那么这个队列还维护每个消费者组的消费位置,这也可以实现发布和订阅模式。

  但是,我的制作者只能向一个队列发送消息吗?由于需要维护消费位置,一个队列只能对应一个消费群中的消费者,因此其他消费者没有用处。从这两个角度来看,并发性要小得多。

  总之,rocketmq通过在一个主题中配置多个队列并维护每个队列中每个消费者组的消费位置来实现主题模式/发布/订阅模式。

抱歉!评论已关闭.