MQ消息队列学习系列之什么是消息队列?为什么使用消息队列?Kafka、ActiveMQ、RabbitMQ、RocketMQ 的优缺点?

1,381 阅读7分钟

什么是消息队列

  • 消息队列,一般我们会简称它为MQ(Message Queue)。就是将消息放到队列中。 队列是一种先进先出的接口。
    将消息放到队列中叫生产者。
    将消息从队列中取出来叫消费者。 总结:消息队列就是由生产者将消息放到队列中,由于它先进先出的结构特性,消费者会拿最早进去的消息回来进行消费。

为什么使用消息队列:

消息队列的优点:

- 三个核心:解耦异步削峰

解耦
    传统情况下,A系统跟B,C,D系统对接数据都是http的方式,分别写三个接口进行对接。这种情况下,

  1. 一旦业务有变动就要三个接口都改一遍,如果是重要的数据,A系统还要时刻关注B,C,D三个系统的状态,如果宕机,没接收成功,是不是要存储数据重新发送等等问题。
  2. 而且如果是一个中台系统,不断有新的系统接进入来,开发就要不断地对接新系统,开发新接口,这是非常耗时耗力的事情**。**

如果接入MQ:     A系统产生一条数据,直接发送到MQ中,让B,C,D系统自己从MQ中获取数据,如果有新的系统需要数据,让它直接去消费MQ即可。A系统也不需要关注B,C,D系统的状态,它们是否宕机,有没有成功接收数据等问题。

在这里插入图片描述

异步:
    A 系统接收一个请求,需要在自己本地写库,还需要在 BCD 三个系统写库,自己本地写库要 3ms,BCD 三个系统分别写库要 300ms、450ms、200ms。最终请求总延时是 3 + 300 + 450 + 200 = 953ms。虽然可以通过创建新线程来对不同系统进发送消息,但是线程是有限的,对接的系统是无限的,高并发的情景下,对性能消耗很大的。
如果接入MQ:
A 系统连续发送 3 条消息到 MQ 队列中,不需要花费时间在分别与B,C,D系统的连接和消息传输中, 耗时5ms就能直接返回结果给前端。
在这里插入图片描述

削峰:
    对于一些系统某些特殊的时刻会有请求高峰期,其它时间又都是请求低谷期。如吃饭时间大家都在点餐,点餐系统在短时间内并发到达成千上万的请求,导致数据库或者其它系统一下子处理不来那么多的sql,负载过高(或者说是定时任务啥的)。一天中就几分钟并发很高,其它时间都是只有几十个请求的。对于这种情况,如果直接加服务器资源那实在太浪费了,性价比过低,不加的话,高峰期又有可能会导致系统或服务器宕机。
如果接入MQ:
    系统可以从 MQ 中慢慢拉取请求,每秒钟只拉取能同时处理的请求个数,只要不要超过自己每秒能处理的最大请求数量就 ok,等高峰期一过,系统也能很快的处理堆积的请求,并不会造成系统宕机和请求丢失的情况。

消息队列的缺点:

系统可用性降低:
    系统引入的外部依赖越多,越容易挂掉。原本A直接调用B,C,D系统,只要A,B,C,D系统正常就行。引入MQ后,A,B,C,D系统正常,但是MQ挂掉,就会导致系统出错。系统的风险点多增加了一个。
系统复杂度提高:
    多增加了个MQ进来,就好考虑消息重发,丢失,顺序等问题。
一致性问题:
    A系统发送消息给MQ后就直接返回,万一BC两系统消费成功,D系统消费失败了,导致三个系统数据不一致,这种情况要怎么办,怎么保证消息一致?
消息队列有优点也有缺点,但是相比优点来说,缺点还是可以接受的。虽然接入MQ会提供系统复杂度,得想各种技术手段来规避他可能出现的问题,但是针对不同情况,该用还是得用。

常见的MQ消息队列有哪些?各自有什么不同呢?

Kafka、ActiveMQ、RabbitMQ、RocketMQ 优缺点对比:

特性ActiveMQRabbitMQRocketMQKafka
开发语言javaerlangjavascala
单机吞吐量万级,比 RocketMQ、Kafka 低一个数量级同 ActiveMQ,万级10 万级,支撑高吞吐10 万级,高吞吐,一般配合大数据类的系统来进行实时数据计算、日志采集等场景
topic 数量对吞吐量的影响topic 可以达到几百/几千的级别,吞吐量会有较小幅度的下降,这是 RocketMQ 的一大优势,在同等机器下,可以支撑大量的 topictopic 从几十到几百个时候,吞吐量会大幅度下降,在同等机器下,Kafka 尽量保证 topic 数量不要过多,如果要支撑大规模的 topic,需要增加更多的机器资源
时效性ms 级微秒级,这是 RabbitMQ 的一大特点,延迟最低ms 级延迟在 ms 级以内
可用性高,基于主从架构实现高可用(master,slave)同 ActiveMQ,高,基于主从架构实现高可用(master,slave)非常高,分布式架构非常高,分布式,一个数据多个副本,少数机器宕机,不会丢失数据,不会导致不可用
消息可靠性有较低的概率丢失数据基本不丢经过参数优化配置,可以做到 0 丢失同 RocketMQ
功能支持成熟的产品,MQ 领域的功能极其完备,在很多公司得到应用;有较多的文档;各种协议支持较好基于 erlang 开发,并发能力很强,性能极好,延时很低;管理界面较丰富MQ 功能较为完善,还是分布式的,扩展性好功能较为简单,主要支持简单的 MQ 功能,像一些消息查询,消息回溯等功能没有提供,毕竟是为大数据准备的,在大数据领域的实时计算以及日志采集被大规模使用
社区活跃度活跃度不高活跃阿里出品,目前捐给Apache,活跃度不高活跃


技术选型时建议

  1. 中小型公司选RabbitMQ。 公司数据量不多,且不需要搭建分布式 ,erlang语言支持的并发能力很高足够支撑公司的数据量,并且有丰富的管理界面,使用起来很方便,快捷。 缺点是能定制化开发erlang的程序员不多,遇到bug只能去社区寻求帮助,幸好社区活跃,开发过程中遇到的bug基本都能解决。当然公司如果有资源和对应的场景也是可以选择rocketMq和kafka的。
  2. 大型公司可根据业务在RocketMq和Kafka之间选择。大公司的数据量较多,并且有能力搭建分布式环境。一般业务场景可以使用RocketMq,毕竟功能较为完善,扩展性好,公司也可以通过调用资源对Rocket进行定制化开发。 如果是大数据领域的实时计算、日志采集等场景推荐使用kafka,这是业内标准。