MQ 队列模式以及推拉模型概念详解

1,309 阅读4分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第28天,点击查看活动详情

1. 消息队列基本概念

消息队列就是一个使用队列来通信的组件。

一般我们称发送消息方为生产者Producer,接受消费消息方为消费者Consumer,消息队列服务端为Broker

消息从Producer发往BrokerBroker将消息存储至本地,然后ConsumerBroker拉取消息,或者Broker推送消息至Consumer,最后消费。

2. 消息队列模式

消息队列有两种模式:点对点模式发布/订阅模式

点对点模式: 生产者往某个队列里面发送消息,一个队列可以存储多个生产者的消息,一个队列也可以有多个消费者, 但是消费者之间是竞争关系,即每条消息只能被一个消费者消费。

发布/订阅模式: 为了解决一条消息能被多个消费者消费的问题,出现了发布/订阅模式。该模型是将消息发往一个Topic即主题中,所有订阅了这个Topic的订阅者都能消费这条消息。

RabbitMQ采用点对点模式,RocketMQKafka采用发布/订阅模式。

为了提高并发度,往往发布/订阅模式还会引入队列或者分区的概念。即消息是发往一个主题下的某个队列或者某个分区中。RocketMQ中叫队列,Kafka叫分区,本质一样。例如某个主题下有 5 个队列,那么这个主题的并发度就提高为 5 ,同时可以有 5 个消费者并行消费该主题的消息。

3. 推拉模式

一般而言我们在谈论推拉模式的时候指的是 Comsumer 和 Broker 之间的交互。

默认的认为 Producer 与 Broker 之间就是推的方式,即 Producer 将消息推送给 Broker,反之是 Broker 主动去拉取消息。

推模式

推模式指的是消息从 Broker 推向 Consumer,即 Consumer 被动的接收消息,由 Broker 来主导消息的发送。

推模式的优点

  • 消息实时性高, Broker 接受完消息之后可以立马推送给 Consumer。

  • 对于消费者使用来说更简单,简单啊就等着,反正有消息来了就会推过来。

推模式的缺点

  • 推送速率难以适应消费速率,当生产者往 Broker 发送消息的速率大于消费者消费消息的速率时,随着时间的增长消费者那边可能就“爆仓”了。

  • 不同的消费者的消费速率还不一样,身为 Broker 很难平衡每个消费者的推送速率,增加了 Broker 自身的复杂度。

推模式难以根据消费者的状态控制推送速率,适用于消息量不大、消费能力强要求实时性高的情况下。

拉模式

拉模式指的是 Consumer 主动向 Broker 请求拉取消息,即 Broker 被动的发送消息给 Consumer。

拉模式的优点

  • 消费者可以根据自身的情况来发起拉取消息的请求。

  • Broker 就相对轻松了,它只管存生产者发来的消息。

  • 参考消费者请求的信息来决定缓存多少消息之后批量发送。

拉模式的缺点

  • 消息延迟,消费者定期拉取,有延迟。

  • 消息忙请求,忙请求就是比如消息隔了几个小时才有,那么在几个小时之内消费者的请求都是无效的,在做无用功。

长轮询

RocketMQ 和 Kafka 都是利用“长轮询”来实现拉模式,用以平衡 Pull/Push 模型各自的缺点。

具体的做法都是通过消费者等待消息,当有消息的时候 Broker 会直接返回消息,如果没有消息都会采取延迟处理的策略,并且为了保证消息的及时性,在对应队列或者分区有新消息到来的时候都会提醒消息来了,及时返回消息。

一句话说就是消费者和 Broker 相互配合,拉取消息请求不满足条件的时候 hold 住,避免了多次频繁的拉取动作,当消息一到就提醒返回。