持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第20天,点击查看活动详情
1. 消息队列的作用
消息队列是我们最常用的中间件之一,本文不具体针对某一个具体的消息队列,而是从整体概念上建立起我们对于消息队列的基本认识,方便我们后续对RabbitMQ,RocketMQ以及Kafka的针对性学习。
说到消息队列,首先要提的就是其三大基础功能:
- 解耦:解除生产者与消费者的直接依赖
- 削峰:将生产者瞬时产生的流量缓缓的释放给消费者
- 异步:生产者讲消息发送给消息队列之后,可以先异步处理其他的业务,等待返回的信号
例如在秒杀或者是一些其他的业务场景,消息队列对于系统稳定性的提高有很好的作用。
2. 消息队列的模型
消息队列本质上还是一个生产者-消费者模型或者说发布订阅模型,生产者生产消息放入队列,消费者从队列中消费消息。
在消息队列中,我们通常讲上述的过程抽象为以下的组成部分:
- producer 是任务的生产方
- topic 在逻辑上可以被认为是一个queue,但是物理上可以由多个queue组成,每条消息都要有其对应的topic
- queue 物理意义上的队列数据结构
- product 消息的生产者
- consumer 消息的消费者
- consumer group 消费统一topic的消费者可以组成消费群
3. 消息队列可靠性
前面我们提到了,消息队列能起到解耦、异步等作用,但是,中间件的引入,一定会使系统的复杂度增减,那么,如何保障系统的可靠性就是一个非常重要的命题。
我们可以分为两个部分来思考这个问题:
- 保证消息的幂等性,即不被重复消费
- 为了做到这一点,最保险的方法是在消费端进行消息全局唯一ID的校验,因为很多时候,生产者消息的重复发送是不可避免的。
- 保证消息不丢失
- 生产者发送消息之后,要确保消息队列收到了消息,例如RabbitMQ的confirm机制;
- 消息队列在确保消费者在成功消费掉消息以后,再删除消息,例如RabbitMQ的ack机制;
4. 死信队列与延时队列
- 死信队列用来处理没有被成功消费的消息
- 延时队列用来处理定时一段时间后需要处理的消息