消息队列基础
- 什么是队列?
- 队列只允许在一端插入,另一端删除;可以理解为先进先出的线性表
- 什么是消息队列?
- 消息队列(MQ)是一种系统间相互协作的通信机制
消息队列的优势
异步
- 首先需要明白,异步与同步的区别只是在于是否需要等待结果的返回;同步需要等待结果的返回,而异步则不需要。
- 拿用户注册的业务来说,通常需要保存用户信息,而后会通过邮箱来激活账户;
- 同步的情况如下:
- 异步处理的情况如下:
解耦
- 想一下如下场景:
- 理论上来说,这里确实可以解决问题。但是如果发生如下情况,阁下又该如何处理?
- CV大法确实好,但是感觉怪怪的。因为同一份代码在不同的地方出现多次。
- 思考一下,是否可以进行抽象?比如这样:
又或者是这样 - 对于第一种方式,最终会导致系统任务难以分割,紧耦合的方式调用,各个模块难以独立的演化。
- 而第二种基于队列的方式,只需要通过队列来通知模块,只需要通知,具体的执行结果,无需关心。换句话来说,* 基于消息队列的模型,关心的是通知,而不是处理*
削峰
- 思考一下场景:双11流量激增的情况怎么处理?
- 当系统的请求超过系统的最大负载时,很容易导致系统延迟加剧;甚至有可能会导致基础服务不可用,进而引发服务雪崩。
- 流量激增,系统难以负载,解决方式最直接的就是加钱买机器,一台不行买两台。
- 但是如果只存在某个时间点激增,而其余的时间都可以负载,是不是存在资源的大量浪费。
- 思考一下:如果短时间的大量请求,短时间无法处理;是不是可以将大量的请求持久化,然后慢慢的处理呢?
当然消息队列除了以上的场景,还能够用于日志收集,事务的最终一致性......等场景;
- 任何事务都具有两面性,需要具有批判的目光去看待事务,消息队列亦是如此;引入消息队列,使得系统更加复杂了,同时,也会使得系统在网络调度时资源消耗更多......
- 引入消息队列的缺点如下:
- 增加了系统的复杂性:引入消息队列后,需要考虑很多与消息队列相关的问题,如:消息是否会丢失?如何保证消息的顺序性?如何处理消息的重复消费?如何监控和管理消息队列?如何保证消息队列的高可用性等。
- 降低了系统的可用性:系统之间依赖于消息队列进行通信,如果消息队列出现故障或不可用,可能会导致整个系统不可用或部分功能失效。因此,需要对消息队列进行高可用部署和容灾备份。
- 一致性问题:由于消息队列是异步处理的,可能会导致数据在不同系统之间不一致。例如,在电商平台中,用户下单后发送了支付成功的消息到队列中,但是订单系统在消费该消息时出现了异常,导致订单状态没有更新为已支付。这时候用户可能会看到订单还是未支付状态,而实际上已经扣款了。