消息队列MQ
消息队列中间件作为分布式系统中重要的组件,主要解决应用解耦,异步消息,流量削锋等问题,实现高性能,高可用,可伸缩和最终一致性架构。目前使用较多的消息队列有ActiveMQ,RabbitMQ,RocketMQ,Kafka。接下来,为你浅析消息队列相关知识。
一.为何要用消息队列?消息队列为我们带来什么?
(1)首先,在一个项目系统的架构设计中首要便是技术选型的考虑,针对系统应用场景调研分析,从而选择适用且实用的技术中间件。消息队列的核心优势便是:解耦,异步,削峰。
解耦场景:如下,A系统调用BCD系统接口POST发送数据,如果新增E系统,那么A代码需要新增调用E接口;如果D不需要了,A代码需要delete掉对D接口的调用。显而易见,A系统需要时时刻刻关注其它系统的稳定和可用,如接口调用是否成功,是否延时等。
解决方法:
在架构设计中加入MQ,A 系统产生一条数据,发送到 MQ 里面去,哪个系统需要数据自己去 MQ 里面消费。如果新系统需要数据,直接从 MQ 里消费即可;如果某个系统不需要这条数据了,就取消对 MQ 消息的消费即可。这样,A 系统就跟其它系统彻底解耦了(用 MQ 作解耦)。
异步场景:
比如,现在A系统接受一个请求request,本地处理后(设耗时100ms),还需要在BCD三个系统进行数据库DB操作(分别耗时300ms),这样总耗时需要100+300*3=1000ms=1s,影响用户体验。
解决方法:
如果使用 MQ,那么 A 系统连续发送 3 条消息到 MQ 队列中,假如耗时 5ms,A 系统从接受一个请求到返回响应给用户,总时长是 100 + 5 = 105ms,响应时间缩短了10倍,好处显而易见。
削峰场景:
顾名思义,就是平缓请求高峰期的请求量,在防止高峰期的请求丢失的情况下,又能很好地对高峰期的请求进行响应。
使用 MQ,每秒 5k 个请求写入 MQ,A 系统每秒钟最多处理 2k 个请求,因为 MySQL 每秒钟最多处理 2k 个。A 系统从 MQ 中慢慢拉取请求,每秒钟就拉取 2k 个请求,不要超过自己每秒能处理的最大请求数量就 ok,这样下来,哪怕是高峰期的时候,A 系统也绝对不会挂掉。而 MQ 每秒钟 5k 个请求进来,就 2k 个请求出去,结果就导致在中午高峰期(1 个小时),可能有几十万甚至几百万的请求积压在 MQ 中。这个短暂的高峰期积压是 ok 的,因为高峰期过了之后,每秒钟就 50 个请求进 MQ,但是 A 系统依然会按照每秒 2k 个请求的速度在处理。所以说,只要高峰期一过,A 系统就会快速将积压的消息给解决掉。
二.消息队列的缺点?
(1)系统可用性降低:
系统引入的外部依赖越多,越容易挂掉。如何保证消息队列的高可用,是需要考虑的地方。
(2)系统复杂度提高:
原有架构多了MQ,系统复杂性增大,如何保证消息没有重复消费?如何处理消息丢失的情况?怎么保证消息传递的顺序性?
(3)一致性问题:
A 系统处理完了直接返回成功了,人都以为你这个请求就成功了;但是问题是,要是 BCD 三个系统那里,BD 两个系统写库成功了,结果 C 系统写库失败了,咋整?你这数据就不一致了。
三.常见消息队列中间件的比较——Kafka、ActiveMQ、RabbitMQ、RocketMQ 各自优缺点