美团-外卖客户端容器化架构的演进

挪动端混合开发技术性并不是一个新话题讨论,早在两年前,WebView容器、React Native、Weex、Flutter、微信小程序等手机端混合开发架构就风云变幻。为什么混合开发那么有诱惑力呢?大家构想一下假如能保证一次开发设计,跨平台重复使用,那麼针对公司而言,就可以减少用工成本费。针对研发而言,只要培训一个架构,就可以在Android和iOS双服务平台上开发设计。节省出来的成本费,可以投放到商品迅速认证、迅速发布。这对每个人而言都具有很大的诱惑力。这节先对于一部分手机端混合开发技术性实现一些简略的详细介绍,便于阅读者可以更好的了解后边的內容。

1.1.1 WebView容器

WebView容器的基本工作原理是根据Web技术性来完成页面和作用,根据将原生态的插口封装形式、曝露给JavaScript启用,JavaScript撰写的网页页面可以运作在系统软件内置的WebView中。那样做的优点是,针对网页开发者较为友善,可以迅速地完成网页页面跨端,与此同时保存启用原生态的能力,根据构建中继层和原生态能力连通。但这类设计方案,跨端能力受制于中继层,当启用以前沒有的原生态能力时,就必须提升桥。此外,ie内核的3D渲染单独于系统软件部件,没法确保原生态感受,3D渲染的功效会少许多。

1.1.2 React Native

2015年,Facebook发布了React Native,一经推行就备受关注。它的基本思路是利润最大化地重复使用前面的绿色生态和Native的生态,和WebView容器的最大的差别取决于View的3D渲染管理体系。React Native抛下了低效能的ie内核3D渲染,继而采用自身的DSL转化成正中间文件格式,随后投射到相匹配的服务平台,3D渲染成服务平台的部件。相对性WebView容器,感受会出现一定的提高。但是,3D渲染时必须JavaScript和原生态中间通讯,在有一些情景很有可能会造成卡屏。此外便是,3D渲染或是在Native层,规定开发者对Native有一定的熟知度。

1.1.3 Flutter

2018年Google推出Flutter,根据Dart语言表达搭建一套混合开发的研发部件,全部部件根据Skia模块自绘,在功能上可以和Native平台的View相提并论。Flutter站在古人的肩头上,参照了React的模式管理方法、Web的自制作UI、React Native的HotReload等特性,与此同时考虑到了与Native通信的Channel体制、自3D渲染、完备的开发环境链。Flutter与以上Recat Native、WebView容器实质上是不一样的,它沒有应用WebView、JavaScript编译器或是系统软件服务平台内置的原生态控制,反而是有一套自身独有的Widget,最底层3D渲染应用自己的性能卓越C/C 模块自绘。但绝大多数手机端发展趋势到今日,都早已建立了自个的架构,在目前根本上再加上Flutter,会产生原来架构和Flutter双服务平台并存的问题。现阶段,对新的App而言,是最被关注的跨端计划方案。

做为我国领跑的生活服务电商平台,美团外卖专注于用高新科技联接顾客和店家,给予服务项目以达到大家日常“吃”的要求,并进一步拓展至多种多样日常生活和旅游管理。而做为企业更为关键的业务之一,美团外卖从2013年建立至今,早已从单一的类目拓展到附近美食、新鲜水果、蔬菜水果、商场、花束、生日蛋糕等多类目,从早午晚饭,发展趋势到下午茶时间、夜宵,午餐、西餐厅、家常小炒、特色小吃、简餐、海产品、火锅店、川味、生日蛋糕、炭火烤肉、新鲜水果、饮品、甜品等多类型餐饮业。美团外卖可以说成现阶段电子商务行业,更为繁杂的业务之一。

业务的复杂,给系统软件架构也提供了很大的挑戰。美团外卖业务往往说成现阶段电子商务行业更为繁杂的业务,关键来源于以下几个方面特点:

总的来说,可以发觉美团外卖不仅本身业务比较复杂,并且对外开放的人物角色也很繁杂。在美团外卖内部结构,外卖不仅是饿了么服务平台的一个频道栏目业务,并且自身实际上也是一个服务平台业务,与此同时美团外卖还担负着新业务发展趋势的网站人物角色。这代表着要想适用好美团外卖业务的发展趋势是一件十分有探索的事儿。

