本人目前项目中有用到rocketMQ作为数据传输过程中的中间件,今天整理了一下资料,记录一下自己对消息中间件的理解。
一.概念1.MQ
message queue消息队列,消息队列是就是队列,是一种先进先出的数据结构。把要传输的数据放在队列中,用队列机制来实现数据的传递,也就是生产者产生消息,将消息放入队列。消费者消费消息,将消息从队列中读出。
2.消息中间件
消息中间件是对消息队列的应用,消息队列(MQ)只是一种数据结构,而消息中间件是分布式系统中一个组件,或者说是一个系统。以上就是MQ和中间件的关系。
消息中间件是基于队列和消息传递技术的,在网络环境中为应用系统提供同步或异步、可靠的消息传输。
目前行业内主要的MQ产品有:RabbitMQ、ActiveMQ、RocketMQ、ZeroMQ、Kafka等等,我们项目用的是RocketMQ,项目是在我入职之前搭建的,有趣的是,当我问早起项目人员,为何我们选择rocketMQ时,他告诉我说因为集团云服务用的是阿里云,而阿里云用的是rocketMQ,我们肯定也就用rocketMQ。我一想,我擦,好有道理,我竟无法反驳。
二.面试问题点 1、你们项目为什么要用到rocketMQ?这个问题拆解以下,可以看作:什么是MQ?MQ由什么组成?又是怎么实现的?
什么是MQ前头讲过了,那么MQ的组成。
1.1 消息中间件的组成broker 消息服务器,作为server提供消息核心服务
producer 生产者,业务的发起点,负责生产消息,并传输给到核心服务,也就是broker
consumer 消费者,业务的处理点,负责从broker获取到消息,并且对消息进行业务逻辑处理
queue 队列,点对点模式下,特定生产者向特定的队列发送消息,消费者订阅特定的队列来完成特定消息的获取
topic 主题,发布订阅模式下,不同生产者向topic发送消息,由MQ服务器分发到不同的订阅者,实现消息的广播
message 消息体,根据不同的通信协议定义的固定格式进行编码的数据包,用来封装业务数据,实现消息的传输
从queue和topic我们可以看出来,MQ是有两种模式的,一种点对点,一种广播模式(发布模式)
1.2 消息中间件的两种模式点对点:queue
A-------------------------------queue---------------------------------B
江湖规矩,单挑!此种模式下,生产者A发送消息到queue队列中,然后消费者B从queue队列中取出消费。这个消息被B消费了之后,queue将不再进行存储,也就是说,该消息只能由一个消费者消费,其他消费者不可能再消费得到。若果没有消费者来消费,则该消息就被一直保存直到有消费者来消费。
广播:topic
跟1对1不同,这是一个N对N,生产者将消息发布到topic中,同时会有多个消费者(订阅者)来消费该消息,严格来说,是所有订阅者。
2、消息中间件给你们带来了什么?解决了什么问题?这个问题就是问作用、实际使用业务场景。
2.1 消息中间件的作用三大作用:异步、解耦、削峰
我们假设快递员现在在一个小区送快递,他有5个快递要送,客户门牌号分别如上图。这个时候,快递员要一个一个跑,这样是不是很浪费时间,我要先送完1栋,再送2栋,再送其他栋,如果我有100个200个件,我这一天非得累死个屁的了。快递一个一个送,同时,没送一个快递之前我还要联系户主,是否在家呀,是否现在方便收快递,然后还要确认签收等等。
现在,我们有了某鸟驿站:
对于快递员来说,世界一下子阳光起来了。这个某鸟驿站,我们可以思考一下,带来了什么好处。首先,从模式上,快递员将所有快递统一集中放到了驿站,不再需要逐个送货上门,其次每个用户不再提前约定好时间在家里等着快递上门,而是自己去驿站取,有空就现在去,没空就晚点再去,反正快递就在那儿放着,也丢不了。
异步假设按照没有驿站的模式,快递员给2栋304、5栋803、15栋301这三户人家送快递,分别需要2分钟,5分钟,15分钟,再加上快递员自己中间休息的时间1分钟,那么总共送完这三户,需要2+5+15+1=23分钟,这还不算经常出现的客户让你在门口等一下的情况,后面6栋904、1栋202其他用户在等着,肯定一直在骂慢死了,赶紧送过来签收完我还要下楼打球。
现在有了某鸟驿站,快递员将这三个快递登记入库,大概只需要3分钟,然后三户人家收到了通知,告诉他们,你的快递到驿站了,有时间来拿。至于你这三户人家分别来驿站拿快递的时间,关我快递员什么事(奸笑)。这个就是异步处理。
解耦假设没有驿站,对于快递员来说,我先来到了2栋304,送第一个快递,按门铃,没人开,再按,还是没人,等了半天没动静,然后打电话,原来用户不在家,重新约个时间送来吧。快递员记录下下次派送的时间,然后来到了第二家5栋803,又没人开门,打电话打了好几个才接,好家伙,在家里睡着了。来到了第三家,15栋301,住的是一个小姐姐,快递是已经分手的男朋友送的,小姐姐说我不要,你退回去,顺便告诉前男友让他死心,快递员打电话给发货的人,发货的说不行,不能退,你必须送到,要不然投诉你。
换我是快递我直接崩溃,面对着客户各种各样的奇葩事件、紧急情况,光这个业务处理就能把你烦死,时间都不说了,头都大了。这是因为系统之间耦合太高,如果我可以避免耦合,我压根就不跟你客户接触,我现在可以直接放驿站,你自己要不要你看着办,什么时候要你随便,这就是解耦,降低耦合度,降低系统之间互相影响的可能性。
削峰还是一样,先假设一下没有驿站。快递最崩溃的事情来了------双十一狂欢购物节。快递员送得崩溃,用户也等得崩溃。
11月10日,还跟往常一样风平浪静,大概一天50个快递,送完这家送那家,慢慢来。11月11日,快递量突然暴涨到2000件,快递员表示要离职,我说的,耶稣来了也拦不住。那么这种突然高并发的业务场景,就是峰值到来。例如我们使用mysql数据库,mysq一般来说每秒可以处理2000个sql请求,如果现在我每秒请求10000次,那么mysql没有办法承载,可能直接就导致系统崩溃,用户就没法使用了,会造成很大的损失。之所以叫峰值,就是说,肯定只是暂时的,不久之后就会回落,如果一直是峰值,那可能产品经理有问题,或者你选型有问题。
说回驿站,峰值到来的时候,快递员就可以以一定速率(不至于让自己累死)将快递都登记入库,这个速度肯定会比客户们来取得速度快,驿站是可以支持快递积压的,哪怕是屋里头放慢了,大不了搬到门前空地上放,反正能够积压。后续等着用户们慢慢来取就行了,这样在资源有限的情况下,不至于让整个快递系统崩溃。这就叫削峰。
以上,我用快递员和驿站的例子来说明异步、解耦、削峰分别的作用和应用场景,可能不太合适,但是我认为意思到了即可,能理解就行。.
2.2 消息队列的缺点前头说了,异步、解耦、削峰是驿站(消息中间件)的好处,那么有没有缺点呢? 肯定有啦。
系统复杂度提高、系统可用性降低
本来是一个简单不动脑,一家一家送的工作,现在快递员要学习怎么把快递入库驿站系统,系统复杂了。复杂了之后,可用性就降低了。比如我以前,我一件一件送,哪怕出问题了,我最多就是某一户的快递丢了,损失比较小,不影响我送下一户。现在所有快递都在驿站,要是驿站老板跑路了,或者今天驿站停电了,系统停用了,再缺德一点,发生火灾了,那就全完了,所有的快递都得完蛋。
还有一些问题,比如别人拿了不属于他的快递咋办(消费了不属于他的消息),或者一个快递两个客户都说是他的(重复消费),此外还有比如一致性的问题,这个问题涉及到zookeeper,有空专门研究一下。
缺点有,但是不能因噎废食,驿站的好处最起码站在快递员这边,是看得见的,对整个系统来说,消息中间件的好处,也是显而易见的,所以它越来越重要。
3、市面上有好几种MQ,你们为什么选择了rocketMQ/rabbitMQ/kafka?这个问题就是选型问题,我在之前关于java面试的新想法_Hassan猿的博客-CSDN博客这一篇文章中曾经说过,我认为选型几乎是一个社招必问的问题。
关于MQ的选型,着重就在于对面试人视野、知识储备、是否真正设计项目架构、是否在以后能担当骨干这么些点上。这里也整理了一些选型的特点和方法。
3.1 MQ选型要素功能维度:也就是业务场景,具体场景具体应用,你的项目需要用MQ解决什么问题,会决定你选什么MQ
性能:吞吐量、时效性,这就是是看你的业务数据量等要求
可靠性:消息丢失率
可用性:重启代价,无故障运行时间等
运维:监控、容灾、扩容等后期考虑
社区和生态发展:API丰富程度、社区强大性、社区活跃度等
我们针对MQ的选型可以从以上这些要素着手,其实不只是MQ,其他技术的选型大部分也都可以依据这些要素。
3.2 具体对比RocketMQ
rocketMQ在阿里集团被广泛使用,包括阿里云、淘宝等模块,应用业务有订单、交易、充值、流计算、消息推送、日志流处理、binglog分发等场景。rocketMQ原本是国内社区,这是人们比较担心的一点,担心阿里要是出了点什么问题,社区倒了,这个技术也就算完蛋了,社区是所有开源软件技术里非常重要的组成,只有足够强大的社区支持,一个技术才会有生命力。但是目前好像rocketMQ已经由阿里送给了Apache,也就是说共享了Apache的社区环境,从社区生态来说,已经没有什么问题了。
Kafka
老牌劲旅了属于是,2011年由linkin开源的项目,主要模式是发布-订阅,也是Apache顶级项目,拥有极高的吞吐量,近乎无限。kafka的目的性很强,偏向于日志收集和传输,不支持事务,对消息的重复、丢失等没有严格的要求,比较适合会产生大量数据的互联网服务的数据收集业务。
RabbitMQ
使用erlang语言开发,基于AMQP协议实现。主要特征是面向消息、队列、路由(包括点对点模式和广播模式)、可靠、安全。适合用于对数据一致性、稳定性、可靠性要求非常高的场景,对性能和吞入量要求在其次。更多地用于企业系统内部。
①吞吐量测试
在服务端同步发送性能上,kafka>rocketMQ>rabbitMQ,kafka在吞吐量上当仁不让,但是rocketMQ也不差,毕竟经历过双十一这种地狱历练的,不是等闲之辈。
②优先级队列
这是个什么概念?首先优先级队列只在发生消息堆积的时候才会发挥作用,就是说,消费者在消费消息的时候,是否只能按顺序消费,能不能跳着消费,也就是是否支持设置优先队列,我跳过其他消息,优先去消费某一个消息队列。如果你压根就没有发生消息堆积,你跳着读?跳个锤子,你直接消费就完事儿了。
③延迟队列
那什么又是延迟队列呢?就是有某些消息,生产者发送完之后,不想立刻让消费者消费,想让消费者在特定时间才能拿到该消息
④可靠性
⑤关注度(成熟度)
⑥所属社区及社区活跃度
⑦事务
⑧集群
⑨支持开发语言
⑩消费模型
什么是消费模型,Push推,Pull自己拉