对整个分布式应用系统而言,一共分为两种调用,一种是同步调用,一种是异步调用。同步调用就是基于RPC,基于链路监控等等的一套东西,而今天分享的主题是则基于异步调用的。
大家仔细思考一下,我们所做的整个分布式系统中有多少链路是同步调用的,又有多少链路又应该是异步调用的呢?比如在一个下单流程中,有多少核心链路是使用同步调用的,有多少需要异步调用?
消息中间件的使命是让消息传递无边界,传递无边界有两个概念,第一个就是你可以把包括应用之间的通信等各种字节流这样的消息传到各个端,包括手机端,物联网,智能电灯,汽车以及云上应用服务等。第二个就是消息可以传递任何东西,从最小的几个字节到最大的几百兆的文件。
一、为什么使用消息中间件
1.云是地基
先问一个问题:为什么要使用消息中间件?现在开发分布式应用系统,很少有人从头开始写代码,因为现在已经不是一个人憋在酒店里写一个软件就可以成功的年代了,现在往往需要团队作战,而且还有可能从更大的角度来讲,是一个生态在作战,并且你所在的生态有可能和其他的生态存在竞争的关系。那什么是中间件呢?
用现实生活类比来讲,现在房价卖的很高,以前卖房子该怎么去卖?开发商需要先买块地基,然后在地基上搭建个框架,最终将其装修完了以后卖给客户。现在卖房子怎么卖呢?可以直接用现成的框架,无论最终客户想要装修成写字间也好,别墅也好,公寓也好,都可以快速地卖给客户,快速实现资金回笼。所以这里有一个理念是:云实际上就是一个地基,用户不需要去搞自己的IDC。
2、中间件是框架
而中间件相当于框架,有了云的地基,有了中间件的框架,就可以在上面快速地搭建业务,实现将业务的快速变现,这才是业务的基石。中间件是应用快速落地的加速器,它可以让团队拥有快速试错的技术能力。
二、消息场景核心问题-解耦
在整个的分布式应用中,需要将应用拆分成很多个WAR包,那么有多少链路需要同步调用,多少能使用异步调用?以经验来说约70%~80%的链路都可以使用异步调用。阿里消息中间件的延迟是在1ms~5ms之间的这样的一个粒度,实际上类似于准实时的概念,甚至在秒杀的某类场景当中减库存也可以是异步的,通知以及实时监控这些链路全部都可以异步实现。设想如果全部都使用同步调用进行设计,现在淘宝的一个下单流程需要几百个调用,如果全是同步的话,实现这样的下单需要大概几十s量级的时间,那么淘宝为什么能做到下单之后立即就能成交,其实是因为其后面全部链路都使用的是异步调用,并且只有在核心链路中某些最核心的交易环节中的几个环节才会使用同步调用。
在这里分享一个可能给大家一些启示的泰国电影,这个电影一共有三个主人公,父亲,女儿和女儿的男朋友,当时女儿不顾家族和父亲的反对一定要和男朋友交往,父亲实在是拗不过女儿就同意了,但是这个父亲却采取了一个非常残酷的措施,把女儿和她的男朋友用手铐拴在一起,于是每天无论吃饭还是睡觉,每天任何行动女儿和男朋友都在一起。最后的结果相信大家都猜到了,开始非常快乐,最后女孩的男朋友疯了,在疯之前将女孩杀死了,而父亲也因为这个事情从此一蹶不振。这是一个真正的悲剧,人生是这样,如果两个事物太过于耦合在一起的话就将是个悲剧。
设计程序架构也类似,如果你将所有程序都紧耦合的设计在一起,对于这样高度耦合的架构,相信在不久的未来随着业务的发展,你所设计的系统也会成为一个悲剧。真正的场景是在分布式应用中,比如说应用中A和B两个功能模块,既希望他们解耦开,但是又希望他们互联达到目标状态。我们不希望B不可用时候,A也不可用,这是目标。那么为了这个目标能采取什么策略呢?
第一步,需要增加很多A和B的实例,但是这样带来的问题是链路也会增加,调用也会增加。因为A的配置或者B的配置要更改,那么第二步就需要在A和B中间加一个负载均衡器,这是最传统的做法,你增加多少,我就增加多少,大家互不关心对方的配置。
第三点,当有一天做大促销的时候,或者当你的客户大量增多的时候,大量的流量到来,A的流量需要直接传导到B。所以阿里在整个消息领域引出了一个非常重要的概念,叫做Topic或者Queue(队列)。Topic其实也是基于队列的,这个东西的作用是:第一负载均衡,第二点它可以充当一个大的缓冲,这样可以把所有的流量缓存到Topic里面。
举个例子说明Topic的概念:这张图有三部分,生产者,Topic和消费者。生产者生产的消息放到对应的Topic里面,谁取了这个消息或者谁订阅了这个消息就把消息拿走。实际上Topic的概念就像是变压器,变压器是220V的出来的也是这个流量,接入其他的也是这个流量。这给最终设计系统带来一个好处就是首先对于后面的这些应用而言,它们不会因为前面像洪水一样的流量而被压垮。第二个更为重要的就是在设计整个系统的时候就不会有更多的成本浪费在这些旁枝末节的服务上。
再举个例子,做秒杀业务时下单应用非常重要,对这个应用扩展了100台机器,下面的通知比如发邮件的应用,需不需要也扩展100台机器呢?其实是不需要的,虽然还是需要发邮件,但是可以保证邮件以平稳的流量发送,只需要扩展5台或者10台来满足基本需求就可以。这是两个最大的好处,中间的这个Topic,也就是消息中间件就像一个万能的变压器一样,即便大洪流来了经过它也变成比较顺畅的流量。
接下来举几个现实中的例子探讨一下到底哪些链路需要异步。
流程推进:就是做工作流或者审批流,再有就是订单的流转,下订单,减库存,使用优惠券结算,最终通知用户或者订单超时等等。这是第一点,流程推进是之前用的最多的。
定时消息:消息中间件MQ支持一个定时或者延时的消息,在电商里面主要有两种应用场景,一个是客户下单30分钟之后,订单可能会判定为超时,所以在客户下单之后需要异步发一条消息;并且在30分钟之后,如果订单还没有支付,就被判定为超时并将其关掉。另外一个就是支付提醒,用户下单之后10分钟还没有支付,那么会对其发送一个支付的提醒。这样带来的最大好处就是也可以自己写轮询条件或定时程序,首先对订单或这张表或者其他的多个表进行轮询,但是这些东西其实不需要去做,只需要发一个定时的消息就可以了,触发条件就会发送那个消息。
日志监控:如果系统足够大并且对实时性要求比较高,日志全部要异步地放到实时计算的引擎里面。
社交互动:现在Facebook用MQTT协议做社交,对于其他类似微信的社交以及现在比较火的视频直播聊天室,点赞送花买礼物等这种对于消息来说的巨大挑战:首先要求实时性,比如在聊天室直播的过程中送花的等待时间不能过长;其次是并发,芒果TV在超女100强比赛的时候也是用了视频直播,包括熊猫TV在选熊猫女郎的时候也是,当聊天室里突然冲进去几百万人的时候,订阅的关系就变得非常复杂,就是说我和你是好友,我发的东西,你应该能看见,但是我跟她不是好友,没有订阅关系,我又和某一个兴趣组有订阅关系,这样就形成了多级的订阅关系,这时候再发消息谁可见谁不可见就取决于订阅关系是什么样的。如果我发的消息之后,一百万人要同时都能接受到这个消息,这是对消息领域一个非常大的挑战。
三、什么是阿里云MQ
阿里云是如何解决这个问题的MQ这个产品已经有7年的历史,并且MQ是经过双十一几千亿条消息流量检验的。第二个就是这个产品在开源社区进行了部分的开源,因为第二阶段需要扩展影响力,所以就将产品一部分进行开源,而开源版本的MQ也有很多电商在用。这就是MQ产品的历史。
从商用的结果来看,阿里的消息队列MQ应该是全球性价比最高的,因为它的计费很简单,就只有API和Topic调用这两块费用。客户建一个Topic就有一个资源占用费,而且计费是阶梯的,其他的消息产品包括亚马逊,微软以,由于收的消息有多种造成很难计算费用,比如要通过调用次数收费,网络流量也需要收费,出口的费用,存储的费用甚至积压的费用都会收取,而阿里云的MQ只收取API的调用费用和Topic的资源占用费用,所以很清楚。
下图是MQ的入口,整个产品都是在这个叫做阿里云互联网中间件里面。互联网中间件包括了企业级分布式应用服务EDAS,消息队列MQ和分布式关系型数据库服务DRDS。我们的团队是服务于整个阿里巴巴集团的,阿里系中大多数应用 都在用我们的中间件。
再一张图是主要控制台界面,在这里可以进行Topic管理,发布管理以及订阅管理。查询方面可以进行Topic查询,Message Key查询和按照Message ID查询,并且还有后面的报表,从这里能获得比如10分钟内TPS是多少,生产了多少消息,失败了多少这样的数据。还有监控报警,整个消息领域内有两个数据最为关键,一个是RT的时间,也就是发送消息的延迟,我们能将其控制在1ms~5ms,这个数据是非常准实时的;第二个是堆积,当大流量到来时会堆积很多消息,堆积对很多消息是很重要的,有的消息中间件堆积了一亿条消息,再将其重新拉取的时候将会使性能下降非常多。如果订单的业务堆积了1000条就需要报警了,需要看看应用是不是已经报错了,所以监控是一个非常重要的功能。
阿里云消息中间件的特点:
- 双11验证:MQ是经过了双十一验证的,MQ不是阿里看到了未来云计算领域消息是很重要的部分而去开发的,这个完全是阿里的业务需求加上七八年的技术沉淀下来的结果。
- 体系完善:阿里云MQ的体系比较完善,首先我们在内部产品名叫做MetaQ和Notify,同时有一部分是开源的,叫做RocketMQ,企业今天可以去IOE,未来真的强大到可以专门研究中间件,可以转移到开源的产品上去,这里没有技术绑定的风险。
- 高可靠和高性能:MQ对消息是多份存储的,可靠性非常高。并且是高性能的,对于单机TPS,在此领域很多人说Kafka性能很高,但是实际上阿里云MQ比Kafka的性能还要高,现在单机性能已经达到10万TPS以上,也就是一秒钟发十万条以上信息,并且这仅是对于单机不是集群。
- 多协议:MQ还支持多协议,不仅支持TCP还支持HTTP以及MQTT,另外MQ还可以像以前的传统软件一样独立部署,如果想不在云上使用,而在自己的IDC环境中使用MQ也可行。
TCP VS HTTP VS MQTT:专业 VS 简单 VS 物联
在整个消息领域里面,大概有这三个协议,对于支持TCP协议的消息,TCP的协议定义长连接是最稳定的,玩法也是最多的。在TCP上可以做到“推拉结合”的方式,在消息里面也有两种基本传递的方式,一种是“拉”一种是“推”,淘宝之前使用“推”的方式,这样比较快,但是大家后来发现这种方式就像是喂金鱼,如果下游消费能力不好很容易被撑宕机,所以后来改为了“拉”的方式,并且将其做成类似“推”的方式,这时候“拉”的方式已经和“推”的方式效率上差不多了。“拉”的方式最大优点就是下游消费端可以按照自己消费能力控制消费进度,即使下游处理能力没有那么强,消息依然会按部就班处理,但是绝不会崩溃。“推”的方式则是全部推给下游,很容易造成崩溃。
在物联网和移动端就完全不一样了,因为终端不同,它的消息很小,所以采用真正“推”的方式,其次这样的消息不会存很长时间,很多消息会被丢弃,很多场景应用“推”的方式。
HTTP相比TCP要慢很多,但是HTTP有好处,很多小众语言包括GOLang,Python和PHP等都支持,大家对HTTP的接受程度很高,所以也会提供HTTP接入。
另外在整个消息领域有很多商业的也有很多开源的,有很多成熟的也有很多不成熟的,甚至几个人用数月时间也能写出一个消息中间件,但是这个就像学日语一样,入门很简单但是要想真正把消息中间件做到透没那么简单,需要研究CPU,磁盘等等很深的东西。
MQ VS Kafka VS ActiveMQ
对比一下,MQ与之前提到的 Kafka,Kafka 基于日志的场景,但是如果需要传输订单的消息,比如金融报文,甚至对汽车遥控的消息,如要使用 Kafka 有效性就会低一些。另外一个就是ActiveMQ,如果用ActiveMQ就会很简单,但流量出现洪峰的时候,性能就会下降非常多。另外MQ在支持事务方面是其他消息中间件所不具备的。MQ提供事务消息,应用与应用之间有服务的分布式事务,数据库之间也有多个分布式事务,比如同时查50个库,这种叫分布式数据库的事务。在消息领域也有分布式消息,也叫作事务消息。就是在做本地事务和提交消息之间,把这两阶段联动成一个事务,之前如果自己写的话,需要判断它的提交状态,所有事物的回滚都需要自己做。MQ使用事务消息能保证操作的原子性,要么全成功,要么全失败。
Kafka存储局限性 :链接
MQ和Kafka 18项差异对比 :链接
另外在阿里云上面有两个消息服务,MQ消息队列和MNS消息服务,MQ是阿里云专业的消息中间件,是阿里双11使用的消息中间件,支持TCP、HTTP、MQTT三种协议。产品首页:链接
应用场景解析:物联网通用消息协议MQTT
消息队列Message Queue可应用在多个领域,包括异步通信解耦、企业解决方案、金融支付、电信、电子商务、快递物流、广告营销、社交、即时通信、移动应用、手游、视频、物联网、车联网等。
而基于物联网的应用是天然的基于消息的分布式应用。消息是构建物联网应用的基础,每个传感器将成为系统中的节点,节点之间依靠消息异步通信。
物联网消息解决方案=MQ+MQTT
物联网消息解决方案的大致过程是这样的,物联网消息从终端上传到云上来,首先经过云盾安全监测和SLB负载均衡,再到MQTT的网关进而进入核心服务,最终短信以及E-mail网关将这些数据发出去。
其中最重要的一点就是链路监控的功能。MQ消息中间件使用了鹰眼监控,可以监控消息从哪一台机器发出来,其RT时间为多少秒,发到哪个Topic,之后被那个订阅组消费了,之后订阅组下面有挂载了多少台机器,哪一台机器接入成功了,哪一台接入失败了,实现真正地监控消息轨迹,而不是让用户去查看日志。
最后想说一点关于创业方面的,创业公司最重要的是试错的能力和商业模式的验证,使用中间件,使用异步解耦的消息可以让创业团队,拥有快速试错、快速创新的技术能力,可以让技术团队专注业务应用开发,从而实现整个团队的业务快速发展。
文章作者:马雷 (花名:阿仁)
编辑:贾子甲 (漫步~云端) 、 Sheeta