好的架构来源于不断地衍变并非设计方案。美团外卖的架构,在历史上也是经历了很多次梯度下降法。因为外卖业务形状不断产生变化,原来的设计也必须不断追随业务形状开展演变。在勇于探索和实践过程中,大家经历了多个大的架构变化。从考虑到怎样高效率地重复使用编码适用外卖App,慢慢地衍变成如何去处理跨平台编码重复使用问题,再从多端编码重复使用到适用别的频道栏目业务的服务平台架构上。在平台化架构基本建设成功后,大家又逐渐试着运用动态性技术性去适用业务迅速发布的需求。如今,大家遭遇着跨平台重复使用、服务平台能力、平台支撑点、单网页页面多业务精英团队、业务动态性需求强等好几个业务情景问题。下面大家对于美团外卖手机端架构的变化史,做一些简易的简述,便于阅读者阅读文章文中时可以有更快的持续性。

1.3.1 组件化架构

初期环节,美团外卖做为企业的一个卵化业务,在2013年底完成了美团外卖App的1.0版本号。伴随着外卖业务的验证通过和跑通,订单信息量也持续增长,在2014年底提升了日订单信息量100万。接着在2015年2月,外卖以Native的方式连接美团外卖App,变成美团外卖App的一个业务频道栏目。在连接全过程中,大家从美团外卖App复制了大批量的源代码到美团外卖App的外卖频道栏目,2个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来3D渲染,JS来编号,进而达到了混合开发开发设计、迅速编译程序、迅速公布、高效率3D渲染和合理布局。RN做为一种平台的手机应用开发架构,它的特征十分合乎咱们的需求。美团外卖也充分的探寻RN技术性。在RN的基本上,美团外卖在钢管脚手架、组件库、预加载、工程分包搭建、公布运维管理等领域开展了全方位的订制及提升,大幅提高RN的开发设计及公布运维管理高效率,产生了MRN(Meituan React Native)技术性管理体系。

从2018年逐渐,美团外卖手机客户端精英团队逐渐试着应用MRN架构来处理业务上的问题。应用RN的另一方面的益处是,能慢慢的刮平Android和iOS开发设计技术栈产生的问题,应用一套编码,2个服务平台发布,理论上人效可以提高一倍,适用的业务要求还可以提高一倍,架构如下图所示:

上文写到,外卖业务早已进步到多App重复使用、单网页页面多业务精英团队开发设计的业务环节。要达到那样的业务情景下,寻找一个协调发展的业务架构是件不易的事儿。通过大家以前架构演变,大家获取了珍贵的工作经验:在平台化架构的情况下,大家将App和业务开展解耦,将App制成壳容器,业务产生单独的业务库,集成化到壳容器里边,进而屏蔽掉多App的问题,提升了业务的重复使用度。在RN混合式教学架构里边,大家引进了RN容器,根据这一容器,促使业务屏蔽掉Android和iOS的服务平台差别。依靠这种完成的工作经验,大家进一步思索,如果我们试着进一步的细分化外卖的业务情景,将不一样情景下的基本能力基本建设成壳容器,业务集成化到容器内,是不是可以更快的支撑点大家多App重复使用、单网页页面多业务精英团队的现阶段现况呢?

容器化架构的企业愿景是:

在我们把承重外卖业务的条件做好了抽象化和规范化后,就可以得到下列若干点益处。最先动态性特性提高,我们可以把原来务必在手机客户端上写的业务放进了远侧,业务的动态获得较大的提高,具有随时随地发布业务的很有可能。针对开发设计全过程来讲,编译程序布署的效率也取得了很大提高。假如牵涉到手机客户端的编码修改,那手机客户端的编译程序装包,即使是增加量的编译程序,也最少是秒级的编译程序速率。而容器化时,大家只装包必需的业务,把业务动态性下达到容器展现,手机客户端编码自身不可能有转变,那样就可以从秒级的编译程序降低到ms级的编译程序。一样,业务动态性下达,对降低手机客户端的包尺寸也是有较大的协助。

