提到消息队列,大家一定不陌生,无论是在校、面试还是工作,我们涉及得都很多。

有需求就有供应,市面上消息队列当然非常多,算得上主流的也有5、6个,而大家可能由于对某一种队列比较熟悉,就一直用它,大概就是亚瑟打野、亚瑟上路、亚瑟中路、亚瑟辅助。

消息队列简介(消息队列这么多)(1)

但你有思考过吗引入的队列是否是最合适的吗?

它与其它队列相比有什么优势吗?

可以说,选型是开发工作中最重要,也是最体现能力的一环。今天牛牛就来给大家介绍下消息队列如何抉择。

消息队列是什么?

消息队列,顾名思义就是传递消息的队列,有着先入先出的特性,既然是队列,自然遵循先入先出的原则,同时,消息队列具备可靠性、高性能等特点。

消息队列是大型分布式系统不可缺少的中间件,一般用于异步流程、消息分发、流量削锋等问题,可以通过消息队列实现高性能、高可用、高扩展的架构。

业界比较出名的消息队列有ActiveMQ、RabbitMQ、ZeroMQ、Kafka、MetaMQ、RocketMQ。

那大家就会问了,这么多消息队列,我选谁好呢?

别急,我们先来深入理一理消息队列的应用场景,以及每个队列的特色,知道这些信息,才好做出决策。

消息队列的应用场景

  1. 异步

如果一个接口,处理时间很长,而且不能通过水平扩容来解决,就需要异步,那么,什么情况下不能通过水平扩容解决呢?

有很多,比如视频处理,涉及到视频下载,那受限于网络带宽等因素,扩容无用;比如区块链这种共识场景,只有单机才能出块,扩容也没有用;还有更常见的,比如一个业务流程,过了10多个微服务,单个也许不长,加起来就很难接受。

以上的情况下,用户很难通过同步接口长时间等待结果,那就应该做成异步,先扔进消息队列,后续再进行消费,响应时间可以从10s,降低到10ms。

消息队列简介(消息队列这么多)(2)

2.消息分发

假设一个核心服务A,是用来发布某种信号的,发布之后,需要通知到下游服务B、C,这种模式在只有B、C两兄弟的时候,没啥问题。

但随着业务需要,可能会有D、E、F等更多的打工人出现,这时候A服务就需要更改代码,将消息也传递给这些新加入的兄弟,每次增加打工人,就需要更改一次代码。

消息队列简介(消息队列这么多)(3)

而引入消息队列,则可以解决这个问题,实现能力复用,业务解耦。

消息队列简介(消息队列这么多)(4)

3.削峰

业务有个概念叫峰值流量,也就说流量在一段时间远大于平时,从视图上看就像一个山峰。比如天猫双十一秒杀日,特别是0点的时候,流量起码是平常的千倍以上,如果不做好处理,一波就能彻底将服务打死。

消息队列简介(消息队列这么多)(5)

如果常备1000倍流量的设备,那是极大的成本浪费,如果临时调配,进行服务扩容,很多时候又不如想象得简单。

之前有和Shopee的同学聊过,一到活动日他们就得紧锣密鼓去做扩容,扩容之后还得熬更守夜地做压测,不光劳命伤财、还容易出事故。

消息队列可以优雅地解决这个问题,将双十一的请求扔入消息队列,等待后续服务慢慢处理,如下图所示。

消息队列简介(消息队列这么多)(6)

其实在架构上,削峰和上面的异步场景是相同的架构,都是将请求扔入队列中,再慢慢消费。

但要注意异步场景是单个请求,本身处理时间很长。削峰针对是单个请求ok,但是流量突发的场景。

消息队列能力对比

上面有提到几个知名的消息队列,其中ZeroMQ太过轻量,主要用于学习,实际是不会应用到生产,我们就Kafka、ActiveMQ、RabbitMQ、RocketMQ来进行不同维度对比。

特性

ActiveMQ

RabbitMQ

RocketMQ

Kafka

单机吞吐量

万级

万级

10 万级

10 万级

时效性

毫秒级

微秒级

毫秒级

毫秒级

可用性

高(主从)

高(主从)

非常高(分布式)

非常高(分布式)

消息重复

至少一次

至少一次

至少一次

最多一次

至少一次

最多一次

消息顺序性

有序

有序

有序

分区有序

支持主题数

千级

百万级

千级

百级,多了性能严重下滑

消息回溯

不支持

不支持

支持(按时间回溯)

支持(按offset回溯)

管理界面

普通

普通

完善

普通

消息队列选型

选型的时候,我们需要根据业务场景,结合上述特性来进行选型。

比如你要支持天猫双十一类超大型的秒杀活动,这种一锤子买卖,那管理界面、消息回溯啥的不重要。

我们需要看什么?看吞吐量!

所以优先选Kafka和RocketMQ这种更高吞吐的。

比如做一个公司的中台,对外提供能力,那可能会有很多主题接入,这时候主题个数又是很重要的考量,像Kafka这样百级的,就不太符合要求,可以根据情况考虑千级的RocketMQ,甚至百万级的RabbitMQ。

又比如是一个金融类业务,那么重点考虑的就是稳定性、安全性,分布式部署的Kafka和Rocket就更有优势。

特别说一下时效性,RabbitMQ以微秒的时效作为招牌,但实际上毫秒和微秒,在绝大多数情况下,都没有感知的区别,加上网络带来的波动,这一点在生产过程中,反而不会作为重要的考量。

其它的特性,如消息确认、消息回溯,也经常作为考量的场景,管理界面的话试公司而定了,反正牛牛呆过的地方,都不看重这个,毕竟都有自己的运维体系。

最后

本次,牛牛给大家分享了消息队列是什么、解决什么问题、每种队列的特性,以及怎么结合场景和特性做分析。

面试时可以针对每个场景的不同因地制宜选取队列,这样不仅可以展现知识的全面性还可以体现出自己分析问题的能力。

而在实际的工作中,我们需要考虑的则更多,比如团队的技术栈、经济成本等情况进行综合分析。只有熟悉每个消息队列的优劣,才能好中取优,选出适合的方案。

,