移动开发实战:生态型App的架构实践分享
转载本文需注明出处:微信公众号EAWorld,违者必究。
其实文章的题目纠结了很久,最后还是采用了“生态型App”这个词,这个词可能不是一个约定俗成的词,但却是这篇文章的主线,我将会从以下面三个维度展开,期望能够给正在从事相应工作的移动架构师以启发,也欢迎大家一起探讨。
本文目录:
一、什么是生态型App
二、生态型App的特点
三、生态型App对架构的挑战与实践
一、什么是生态型App
什么是生态型App?正如开题说的,这个词我纠结了很久,但是我还是以生态型App来作为题目的关键词,那就有义务稍微解释一下这个词。众所周知,在移动互联发展到这个阶段,一个新的App推广起来越来越难。用户大量的时间都会聚焦微信、支付宝等这些超级App,我称其为生态型App。
生态型App一般提供了一共生的生存环境(运行环境)以及相同的约束(规范和API等),允许不同的团队或个人,在允许的情况下,自行的研发或相同或者不同的移动相关的功能。相关功能运行在一个进程里,相互间独立,且与同在的环境有一定的交互。
生态型App区别与传统的App,除自身提供的功能外(比如微信的IM功能),更多的功能可以由三方的团队自行完成。除了ToC的超级应用外,也特别适合多团队、跨地域、多供应商的大中型企业使用。
二、生态型App的特点
区别于传统的App,生态型App具备以下的特点:
第一、开发的独立性。
这是生态型App的基础,开发的独立性,确保了多个团队能够并行开发,并且无需互相依赖,其应用的功能又与生态型App本身独立,确保了其功能的自由成长。
开发期的独立型,并不代表没有约束,恰恰相反,为了能够让生态型App有健康的发展,相同的约束是必须的。正如我们都相对熟悉的微信,在开发公众号相关的功能时,我们要遵守微信的相关的API的规范。甚至针对现在狂推的微信小程序,我们还必须采用其特有的开发工具,遵守其特有的DSL语言进行开发。
总结来说,开发的独立性,并不是说技术上的随意性,不受约束,而是说,从团队、时间、功能上等角度的独立性。看似简单的一个特点,实际上,并不简单,一个简单的考量就是,多少App增加一个功能时,都必须调整代码重新打包,上线。
第二、运行态的共生性。
运行态的共生性是生态型App的重要属性。从开发的独立性角度看,这个是现在任何手机操作系统都具备的特点。实际上,共生性是指任何功能的加入都与原有的生态中的功能在同一个运行态中,简单说是在一个进程或者一组相关进程内。
因为共生,所以新增的功能才能使用到生态型App带来的诸多益处,同时可以让生态型App得到更多新增功能带来的附赠价值,比如用户的使用信息等。
如果不考虑共生性,开发期的独立性完全可以考虑以独立的App为单元进行业务功能的开发,实际上真毫无裨益,越来越多的人并不愿意让自己的手机中安装更多的App,这也是大量用户在近年来在手机中没有安装新的应用的重要原因。
这里插一句话,我本人暂时(或许将来会改变)并不看好PWA的发展的一个重要原因也在于此,难道用户不愿意安装新的App真的是简单的因为安装包大,安装缓慢吗?
这一点,真对企业用户来讲,尤为明显,没有多少员工真心愿意在自己的手机上安装几十个为了企业内工作需要的App的。
第三、业务的隔离性。
业务的隔离性是生态型App是否能够健康运转的基础。这里需要重要考虑的两个因素是,业务的相关资源需要单独规划,避免业务之间的干扰;同时,避免新增的业务代码导致整个生态型App的不稳定。
第四、与生态型App的交互性。
三方的功能需要能够以与整个生态型App进行双向的交互。提供双向的交互,包括App的信息能够传递到相关三方的功能,以及相关的三方功能的业务能够聚合到App内,前者最常见的是鉴权信息(比如微信的授权登陆),后者在微信里是以消息的方式可以提供。
三、生态型App对架构的挑战与实践
生态型App因其自身的特点,导致相对于一般的App对于架构角度的挑战会更多,针对其特点,相应的架构层面也需要提供一定的支持。
通常有以下三种方式做到类似的方式:
1、每一个三方功能都是一个App。
这意味着每个功能需要开发出针对的iOS、Andriod操作系统的应用,父应用以应用跳转的方式打开三方应用。早几年的所谓移动门户(portal)大多采用这类技术,优点是技术简单。缺点是,父应用与三方应用之间就是两个独立的应用,无法真正的共享生态,跳转后,基本上就离开了父应用,在互联网应用中较少出现。
2、每一个三方功能,都是以Web的方式存在。
这种方式很好的解决了跨平台的问题,也很好的避免了跳出父应用的问题。其主要解决思路是每一个三方应用都是一个Web站,父应用中通过嵌入Webkit,以打开URL的方式进入。为了解决Web站点与父应用的交互以及本地能力的限制,基本上都会提供扩展后的Webkit内核以及相关的JS SDK。在微信小程序没有出现之前,微信是通过这个方式提供三方服务的。
这种方式存在一些硬伤,比如,每次打开一个三方功能,几乎都会有几秒的短暂白屏,主要原因是每次都要获取HTML的前端代码并展现。另外也难以做一些离线式的业务、难以确保业务的良好体验。比如说,我正在使用某个三方功能,录入到一半,突然有人微信我一条消息,一般要回到父应用查看一下,之后就得必须重新从头录入。
这也就是意味着,实际上,真正的复杂连续性的业务很难采用这种方案得到良好的用户体验。
3、每一个三方功能,都是一个微应用(或者是小程序)
区别于第二种,这种方案的UI除第一次访问的情况下,是可以完全本地化,所以能很好的解决第二种方案的问题,真正达到原生的体验。
实际上,这也带来了架构上的挑战,三方应用的生命周期必须自行管理,包括三方应用的加载、运行、销毁等一系列动作,甚至更新。微信的小程序就是采用了这个方案,而针对企业应用,还需要关注其针对这个三方应用的权限问题。
这里有两个大需要考虑的因素:
(一)微应用的呈现及微应用的更新
(二)微应用独立加载、销毁等运行期生命周期的管理
上图是微应用的呈现及微应用的更新的示意图,在结合了权限后,会引入了新的挑战,微应用的呈现过程中需要与服务端进行确认。具体流程如上,就不一一展开描述了,需要说的一点是,前端的架构中,必须针对微应用的本地库(App内)具备相关的管理功能,我们的经验是单独规划出微应用的资源空间,并且约定好微应用的规格。
另外一点,微应用的运行期生命周期的管理,需要前端结合自身的技术进行支持和实现,如果采用传统的Web方式是可以交由Webkit进行处理。
这里需要补充说明的是,如果直接使用React Native 期望达到上述的功能及效果,建议先解决多Bundle的问题。
当然在这个方案中可以提供多种应用类型的支持,兼容第二种以Web集成的方案,下面是以集成M站天猫为例。
上述的架构考虑主要还是围绕在父应用与三方功能交互的诉求,基本上能够做到如下图的效果
同时,我们还需要让父应用与三方功能联动起来,让三方功能的数据聚合到父应用里。
如上图中,流程管控、公文系统的信息都聚合在一起,结合之前图中提到的“传递参数及上下文”,点击任何一条信息都会准确的跳转到相关的微应用中进行处理。
这里的数据聚合可以根据业务特点采用推的方式或者拉的方式,上图的例子因其特点,采用拉的方式进行。实际上,在非聊天式的场景里,绝大多数都采用拉的方式。
说到这里,现在的新的App端呈现无论是在主页上、还是在类聊天窗口中,都已经趋向于多楼层、多交互的模式,如下图:
这就意味着,我们需要增加楼层的框架支持、UI模版的支持。
从架构上看,多UI模版的支持与微应用的支持有诸多相似之处,前端也同样需要管理对应的模版库,这里就不增加图说明其原理了。
那让我们来回顾一下,看一张图,前端为了支撑生态型App的一个基础架构都包括哪些?
这里大致包括了五部分,每一部分都各司其职。
1、最下层是一个基础服务层,包括UI渲染引擎、文件服务、数据库访问服务、本地能力等等基础功能,是支撑一个App正常开发的功能,可以理解为即使不是生态型App也需要具备的功能。
2、下数第二层,我们将App内分层了三个区域,其中有两个区域是微应用或者三方无法直接访问的区域,这些区域包括业务代码区和缓存目录区。其中、业务代码区应用存放可以直接运行的程序代码,与此区域交互的主要是相关的管理服务、生命周期服务和各个中心。缓存目录区,是用于支撑整个生态型App的一些资源的,比如我们下载微应用的安装的包、增量的更新包等等。
三方的服务实际上可以操作的数据是业务数据区,这个区域会根据MicroAppID去创建一个独立隔离的区域,三方的服务操作也是只能这个区域。
3、三中心(右中)。包括个性化中心、注册中心、资源中心,这三个中心一般不会直接暴露服务,也不允许三方直接访问,而是通过其左侧的服务提供,比如微服务管理服务等。个性化中心,主要是记录与当前手机或者当前用户的信息,比如说当前用户某个三方微应用显示的位置、Icon等一些信息,当然这个可以根据权限进行控制。注册中心是针对三方服务的注册,其中包括类型(MicroApp、HTML5、UI模版等等)、ID、下载URL、本地运行版本号、本地上个版本号等等信息。而资源中心,可以存放每个三方应用下载后当前和之前的版本等相关资源。
4、在右上部分,是用于针对不同类型的三方应用的生命周期管理的功能,比如点击了一个MicroApp后,他需要Load这个微应用,跳转到指定Page、退出这个微应用后的内存销毁等一系列的工作都在这里进行。
5、左上是一些生态型App提供的一些特有的服务,其与最底层的服务一起构成了三方服务能够使用的全集。
这里需要提到的一点,对于三方功能,我们不允许存在直接的依赖,而重点要考虑的是尽可能的隔离,避免之间互相的干扰,所以可以看到实际上很多功能不直接对三方服务提供。对于一些可能需要进行一些传递的数据或者公用的信息,我们提供了“上下文服务”的功能,三方服务在前端可以通过这种方式共享,当然也可以通过服务器端进行传递。
对于UI模版的很多支持技术维度很多的工作都与MicroApp有很多相似之处,但还是有一些区别,我再啰嗦两句。
1、数据驱动的UI呈现
通常一般的情况下,真实的业务需要传递“二号会议室预定成功,会议时间…..”。
实际上,这条信息的传递到前端,并以上图的方式呈现,大概还会包括一下的信息:
用于显示着一条信息的UI模版ID,上图是用了带按钮的列表。
而这个模版需要的数据包括:
Title Icon、Title DisplayName、Title Info
显示数据(含期望的样式)
Button Label[]、Button Event[]
所以,这部分的聚合的数据是采用了统一中台的方式,在中台构造带显示信息的数据。
2、UI模版的动态获取
UI模版本质是一种代码片段,体积上远比三方应用的体积小,三方应用(比如MicroApp)默认采用的是使用前下载的方式,在使用过程中也会以显性方式下载为主,打开MicroApp,在进行传递数据。
UI模版的使用是采用的方式是在数据传递后,如本地无对应的模版,再向服务器获取UI模版。简单说,带显示信息的数据传递过来后,根据UI模版的ID向注册中心查询,如果注册中心确认本地存在对应的UI模版,直接显示;如果不存在UI模版管理模块向服务端发起请求获取UI模版并注册到注册中心,然后进行显示。
这种加载机制是因为UI模版是一个羽量化,方便进行快速获取。
UI模版是一个变化性和数据都有限的,本地命中概率较高。
生态型App是对于绝大多数移动开发者是一个新的事物,可能有很多地方通过文章不一定能讲清楚,欢迎加作者微信探讨相关技术。
关于作者:
郝振明
普元移动产品线总负责人,十多年 IT 从业经验,一直专注于企业信息化的工作,近五年间一直从事企业移动信息化、移动互联网化的咨询、产品工作,曾主持参与了 Primeton Mobile 产品研发、联通集团、广东农信、诺亚财富、中信重工、索菲亚等公司的移动信息化工作。近两年来,致力于基于 React Native 工程化能力的提升、降低实施难度,以及智能化移动平台的产品研发,在移动开发智能化的路上不断进行探索。
关于EAWorld
微服务,DevOps,元数据,企业架构原创技术分享,EAii(Enterprise Architecture Innovation Institute)企业架构创新研究院旗下官方微信公众号。
微信号:eaworld,长按二维码关注
阅读原文:http://platformplus.blog.sohu.com/324925132.html