随后,容器坐落于运用以内,大家向运用中引进同样的容器SDK,容器屏蔽掉运用间的差别,针对Android和iOS服务平台,在设计上,根据容器这一层去尽量屏蔽掉服务平台间的差别,使业务开发者只必须了解容器,不用耗费很多的活力去关心运用和服务平台间的差别,进而促使开发设计高效率获得了很大程度的提高。

次之,容器化时,容器对承重的內容是有通讯协议规定的,承重的內容仅有达到容器界定的协议书才可以获得容器产生的益处,这促进业务获得了更粗粒度的细分化,业务开发设计情况下,对模块化设计的观念获得了确保。此外,容器这一层给予的插口在Android和iOS上是规范化的,业务的研发也由于依靠的规范化,而趋于规范化,双端业务一致性获得了提高。这种不确定性的架构益处,对将来的业务维护保养和拓展都奠定了比较好的路基。

全部外卖容器化架构可以依照从下向上,从左往右的角度开展讲解:

底层是服务程序,由于大家选用了H5和RN那样跨端技术栈,促使iOS操作系统和Android系统软件变成了底层。

服务程序以上是集团公司根据Native基本建设的基建,全企业通用性,遮盖了产品研发工程项目中各个方面的基础服务。

在基本建设以上是大家界定的容器层。大家试着用单一技术栈处理任何问题。但通过大家的探寻,感觉不大可能完成。好的架构要配对业务形状,业务的需求决策了我们不能挑选唯一的技术栈去处理任何问题,细分化外卖的业务情景可获得下列3个角度的网页页面归类:

直往上,便是垂直线的业务,外卖现阶段有总流量业务、买卖业务、店家业务、产品业务、广告宣传业务、营销推广业务、限时抢业务等。业务全是竖直往下依靠,立即由此可见容器,可见基本建设,可以有效地获得到各种各样早已建成的能力去进行业务的要求。

最上边是承重的App端,现阶段有四端,包含外卖、评价、美团外卖、限时抢这些。

右边是检测公布和网上监管,相对性于基本的手机端App架构来讲,容器化架构的检测公布和监管是更加精细化管理的。不仅要关心端自身的易用性,还要关心容器、容器承重的控制模块、模块展现的模版,模板里头的款式这种的易用性。

容器化架构相对性基本的手机端架构来讲,它从管理方法挪动端编码转化成管理方法挪动端容器基本建设编码和业务远侧开发设计编码,空出了容器和业务远侧下达。这不单单是对技术性上的挑戰,对长期性做客户端开发同学们,也必须一个逻辑思维转换的自动跳转。

一致性的挑戰:容器必须在好几个寄主运用当中运作,寄主运用的自然环境一致性可以直接影响到了容器的一致性。大家的对策是双手提前准备,一方面运用外卖业务的优点促进寄主运用的自然环境两端对齐;另一方面将容器基本建设成SDK,根据SDK将始终保持容器的一致性,也根据SDK内部结构的设计方案屏蔽掉运用间的差别;针对Android和iOS服务平台,大家根据分段的设计方案,尽量屏蔽掉服务平台的差别。总的来说,一致性的考验取决于(1)容器运作的寄主运用的自然环境一致性;(2)不一样运用不一样版本号容器的一致性;(3)Android和iOS平台容器的对业务的一致性。

动态发布的挑战:长期以来,客户端同学的开发概念里面只有App版本的概念,而当我们逐渐把业务代码做成远端下发时,将会新增一个线上动态发版的概念。当我们在发布业务的时候,相对以往的工作,多出需要去考虑这个业务的版本,可以运行的容器对应的App上下界版本。另外,发版的周期也会新增业务的发版周期,不仅仅是App的发版周期。这两者在一起将会产生新的火花,业务的版本和App的版本如何适配的问题,业务动态发版的周期和App的发版周期如何适配的问题。外卖这边的解决方式是建设主版本迭代+周迭代的模型。

监控运维的挑战:以往的移动端架构,我们更加关注的是端本身的可用性,然而当我们演进到容器化架构的时候,仅仅关注端的可用性已经远远不能确定业务是可用的了。我们需要从端的可用性延伸出下载链路、加载链路,使用链路上的可用性,针对每个重要的环境,都做好监控运维。

