- 美团外卖作为一个超级业务方,业务内又运营多个方向业务,如流量业务、交易业务、商家业务、商品业务、营销业务、广告业务等。
综上所述,可以发现美团外卖不仅仅自身业务比较复杂,而且对外的角色也很复杂。在美团内部,外卖不仅仅是美团平台的一个频道业务,而且自己本身也是一个平台业务,同时美团外卖还承担着新业务发展的平台角色。这意味着想要支持好美团外卖业务的发展是一件非常有挑战的事情。
1.3 美团外卖移动端历史架构概述
好的架构源于不停地衍变而非设计。美团外卖的架构,历史上也是经历了很多次迭代。由于外卖业务形态不断地发生变化,原有的设计也需要不断地跟随业务形态进行演进。在不断探索和实践过程中,我们经历了若干个大的架构变迁。从考虑如何高效地复用代码支持外卖App,逐渐地衍变成如何去解决多端代码复用问题,再从多端的代码复用到支持其他频道业务的平台架构上。在平台化架构建设完成后,我们又开始尝试利用动态化技术去支持业务快速上线的诉求。如今,我们面临着多端复用、平台能力、平台支撑、单页面多业务团队、业务动态诉求强等多个业务场景问题。下文我们针对美团外卖移动端架构的变迁史,做一些简单的概述,以便读者阅读本文时能有更好的延续性。
1.3.1 组件化架构
早期阶段,美团外卖作为公司的一个孵化业务,在2013年底完成了美团外卖App的1.0版本。随着外卖业务的验证成功和跑通,订单量也快速增长,在2014年底突破了日订单量100万。随后在2015年2月,外卖以Native的形式接入美团App,成为美团App的一个业务频道。在接入过程中,我们从美团外卖App拷贝了大量的代码到美团App的外卖频道,两个App上的外卖业务代码也分别由两个独立的团队维护。早期外卖业务变化快,App迭代频繁,写代码的方式也比较粗放,同时美团App也处在一个平台化转变的时期,代码的稳定性和质量都在变化和提升当中。这些因素导致了外卖代码内各子系统之间耦合严重,边界模糊,“你中有我,我中有你”的情况随处可见。这对代码质量、功能扩展以及开发效率都造成很大的影响。此时,我们架构重构的目的,就是希望将各个子系统划分为相对独立的组件,建设组件可以直接复用,架构如下图所示:
1.3.2 平台化架构
如上文所述,大家可以知道美团外卖和美团外卖频道是由不同的团队在维护发展。2015年,公司考虑到业务发展的一致性,将美团外卖频道团队正式归于美团外卖。从组织架构上来说,美团外卖和美团外卖频道,逐渐融合成一个团队,但是两端的差异性,导致我们不得不仍然阶段性地维持原有的两班人马,各自去维护独立外卖App和美团外卖频道。如何解决这个问题?两端代码复用看起来是唯一的途径。另外,随着业务的快速发展,外卖App所承载的业务模块越来越多,产品功能越来越复杂,团队规模也越来越大,如闪购、跑腿等业务想以独立的Native包的形态接入外卖App,还有外卖的异地研发团队的建立,都带来了挑战。这使得我们在2017年开始了第二次架构重构——平台化架构,目标是希望能够支持多端复用和支持不同团队的业务发展。通过抽象出平台能力层、业务解耦、建立壳容器,最终实现了平台化架构,架构如下图所示:
1.3.3 RN混合架构
在平台化架构之后,美团外卖功能持续增加,美团外卖客户端安装包的体积也在持续增加。回顾2017年和2018年,每年几乎都增长100%。如果没有一个有效的手段,安装包将变得越发臃肿。另外,由于原生应用需要依托于应用市场进行更新,每次产品的更新,必须依赖用户的主动更新,使得版本的迭代周期很长。业务上的这些痛点,不断地督促我们去反思到底有没有一种框架可以解决这些问题。
在2015年的时候,Facebook发布了非常具有颠覆性的React Native框架,简称RN。从名字上看,就可以清楚的明白,这是混合式开发模式,RN使用Native来渲染,JS来编码,从而实现了跨平台开发、快速编译、快速发布、高效渲染和布局。RN作为一种跨平台的移动应用开发框架,它的特性非常符合我们的诉求。美团也积极的探索RN技术。在RN的基础上,美团在脚手架、组件库、预加载、分包构建、发布运维等方面进行了全面的定制及优化,大幅提升RN的开发及发布运维效率,形成了MRN(Meituan React Native)技术体系。
从2018年开始,美团外卖客户端团队开始尝试使用MRN框架来解决业务上的问题。使用RN的另一方面的好处是,能逐渐的抹平Android和iOS开发技术栈带来的问题,使用一套代码,两个平台上线,理论上人效可以提升一倍,支持的业务需求也可以提升一倍,架构如下图所示:
2. 美团外卖容器化架构全景图
2.1 什么是容器化架构
上文说到,外卖业务已经发展到多App复用、单页面多业务团队开发的业务阶段。要满足这样的业务场景下,寻求一个可持续发展的业务架构是件不容易的事情。经过我们之前架构演进,我们获得了宝贵的经验:在平台化架构的时候,我们将App和业务进行解耦,将App做成壳容器,业务形成独立的业务库,集成到壳容器里面,从而屏蔽了多App的问题,提高了业务的复用度。在RN混合式架构里面,我们引入了RN容器,通过这个容器,使得业务屏蔽了Android和iOS的平台差异。借助这些成功的经验,我们进一步思考,如果我们尝试进一步的细分外卖的业务场景,将不同场景下的基础能力建设成壳容器,业务集成到容器内,是否可以更好的支撑我们多App复用、单页面多业务团队的当前现状呢?
容器化架构的愿景是:
- 希望将前端呈现业务的环境抽象出来,将能力进行标准化,形成统一的容器,通过容器去屏蔽平台和端的差异。容器提供上层标准统一的能力接口,使得业务开发人员专注于容器内的业务逻辑的实现,最大复用已有的能力,而不用关注现在的环境是Android还是iOS,现在的端是美团App还是大众点评App。
- 容器和远端达成呈现协议,使得端上的内