消息模型

概述

消息中间件主要包括发送、存储、消费三个模块,那么消息是如何在这三个模块之间传递的呢?

接下来,本文将会介绍两种常用的消息传递模型,以及这两种传递模型在主流消息中间件中的使用。

消息传递模型

消息的传递模型一般有两种:点对点(P2P,Point-to-Point)模型和发布/订阅(Pub/Sub)模型。

点对点模型

1.点对点模型由生产者(producer)、队列(queue)、消费者(consumer)组成。

2.点对点模型的示意图:

image

  • producer生产消息并且发送到queue中,consumer从queue中拉取消息并且处理、处理成功以后发送Ack确认。
  • 由于queue不存储已经消费的消息。所以消息消费者不可能消费到已经被消费的消息,即对于一条消息而言只有一个producer和一个consumer。
  • 但是在点对点模型的实现中,对于一个queue而言,可以有多个producer和多个consumer,如下图所示:

image

  • 在多producer和多consumer的点对点模型中,producerA发送一条消息(Message1)到queue中,由于Message1只有一份,此时只能有一个consumer可以从queue中取到Message1进行消费。
  • 例如图中consumerA从queue中取出Message1进行消费以后,queue中不再存储Message1。所以其他consumer不能对Message1进行消费,并且consumerA也不能对Message1进行重复消费。
  • 所以queue不存储已经消费的消息,保证了消息的点对点传输,即一条消息只有一个producer和一个consumer(无论queue有多少个producer和consumer)。

3.点对点模型的特点:

  • queue不存储已经消费的消息。
  • 每个消息只有一个消费者和一个生产者。
  • 生产者发消息和消费者消费消息是异步解耦的。
  • 消费者接收到消息后,需要发送ACK确定。

发布/订阅模型

1.发布/订阅模型由生产者(producer)、主题(topic)、消费者(consumer)组成。

2.发布/订阅模型的示意图:

image

  • 生产者将消息发送到topic中,所有订阅该topic的消费者,都可以消费该topic下的全部消息。该模型是一种观察者模型,生产者和消费者之间相互透明,并且可以动态的发布和订阅。
  • 消息只会存储一份,所以订阅同一个topic的消费者拉取的是同一份消息。消息被消费以后,不会立即删除,所以支持重复消费。

3.发布/订阅模型的特点:

  • 每条消息都可以有多个消费者。
  • 针对某个topic,消费者必须订阅以后才可以消费它的消息。
  • 可重复消费

消息模型的应用

本章节主要讲述:上文两种传递模型在主流消息中间件kafaka、RabbitMQ中的应用。

kafka的消息传递模型

Kafka是一种发布订阅模型,但是它与传统的发布订阅模型有所不同。

kafka提供了一个消费者组(consumerGroup)的概念,一个消息可以被多个消费者组消费,但是只能被一个消费者组里的一个消费者消费。当只有一个消费者组时,每个消息都只有一个消费者,就是点对点模型。当存在多个消费者组时,同一条消息可以被多个消费者组消费,就是发布订阅模型。

1.kafka的模型由生产者(producer)、主题(topic)、分区(partition)、消费者(consumer)组成,一个topic包含多个partition。

2.kafka消息模型的示意图:

image

  • 在普通发布/订阅模型下,当生产者发送的消息量比较大时,单个消费者处理能力不足,就造成大量的消息堆积。
  • kafka使用一种基于消费者组的发布/订阅模型,来解决堆积问题。在该模型中,订阅相同topic的多个消费者组成一个消费者组,分组订阅topic,实现消费端的负载均衡。消费端负载示意图如下:

image

  • 同一个消费者组中的消费者,分工消费topic下各个partition的消息,实现了消费能力的线性扩展。此模型中,topic下的某一partition,只能被消费者组中的一个消费者消费。即消费者组下的消费者,不能同时消费topic下的同一个partition,因为这样会造成重复消费。

3.kafka消息模型的特点:

  • 消息持久化,客户端为拉模型。
  • 消费状态和订阅关系由客户端维护。
  • 生产者断和消费者端都实现了负载均衡。
  • 在一个消费者组内部是点对点模型。
  • 多个消费者组之间是发布/订阅模型。

RabbitMQ消息传递模型

RabbitMQ是一种典型的点对点模型,但是RabbitMQ中可以通过设置交换器类型来实现发布订阅模型而达到广播消费的效果。

RabbitMQ的点对点模型

RabbitMQ中一个核心的原则是,消息不能直接投递到Queue中。Producer只能将自己的消息投递到Exchange中,由Exchange按照路由规则将消息投递到对应的Queue中。

在Consumer中,声明自己对哪个Exchange感兴趣,并将自己的Queue绑定到自己感兴趣的路由关键字上,建立相应的映射关系;第二,在Producer中,将消息投递一个Exchange中,并指明它的路由关键字。

RabbitMQ的点对点模型如下图所示:

image

图中两个生产者将消息发送到exchange交换器,exchange交换器根据消息的路由关键字,将消息发送到不同的队列里面。消费者从自己的队列中拉取消息,由于队列不存储已经被消费的消息,此模型中每一条消息只有一个唯一的消费者

RabbitMQ的发布订阅模型

1.RabbitMQ通过exchange可以支持多订阅,当RabbitMQ需要支持多订阅时,生产者发送的消息通过路由同时写到多个Queue,不同消费者都可以消费此消息。

2.RabbitMQ的发布订阅式如下图所示:

image

  • Consumer声明自己对多个Exchange感兴趣,并将自己的Queue绑定到自己感兴趣的Exchange上,建立相应的映射关系。
  • 图中queue1和queue2同时都与exchange1、exchange2建立映射关系。当生产者将消息发送到exchange1,exchange1会把同一份消息分别发送到queue1和queue2。同理exchange2也会把同一份消息分别发送给queue1和queue2。从而实现了同一份消息可以被多个消费者消费,消费者分别从自己的队列中拉取消息进行消费。
  • 由于queue中的消息消费完后立即删除,不保留历史消息。所以在多订阅时,消息会以拷贝的形式存在不同的队列中。

3.RabbitMQ消息模型的特点:

  • 通exchange交换器和消息拷贝实现多订阅。
  • RabbitMQ既支持内存队列也支持持久化队列。
  • 消费端为推模型,消费状态和订阅关系由服务端负责维护。
0%