文章目录
  1. 1. 一、为什么要使用消息队列?
  2. 2. 二、消息队列有什么优点与缺点?
  3. 3. 三、ActiveMQ、RabbitMQ、RocketMQ、Kafka都有什么优点和缺点?该如何选型呢?

相信各位或多或少都用过消息队列(MQ),这个系列是总结整理自己对石杉老师视频教程学习成果(石杉老师讲的很棒,就是边讲边打字画图很耗时),总不能每次想复习都去看视频吧,二来是试试看自己能否有能力把学到的内容再讲出去,通过写博文的形式进行复习与提高。

注:本系列所有文字、图片等其他信息均来自石杉老师视频教程,本人仅做整理工作。

下面言归正传,开始问与答。


一、为什么要使用消息队列?

MQ的使用场景有很多,使用理由也是五花八门,但核心的不外乎:解耦、异步与削峰。

1、先说解耦:

假如系统A为核心交易系统,B、C、D三个系统需要A的数据,如果不使用MQ那只能通过接口调用的形式进行发送。如果新增E系统也需要A的数据,A需要改动程序调用E的接口进行发送。如果B变的不需要A的数据了,也需要改A的程序去掉接口调用。如果A需要发送另外一种数据,那么又得七七八八改一轮。除了这些麻烦事外,系统A的处理逻辑还需要考虑其他几个系统会不会挂了,如果挂了我需不需要重新调用接口发数据,需不需要把待发送数据存起来备后用,这样系统A的复杂度会大大增加,整个系统的耦合度也很高。

如果采用MQ进行消息传递,那么A只需要把消息发送到MQ,后续的事情完全不需要考虑,其他业务系统如果对该消息感兴趣,订阅吧,哪天不需要这些消息了,取消订阅即可。消息的本地存储、重发全部由MQ进行控制。通过Pub/Sub模型,系统A和其他系统彻底解耦了。

2、接着是异步:

假如A系统接收一个请求,需要在自己本地写库,还需要在BCD三个系统写库,假设自己本地写库要100ms,BCD三个系统分别写库要200ms、300ms、400ms,如果不使用MQ,采用同步调用模式,则总耗时为100+200+300+400=1000ms,1s,这样很慢。

如果采用MQ,整个请求只需要考虑A的本地写库与发送MQ消息时间(假设为30ms),则请求的响应时间为130ms左右,其他BCD系统的写库让他们采用异步方式慢慢写,不用管。响应时间比原来有了大幅提升。

3、最后是削峰:

假设大量的用户在高峰期访问系统,如果没有采用MQ,请求直接通过A系统打到Mysql,很可能直接把数据库压垮,数据库一旦死掉,意味着整个系统挂掉。但如果盲目的采用扩充机器、提高配置的方法,在平时请求不多时又会造成资源浪费。

如果采用MQ,让请求先写入MQ,由A系统拉取,每秒拉取固定的数目(不超过处理极限),慢慢的处理,这样便能保证数据库不会被打死。因为高峰期MQ写入大于拉取,势必会造成消息的积压,但短暂的高峰期积压是没有问题的,高峰期一过,业务系统A会快速的把堆积的消息给处理掉。


二、消息队列有什么优点与缺点?

优点:特殊场景下有其对应的好处,解耦、异步、削峰

缺点

1、系统可用性降低:系统引入的外部依赖越多,越容易挂掉,引入MQ后,会在整个系统内增加一关键节点,如果MQ挂掉,即使ABCD等业务系统都正常,整个系统也处于不可用状态;

2、系统复杂性提高:加入MQ后会使得整个系统的复杂度大幅上升,如何保证消息没有重复消费、如何处理消息丢失的情况、如何保证消息传递的顺序性都需要进行考虑;

3、一致性问题:如上述第一个问题中的异步,A系统处理完了直接返回成功了,别人都以为你这个请求就成功了。但是问题是,要是BCD三个系统那里,BD两个系统写库成功了,结果C系统写库失败了,你这数据就不一致了。


三、ActiveMQ、RabbitMQ、RocketMQ、Kafka都有什么优点和缺点?该如何选型呢?

常见MQ对比