3.1.1 MRN容器简介

React Native框架本身只是一个运行时环境中的渲染引擎,可以将同一套JS代码分别在Android和iOS系统上最终以Native的方式渲染页面,从而为App提供了基础的跨端能力。但从工程化的角度来看,如果想在App中大规模地应用RN技术,除了RN框架本身外,还需要在开发、构建、测试、部署、运维等诸多方面的配合。MRN(Meituan React Native)是美团基于React Native框架改造并完善而成的一套动态化方案,在RN的基础上提供了容器化能力、动态化能力、多端复用能力和工程化保障。MRN在开发效率、稳定性、性能体验、动态化和监控运维等多方面进行了能力升级和扩展,满足了美团RN开发工程化的需要。目前,MRN已接入美团40多个App,核心框架及生态工具有超过100位内部代码贡献者,总PV超过4亿。

3.1.2 Roo组件库

下面再介绍一下外卖建设的两个UI相关的技术项目,Roo组件库和组件样式动态配置。

外卖在2018年底开始试验MRN容器在外卖业务上的应用,并在2019年上半年进行了大面积的页面落地。目前,外卖已有近60个RN页面上线,占外卖页面比例超80%,其中包括Tab页面“我的”、提单选择红包页、订单评价页等高PV页面。MRN容器的接入,给外卖App的容器化、动态化、人效提升、包大小瘦身等方面都做出了不小的贡献。

3.2.1 Titans容器简介

Titans容器是美团系App统一的Web容器组件,基于苹果提供的WebView组件,将WebView容器化,统一了WebView的UI展示和交互方式,规范了桥协议的使用范式,同时预置了诸多基础能力和业务能力。Titans容器大大提高了Web页面的开发效率和用户体验上的一致性。

Titans容器在外卖业务中的使用场景非常丰富,其中最重要的使用场景是各种运营页和活动页,例如点击首页顶部Banner的广告落地页、为你优选、限时秒杀等活动运营页等;还有客服页、帮助反馈页、商家入驻页、美团公益页等功能性页面;作为一级入口页面的美团会员页面,也是一个基于Enlight的Titans容器。

外卖容器化建设,首先需要要区分的是核心页面和非核心页面。外卖业务中对核心页面的定义是页面DAU>美团DAU的5%或者是下单关键路径。为什么要先按照是否为核心页面进行拆分呢?重点就在于改造的成本。核心页面的业务复杂度决定了它不容易做全页面的动态化,它比较适合做局部的动态化方案。核心页面的复杂度在于业务本身复杂,最重要的是核心页面往往会有多个垂直业务团队共同的开发维护,大家各自有重点关注的模块,做全页面的动态化,无法做到有效的物理隔离。

而对于非核心页面,业务功能和交互相对简单,组织关系也较为确定,更适合做标准的MRN和Titans容器化。所以我们的策略是核心页面做到支撑页面模块级别的业务动态和复用,非核心页面可以做到页面级别的动态化和复用。页面容器化的核心含义就是把一个页面划分为若干个模块,每个模块成为一个业务容器,每个容器的填充既可以用Native的方式实现,也可以用Mach实现(Mach是外卖自研的页面局部动态化技术),可以支持iOS/Android/小程序三端跨平台运行。页面本身则化身为容器的管理者,负责子容器的编排和布局,并支持其动态化。

页面容器化设计中主要分为三个阶段,模块有序化、模块编排化、渐进式业务落地。

从App页面开发的角度看,一个完整的页面可以按照不同的功能及不同业务属性划分出多个不同的模块。

业务构建泛指由多个业务模块组合拼装为一个业务页面的过程,涉及页面本身(UIViewController/Activity)以及各个业务模块的构造过程,前后端业务数据以及页面和业务模块之间的数据交互过程,业务模块内部的数据处理以及视图刷新流程。

模块标准化指的将业务构建涉及到的多个过程通过规范化的方式确定下来,形成唯一的标准。模块标准化一方面能够在解决业务共性问题的基础上提供业务难点专项解决方案,另一方面能够在框架基础上形成能力约束,减少重复建设、低质量建设的问题。

