持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第28天,点击查看活动详情
1. 消息队列基本概念
消息队列就是一个使用队列来通信的组件。
一般我们称发送消息方为生产者Producer
,接受消费消息方为消费者Consumer
,消息队列服务端为Broker
。
消息从Producer
发往Broker
,Broker
将消息存储至本地,然后Consumer
从Broker
拉取消息,或者Broker
推送消息至Consumer
,最后消费。
2. 消息队列模式
消息队列有两种模式:点对点模式和发布/订阅模式。
点对点模式: 生产者往某个队列里面发送消息,一个队列可以存储多个生产者的消息,一个队列也可以有多个消费者, 但是消费者之间是竞争关系,即每条消息只能被一个消费者消费。
发布/订阅模式: 为了解决一条消息能被多个消费者消费的问题,出现了发布/订阅模式。该模型是将消息发往一个Topic
即主题中,所有订阅了这个Topic
的订阅者都能消费这条消息。
RabbitMQ
采用点对点模式,RocketMQ
和Kafka
采用发布/订阅模式。
为了提高并发度,往往发布/订阅模式还会引入队列或者分区的概念。即消息是发往一个主题下的某个队列或者某个分区中。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 住,避免了多次频繁的拉取动作,当消息一到就提醒返回。