特性 ActiveMQ RabbitMQ RocketMQ Kafka
单机吞吐量 万级,吞吐量比RocketMQ和Kafka要低了一个数量级 万级,吞吐量比RocketMQ和Kafka要低了一个数量级 10万级,RocketMQ也是可以支撑高吞吐的一种MQ 10万级别,这是kafka最大的优点,就是吞吐量高。
一般配合大数据类的系统来进行实时数据计算、日志采集等场景
topic数量对吞吐量的影响 topic可以达到几百,几千个的级别,吞吐量会有较小幅度的下降
这是RocketMQ的一大优势,在同等机器下,可以支撑大量的topic
topic从几十个到几百个的时候,吞吐量会大幅度下降
所以在同等机器下,kafka尽量保证topic数量不要过多。如果要支撑大规模topic,需要增加更多的机器资源
时效性 ms级 微秒级,这是rabbitmq的一大特点,延迟是最低的 ms级 延迟在ms级以内
可用性 高,基于主从架构实现高可用性 高,基于主从架构实现高可用性 非常高,分布式架构 非常高,kafka是分布式的,一个数据多个副本,少数机器宕机,不会丢失数据,不会导致不可用
消息可靠性 有较低的概率丢失数据 经过参数优化配置,可以做到0丢失 经过参数优化配置,消息可以做到0丢失
功能支持 MQ领域的功能极其完备 基于erlang开发,所以并发能力很强,性能极其好,延时很低 MQ功能较为完善,还是分布式的,扩展性好 功能较为简单,主要支持简单的MQ功能,在大数据领域的实时计算以及日志采集被大规模使用,是事实上的标准

优劣势总结

1、ActiveMQ:

非常成熟,功能强大,在业内大量的公司以及项目中都有应用

偶尔会有较低概率丢失消息

而且现在社区以及国内应用都越来越少,官方社区现在对ActiveMQ维护越来越少,几个月才发布一个版本

而且确实主要是基于解耦和异步来用的,较少在大规模吞吐的场景中使用

2、RabbitMQ:

erlang语言开发,性能极其好,延时很低;

吞吐量到万级,MQ功能比较完备,而且开源提供的管理界面非常棒,用起来很好用

社区相对比较活跃,几乎每个月都发布几个版本,在国内一些互联网公司近几年用rabbitmq也比较多一些

但是问题也是显而易见的,RabbitMQ确实吞吐量会低一些,这是因为他做的实现机制比较重。

而且erlang开发,国内有几个公司有实力做erlang源码级别的研究和定制?如果说没这个实力的话,确实偶尔会有一些问题,很难去看懂源码,公司对这个东西的掌控很弱,基本职能依赖于开源社区的快速维护和修复bug。

3、RocketMQ:

接口简单易用,而且毕竟在阿里大规模应用过,有阿里品牌保障,而且一个很大的优势在于,阿里出品都是java系的,我们可以自己阅读源码,定制自己公司的MQ,可以掌控

日处理消息上百亿之多,可以做到大规模吞吐,性能也非常好,分布式扩展也很方便,社区维护还可以,可靠性和可用性都是ok的,还可以支撑大规模的topic数量,支持复杂MQ业务场景

4、Kafka:

kafka的特点其实很明显,就是仅仅提供较少的核心功能,但是提供超高的吞吐量,ms级的延迟,极高的可用性以及可靠性,而且分布式可以任意扩展

同时kafka最好是支撑较少的topic数量即可,保证其超高吞吐量

而且kafka唯一的一点劣势是有可能消息重复消费,那么对数据准确性会造成极其轻微的影响,在大数据领域中以及日志采集中,这点轻微影响可以忽略

这个特性天然适合大数据实时计算以及日志收集

选型建议

一般的业务系统要引入MQ,最早大家都用ActiveMQ,但是现在确实大家用的不多了,没经过大规模吞吐量场景的验证,社区也不是很活跃,所以不推荐用这个;

后来大家开始用RabbitMQ,但是确实erlang语言阻止了大量的java工程师去深入研究和掌控他,对公司而言,几乎处于不可控的状态,但是确实人是开源的,比较稳定的支持,活跃度也高;

不过现在越来越多的公司,会去用RocketMQ,确实很不错,但是提醒一下想好社区万一突然黄掉的风险,对自己公司技术实力有绝对自信的,推荐用RocketMQ,否则回去老老实实用RabbitMQ吧,活跃的开源社区,绝对不会黄

所以中小型公司,技术实力较为一般,技术挑战不是特别高,用RabbitMQ是不错的选择;大型公司,基础架构研发实力较强,用RocketMQ是很好的选择

如果是大数据领域的实时计算、日志采集等场景,用Kafka是业内标准的,绝对没问题,社区活跃度很高,绝对不会黄,何况几乎是全世界这个领域的事实性规范

文章目录
  1. 1. 一、为什么要使用消息队列?
  2. 2. 二、消息队列有什么优点与缺点?
  3. 3. 三、ActiveMQ、RabbitMQ、RocketMQ、Kafka都有什么优点和缺点?该如何选型呢?