业务构建模块标准化中我们抽象了四层,下面将分别进行解读。

通过业务构建模块标准化的建设,业务模块已经是标准化的了,可以在跨页面间自由组合,这为页面容器化打下了基础。

在页面容器化中最基础的能力有以下几点:页面中业务模块可编排能力,动态上线前端AB实验的能力,增量上线动态模块的能力。实现这些能力最重要的就是进行前后端数据协议标准化建设。客户端根据数据协议中的模块唯一标识匹配并构造业务模块,在完成模块数据的填充后会根据数据协议中的模块布局信息完成模块的布局。针对Mach动态模块,我们创建了基于模板ID的模块匹配和数据填充流程,可以支持Mach动态模板的增量上线。在数据协议中针对前端AB实验我们预留了AB实验和通参字段,在数据填充阶段通过容器化接口传入动态模块中,用于支持AB实验的动态上线。

在容器化上线的过程中属于接口的大版本升级,为了保证容器的高可用性,客户端从模块级别和API级别实现了两套降级容灾方案。

模块级别的降级方案主要针对Mach动态模块,与Native模块不同,Mach动态模块需要预先下载动态模板才能正常地完成模块的载入和渲染。为了保证动态模块的加载成功率,我们一方面在接口上线前利用Eva(美团内部系统)对Mach模板的下载进行预热。另一方面,我们设计了动态模块的主动降级方案,针对动态模块的动态上线使用Native模块进行兜底降级,对于跟版动态模块使用App内置模板的方案进行兜底降级。

API级别的容灾方案主要为了保障客户端在新接口不稳定的情况下可以自行降级到旧接口。针对这个问题,我们对线上老接口设计了数据结构映射方案,在客户端通过配置化的方式可以把老接口的数据结构映射为新接口的数据结构。这样在上层业务无感知的情况下,可以做到容灾方案的上下线。

通过页面容器化,使得页面只需要关心页面级的构造方式,而无需关心某一模块内部如何实现动态化的。把页面与页面的模块分离,也符合目前外卖客户端的组织结构,有利于业务组间的协作。同时,页面容器化使得外卖核心页面具备了符合外卖业务场景下的动态能力,渐进式把Native静态模块过渡到具备动态能力的模块,从模块的维度使整个页面具备了动态能力。这种渐进式的迁移方案把容器迁移跟业务模块的迁移分隔开,大大降低了页面容器化改造的风险。

质量和性能指标是衡量我们App开发质量和用户体验的重要依据,是我们一直都非常关注的重点数据。在非容器化时代,我们大多数的指标都和App的使用环节紧密相关,因为在非容器化时代,逻辑链路相对简单,例如我们打开一个新页面时,我们首先创建页面实例,然后发起网络请求,同时页面会经历一系列生命周期方法,最后渲染。这时我们可能会关注网络请求的成功率和请求时间,页面的渲染时间,和过成功是否发生Crash,这个过程相对更短暂,指标更少,所以监控起来也更容易。

外卖的容器化大大提升了外卖业务的复用能力、动态能力、模块化和开发效率,但同时也带来了更长的逻辑链路,链路从时间维度上划分是:下载链路、加载链路、使用链路。例如我们在使用MRN容器的时候,会涉及到bundle的启动下载或预热下载,bundle解压缩,MRN容器引擎初始化,bundle加载,JS的加载、执行,页面渲染等步骤,其中的每个步骤都可能存在性能问题和质量风险。因此,我们需要升级我们的衡量指标系统来应对容器化带来的新的挑战。

因为容器化的使用形成了一个串行的链路,所以如果某个关键节点失败,会导致容器功能不可使用,关键指标的任务就是从上述众多的指标当中筛选出这些关键节点。例如在下载链路中bundle下载的成功率和API的成功率,加载链路中bundle加载的成功率和模块匹配的成功率,下载或加载失败都无法再进行链路中的后续步骤,针对上面的成功率指标,我们会添加分钟级别的实时监控告警,做到及时发现,快速响应和紧急修复。

