订单业务模块到分布式高可用:美团外卖订单中心的演进之路
“ 美团外卖订单中心是如何用3年时间,从一个单一的订单业务模块发展到现在分布式可扩展的高性能、高可用、高稳定订单系统的?
美团外卖从2013年9月成交第一单以来,已走过了三个年头。期间,业务飞速发展,美团外卖由日均几单发展为日均500万单的大型O2O互联网外卖服务平台。平台支持的品类也由最初外卖单品拓展为全品类。
随着订单量的增长、业务复杂度的提升。外卖订单系统也在不断演变进化,从早期一个订单业务模块到现在分布式可扩展的高性能、高可用、高稳定订单系统。整个发展过程中,订单系统经历了几个明显的阶段,下面本篇文章将为大家介绍一下订单系统的演进过程,重点关注各阶段的业务特征、挑战及应对之道。
本文由「美团点评技术团队」授权InfoQ发布,ID:meituantech
老司机简介
何轼新美大餐饮平台外卖订单系统技术负责人。2013年加入美团,参与外卖早期大部分系统建设。2014年起,作为技术负责人,主导外卖系统的研发工作。目前,致力于推进新美大外卖订单系统的配置化、开放化、运维智能。
新美大外卖平台(美团外卖)是全球最大的在线订餐平台,致力于为消费者提供优质的外卖服务。
为方便大家更好地了解整个演进过程,我们首先看一下外卖业务。
外卖订单业务
外卖订单业务是一个需要即时送的业务,对实时性要求很高。从用户订餐到最终送达用户,一般在1小时内。如果最终送达用户时间变长,会带来槽糕的用户体验。在1小时内,订单会快速经过多个阶段,直到最终送达用户。各个阶段需要紧密配合,确保订单顺利完成。
下图是一个用户视角的订单流程图。
从普通用户的角度来看,一个外卖订单从下单后,会经历支付、商家接单、配送、用户收货、售后及订单完成多个阶段。以技术的视角来分解的话,每个阶段依赖于多个子服务来共同完成,比如下单会依赖于购物车、订单预览、确认订单服务,这些子服务又会依赖于底层基础系统来完成其功能。
外卖业务另一个重要特征是一天内订单量会规律变化,订单会集中在中午、晚上两个“饭点”附近,而其它时间的订单量较少。这样,饭点附近系统压力会相对较大。
下图是一天内的外卖订单量分布图:
总结而言,外卖业务具有如下特征:
流程较长且实时性要求高;
订单量高且集中。
下面将按时间脉络为大家讲解订单系统经历的各个阶段、各阶段业务特征、挑战以及应对之道。
订单系统雏形
外卖业务发展早期,第一目标是要能够快速验证业务的可行性。技术上,我们需要保证架构足够灵活、快速迭代从而满足业务快速试错的需求。
在这个阶段,我们将订单相关功能组织成模块,与其它模块(门店模块等)一起形成公用jar包,然后各个系统通过引入jar包来使用订单功能。
早期系统的整体架构图如下所示:
早期,外卖整体架构简单、灵活,公共业务逻辑通过jar包实现后集成到各端应用,应用开发部署相对简单。比较适合业务早期逻辑简单、业务量较小、需要快速迭代的情况。但是,随着业务逻辑的复杂、业务量的增长,单应用架构的弊端逐步暴露出来。系统复杂后,大家共用一个大项目进行开发部署,协调的成本变高;业务之间相互影响的问题也逐渐增多。
德达侦探所
早期业务处于不断试错、快速变化、快速迭代阶段,通过上述架构,我们能紧跟业务,快速满足业务需求。随着业务的发展以及业务的逐步成熟,我们对系统进行逐步升级,从而
更好地支持业务。
独立的订单系统
2014年4月,外卖订单量达到了10万单/日,而且订单量还在持续增长。这时候,业务大框架基本成型,业务在大框架基础上快速迭代。大家共用一个大项目进行开发部署,相互影响,协调成本变高;多个业务部署于同一VM,相互影响的情况也在增多。
为解决开发、部署、运行时相互影响的问题。我们将订单系统进行独立拆分,从而独立开发、部署、运行,避免受其它业务影响。
系统拆分主要有如下几个原则:
相关业务拆分独立系统;
优先级一致的业务拆分独立系统;
拆分系统包括业务服务和数据。
基于以上原则,我们将订单系统进行独立拆分,所有订单服务通过RPC接口提供给外部使用。订单系统内部,我们将功能按优先级拆分为不同子系统,避免相互影响。订单系统通过MQ(队列)消息,通知外部订单状态变更。
独立拆分后的订单系统架构如下所示:
其中,最底层是数据存储层,订单相关数据独立存储。订单服务层,我们按照优先级将订单服务划分为三个系统,分别为交易系统、查询系统、异步处理系统。
独立拆分后,可以避免业务间的相互影响。快速支持业务迭代需求的同时,保障系统稳定性。
高性能、高可用、高稳定的订单系统骚妹>金希澈韩庚
重庆景点订单系统经过上述独立拆分后,有效地避免了业务间的相互干扰,保障迭代速度的同时,保证了系统稳定性。这时,我们的订单量突破百万,而且还在持续增长。之前的一些小问题,在订单量增加后,被放大,进而影响用户体验。
比如,用户支付成功后,极端情况下(比如网络、数据库问题)会导致支付成功消息处理失败,用户支付成功后依然显示未支付。订单量变大后,问题订单相应增多。我们需要提高系统的可靠性,保证订单功能稳定可用。
丰富的反义词
另外,随着订单量的增长、订单业务的复杂,对订单系统的性能、稳定性、可用性等提出了更高的要求。
为了提供更加稳定、可靠的订单服务,我们对拆分后的订单系统进行进一步升级。下面将分别介绍升级涉及的主要内容。
性能优化
系统独立拆分后,可以方便地对订单系统进行优化升级。我们对独立拆分后的订单系统进行了很多的性能优化工作,提升服务整体性能,优化工作主要涉及如下几个方面。
异步化
服务所需要处理的工作越少,其性能自然越高。可以通过将部分操作异步化来减少需要同步进行的操作,进而提升服务的性能。异步化有两种方案。
线程或线程池:将异步操作放在单独线程中处理,避免阻塞服务线程;
消息异步:异步操作通过接收消息完成。
异步化带来一个隐患,如何保障异步操作的执行。这个场景主要发生在应用重启时,对于通过线程或线程池进行的异步化,JVM重启时,后台执行的异步操作可能尚未完成。这时,需要通过JVM优雅关闭来保证异步操作进行完成后,JVM再关闭。通过消息来进行的,消息本身已提供持久化,不受应用重启影响。
阿胶的功效具体到订单系统,我们通过将部分不必同步进行的操作异步化,来提升对外服务接口的性能。不需要立即生效的操作即可以异步进行,比如发放红包、PUSH推送、统计等。