在使用链路中模块渲染的成功率、Native Crash率、JS错误率也属于关键指标,这些任务的失败也会导致容器的不可用,针对这些指标我们也会采用实时监控措施,并且添加降级手段,例如回滚bundle版本,或者把MRN和Mach容器降级为Native容器。

上面讲到了容器化架构的各项衡量指标,那么把这些指标具体落到实处的工作就是线上的运维监控工作。工欲善其事,必先利其器,对于监控运维工作,一定要有合适的监控工具辅助配合才能事半功倍,公司内有很多优秀的监控统计工具可供使用,这里的难点就是如何根据监控的需要判断选择合适的工具。还有就是合理的划分监控维度和数据指标的优先级,例如对于能够影响到链路稳定性的关键指标,我们需要做到分钟级的监控,一旦出现问题就能及时收到告警,对于非关键指标,则通过生成日报的方式,方便开发者的统计和分析。

工具的使用上主要分为大盘工具、具体异常工具、灰度降级工具、告警工具等(以下是美团内部使用的工具)。

业务覆盖维度监控可以分为全局监控和局部(单业务)监控。

时间维度监控:可以按天、小时、分钟的时间维度。天级别的监控主要是一些非关键路径指标,例如一些性能指标,页面加载时间、页面FPS、JS渲染时间等,我们可以按天维度的生成数据报表,已邮件的数据发送日报。当App灰度上线时,我们会开始小时级别的监控,每过半小时通过IM软件向广播一些关键指标,方便开发者跟踪线上数据的稳定性。分钟级别的监控则是针对关键指标,观察分钟维度上的变化,如果关键指标超过阈值,或者波动过大,就会及时产生告警。

下面我们以一个开发者的视角去看一下外卖容器化架构的监控运维系统。从获取信息的方式上可以分为主动查询和被动推送,开发者可以通过监控工具监控全局和局部数据的变化趋势,也可以分析具体异常Case;也可以从IM工具,邮件等收到相关的推送数据,以便及时响应。在控制运维上,开发者可以通过Eva、Horn等美团内部的灰度系统进行灰度发布,当灰度期发现问题的时候,可以及时地通过停止灰度,版本回滚,关闭入口的方式进行降级容灾处理。

容器化使外卖业务具备了强大的动态化能力,但动态化能力又和需要相应的发布能力来支持,发布能力是我们业务开发质量和效率的重要保障,也是我们容器化建设工作过程中的重点环节,这一节主要介绍一下外卖容器化的发布能力。

从发布能力类型的角度看主要可以分为三种类型:(1)容器内容的发布,包括发布整个页面或者发布页面中的局部模块;(2)配置下发,通过API或其他配置平台,下发布局协议、AB测试、样式配置、功能配置、模板配置、容器配置等,大大提高了业务的灵活度和线上验证能力;(3)灰度、降级下发,通过UUID,用户画像等信息做到灰度发布,降级回滚等控制能力。

从发布资源的的角度看主要分为两种:一种是普通的资源,例如发布一个Web页面,或者通过发布新版API来控制页面局部容器的展示与否和展示的位置,同时我们也可以进行一些AB Test操作;另一种是bundle资源,主要是针对MRN容器和Mach容器,每个MRN容器和Mach容器的资源都会先被打包成一个bundle,然后通过发布系统下发到终端,然后终端解析bundle中的代码和资源,最终渲染页面。

从发布阶段的角度看,可以分为测试阶段、上线阶段、灰度阶段和全量阶段,其中上线阶段是最终的环节,我们增加了很多校验和保护手段来尽量保证上线操作的正确性。

虽然我们具随时备动态发布能力,但正常的版本迭代还是会存在中,所以外卖这边的节奏是周动态迭代+双周版本迭代,这保证了我们的开发工作有个一清晰的周期。在动态发布阶段中最关键的阶段操作上线阶段。以MRN为例,目前外卖业务中应有70多个bundle,再算上测试环境的bundle就有接近150个bundle,只是管理这些bundle就是一个复杂的工作,况且在进行上线操作时还是涉及发布的目标App、App版本的上下界、MRN版本的上下界等,一不小心就会造成操作失误,所以进行上线操作时需要非常谨慎。

我们针对操作上线阶段进行了事务流水线,通过流水线建立保护措施,一个bundle的上线要经历一个流水线的若干操作。首先,操作人根据上线SOP手册进行若干检查操作,同时编写标准格式的发布说明,然后周知相关核心人员后在操作系统上发起上线申请,Leader和QA收到申请后会进行检查并审批,审批通过后还要避开App使用的高峰期或节假日上线,上线后通过灰度发布观察各项数据指标,指标正常后全量发布。

bundle是我们最常发布的资源类型,这里再结合发布工具讲解一下bundle的发布过程。MRN和Mach都是以bundle的形式下发到设备终端的,我们在发布bundle的时候主要会用到两个工具,打包工具Talos和发布工具Eva(美团内部工具)。一个bundle的工程文件主要由三个部分组成:配置文件、源代码和资源文件,其中配置文件用于指导Talos对工程文件进行打包,多个bundle可以共享一份配置文件。当我们准备发布一个bundle时,先找到该bundle在Talos的发布模板,选择发布环境(测试或线上),然后进行一键打包,然后Talos会进行一系列流水线操作,包括Clone代码、配置环境、进行Lint检查、构建和上传等。Talos打包完毕后将bundle上传到Eva系统,然后Eva负责bundle的分包、上线、下线、灰度等操作,最终下发到终端设备上。

未来,我们还将引入美团住宿的MRN-DevOps来进一步的屏蔽当前多系统的问题,降低整个周期管理的成本,特别是发布前的人工检查成本,逐渐实现RD在一个平台上操作从研发到发布运维的所有实现。尽可能地减少人工成本,提升自动化。

上面介绍的是以bundle资源形式的发布流程,过程较为清晰简单。下面再结合外卖首页,介绍一下局部容器化的发布方式。外卖首页是典型的流式列表,在局部容器化的架构下,首页就是由一个个矩形容器以ListView方式布局的,容器分两种,Native容器和Mach容器,Mach容器是一个通用容器,我们可以编写不同的样式模板,下发到终端后交由通用Mach容器来渲染,以此达到只使用通用容器展示不同UI样式的目的,这里涉及了Mach的发布系统。

首页各子容器相当于一块块积木,它们的位置排布、展示与否、模板的选择等最终交由API控制,API具备了控制首页布局,样式展示的能力,而不再是单纯的数据源。同时,首页也涉及了AB能力、灰度降级策略等其实配置项下发系统。可以看到外卖首页的容器化是由多种发布能力配合支撑的,是外卖发布能力体系的“集大成者”。

好的架构是要随着业务的发展,不断演变去适应业务的发展。美团外卖从一个很小规模,每日单量只有几千的业务,逐渐地走到今天,每日单量峰值超过4000万,组织架构也从一个十几个人的团队,逐渐发展到现在多角色、多垂直业务方向,上千人共同协作的团队。移动端上的架构,为了适应业务的发展要求,也经历了组件化、平台化、RN混合化,再到现在向容器化的变迁。

容器化架构相对于传统的移动端架构而言,充分地利用了现在的跨端技术,将动态化的能力最大化的赋予业务。通过动态化,带来业务迭代周期缩短、编译的加速、开发效率的提升等好处。同时,也解决了我们面临着的多端复用、平台能力、平台支撑、单页面多业务团队、业务动态诉求强等业务问题。

当然,容器化架构带来好处的同时,对线上的可用性、容器的可用性、支撑业务的线上发布上提出了更加严格的要求。我们通过监控下载、加载、使用链路上的可用性,来保障线上动态业务的可用性。针对容器,我们利用成熟的测试基建,建设容器的自动化测试来保障容器的可用性。针对发布,我们建设迭代流程,配合发布流水线,将线上的发布变得更为可控。

截止到目前为止,外卖业务经过了几十个动态化业务上线窗口,累积共发版百次以上。未来半年,我们还将进一步从业务需求入手,将业务需求细分归类,让产品侧逐渐建立容器和动态化需求的概念,能够从源头上,逐渐的将业务进行划分,最终使得每个业务需求,都可以归类抽象成可以动态下发的业务和容器能力建设,从而进一步的完善容器化架构的能力和支持更多的的业务场景。

扫码免费用

源码支持二开

申请免费使用

在线咨询