彭飞App工厂产生背景业务的快速试错催生多App
发表时间:2023-10-17 20:05:27
文章来源:炫佑科技
浏览次数:129
菏泽炫佑科技
彭飞App工厂产生背景业务的快速试错催生多App
App 的目标是根据特定架构和业务场景下的一组代码,按需生成目标App所需的代码。 一套代码和按需生成是核心,缺一不可。 特别是,按需生成意味着不携带任何不必要的代码,这在实现过程中非常具有挑战性。 本文分享58App从iOS角度对App 的理论和实践探索。
作者 | 彭飞
应用工厂生成后台
快速的业务试错催生了多种应用
无论是移动互联网的上半场还是下半场,商业创新从未停止过。 从微博到团购,从共享汽车到共享单车,从长视频到短视频,业务和模式创新不断。 近年来,头条业务的试错在各报纸上屡见不鲜,从新闻到直播再到短视频,层出不穷。
目前,无论是大型互联网公司还是小型创业公司,如果想要探索新的领域,就必须不断试错。 移动领域的业务不断试错,需要快速生产出与每个业务相对应的创新应用。
集团业务逐步扩张和细化,催生了多个APP
互联网世界早已被分成三部分,巨头纷纷成立,很难形成大型互联网平台。 但互联网平台越大,就越担心垂直细分业务的攻击。 为了应对攻击,集团的业务也需要在一些领域逐步做大和细化,垂直应用也随之出现。
垂直应用和创新应用的区别在于,垂直应用是根据现有平台业务进行细分的,而创新应用则不存在于平台业务中。
另外,为了应对应用市场的分布以及对包大小敏感的用户,近年来几乎成为各大公司的必备应用。
集团业务合并整合催生多App跨界
企业收购合并对于大型互联网公司来说也很常见。 如何整合收购后和合并后的业务,如何保持业务的独立性,节省集团的研发资源,并支持一套跨业务(也叫垂直业务)的代码在独立的App中运行,是一个重要且重要的问题。复杂的问题。 问题。 比如,今年安居客将58集团内部的房地产业务与原58地产业务整合就是一个典型案例。
App 的目标、架构和实现方法
App 的实现目标
1.App 有以下目标:
标准化能力是实现App 的基础。 标准化能力与App业务代码没有耦合关系,如React SDK、网络库、缓存库等。
同一套代码,根据配置,可以按需生成不同App所需的代码。 按需生成是关键和核心。 App 生成的App代码不携带任何无用代码并增加包大小。
App 附在58App框架代码中。 马甲包、极速包和应用工厂(58App)是一个子集,也是一个完整的集合。 但安居客App和58App是两个相互重叠的独立App(共同底层代码或某些业务代码),业务代码集不同。
独立应用程序的公共业务代码被定义为垂直业务。 在统一底层服务的前提下,App 还必须支持垂直业务向独立App的转化。 即一组可以运行在两个或多个独立App上的业务代码。
应用工厂架构
词汇表
PODS
在iOS领域,专门将pod称为其缩写。 它是 OC 或 swift Cocoa 项目的依赖管理。 (适用于 Swift 和 -C Cocoa 。)
中间件
软件领域对中间件的一般解释是:连接软件组件和应用程序的程序。 这里的中间件体现的是连接和共享。 连接的是业务层和基础库层,共享业务层体现的公共服务。
中间件按照与业务是否强相关分为业务中间件和标准中间件。
基础库
一个不依赖于其他 Pod 的独立库。 比如一些开源的第三方库就是常见的基础库。 除了第三方开源之外,58集团内部自封装的SDK如果不依赖其他pod,也可以纳入基础库的范围,比如SDK、WPush SDK等;
入学项目
主要负责配置App 生成的App所需的代码。
入口项目pod:主要负责配置App工厂生成的App所需的代码。 入门项目包含的功能有:
工程库
项目池是App 的总Pod代码集合。
工程池是App 的总代码集合。 生成App所需的每条代码都是从这个代码集合中获取的。 开发过程中的代码更新也会同步更新到这个代码集合中。
业务中间件:
与58App业务强相关,但属于58App业务中常见的中间服务,其应用场景在58App业务场景之内。
标准中间件:
与58App业务关联性较弱,可以作为标准化中间件引入到其他独立App上。
在标准中间件中,可以看到图标上添加了两条竖线,这意味着这个标准中间件的部分功能的实现依赖于接入App的实现,只开放了接口协议。
以RN基础库标准中间件为例:
中间件包含的内容为运营商页面和热更新的所有公开的、业务弱相关的内容。 但有些扩展组件(如埋点)需要开放协议供接入方实现,而这个逻辑在中间件中并未实现。
架构分析
上图是App工厂架构图。 大方面分为两层:入口工程和工厂池。 入口项目Pod通过配置每个入口项目所在App所需的Pod代码来依赖项目池中的Pod。
工程池中的pod分为业务层、中间件层和基础库层。 中间件层根据代码是否强依赖58App业务分为业务中间件和标准中间件。
从架构设计上来说,每一层Pod的依赖标准是:
制定上述依赖准则是为了在生产应用程序或进行垂直业务翻译时可以按需配置所需的 Pod。
如何借助App 架构实现设计目标
1、如何提供标准化能力
所谓标准化能力可以理解为独立自主或者SDK,对应上面架构图中的标准中间件。 例如,RN基础库封装了运营商页面、热更新等一整套公共服务,可以被58App以外的独立App无缝访问。
下图展示了一些标准的中间件:
标准中间件名称
Pod 名称
功能说明
RN基础库
封装了RN的基本功能,包括承载页面、热更新、性能优化以及一些标准化
基础库
封装了交互功能、分发功能以及一些标准化的功能
跳跃组件
谢尔
基于主App跳转协议封装了对跳转分发逻辑的支持
网络图书馆
封装了网络接入的基本操作,让网络操作更加方便快捷
位置
封装了定位触发和定位原始数据获取的基本策略
缓存库
封装了缓存的底层实现和一些基本操作
...
另外,还有一些集团内其他中台部门提供的标准化SDK,如IMSDK等。
2. 如何支持创新应用和极快应用的生成
如上图所示,在理想的工程架构状态下(即满足架构各层的依赖标准),可以根据需要配置App所需的功能,生成马甲包或者速度包。
当然,为了应对苹果的审核(应用程序必须保持差异),必须对马甲包或速度包进行一些个性化处理。 这种个性化的处理在之前的项目中已经完成了。 详情请参见项目。
3.如何支持垂直业务的翻译
垂直业务:同一业务在多个App上呈现,称为垂直业务。
垂直业务翻译:并不意味着垂直业务及其依赖的底层代码是一组可以运行在不同应用程序上的通用代码。
上图所示的是,租房和二手房这两个垂直业务需要有一套代码,可以同时运行在58App和安居客App上。 这需要:
垂直业务代码及其所依赖的底层代码必须满足App 架构中的分层原则和依赖原则,这样架构的扩展性才会更加灵活。
如何在现有代码上实现App
基于之前App 的技术架构和各层Pod的依赖标准,理想的各层Pod的依赖关系示意图如下图所示(以招聘业务Pod依赖为例):
有了以上理想的依赖关系,当入口项目生成App所需的代码并配置时,就可以根据需要进行配置了。 不会因为 Pod 之间的反向依赖、循环依赖、全层依赖而携带大量无用代码。 增加封装尺寸。
1.业务层Pod解耦
招聘业务的依赖关系如上图所示。 黑色箭头代表 Pod 的单向依赖,红色双向箭头代表 Pod 的双向依赖。
注:服务层对应中间件层,第三方库层对应基础库层。
业务Pod解耦主要处理下层Pod对业务Pod的依赖以及业务Pod之间的依赖,如下图所示:
2.中间件层Pod解耦
如上图中实线所示彭飞App工厂产生背景业务的快速试错催生多App,招募Pod所依赖的就是中间件层Pod之间的耦合关系。
服务层Pod解耦需要解决以下两个耦合关系:
服务层Pod的解耦至关重要,直接涉及到工具库Pod的依赖处理。 如果服务层pod的循环依赖不释放,会导致整个层依赖于工具库pod,并且依赖的pod无法按需配置,导致包大小不可控。
3.基础库层pod解耦
由于基础库层Pod是*底层的Pod,没有其他依赖的Pod,因此它也是这三层Pod中解耦工作量*小的。
目前58App中所有基础库层Pod都放在一个Pod中。 这一层解耦需要的就是将pod按照功能进行拆分,拆分成上层pod可以依赖的单元。
如何保证APP工厂质量
App 的质量在版本迭代过程中非常重要。 如果代码在后续版本迭代过程中没有严格遵循App 的Pod依赖准则,等到发现问题再解决会带来很多额外的工作。
1.Pod依赖检测
这是所有质量检验的基础。 本文看到的一些Pod依赖关系来源于我们开发的Pod依赖关系自动分析工具。 如果没有这个工具,在一些中大型应用中,手动理清这种依赖关系将是一个巨大的工作量。 以下是这些想法的简要概述。 如果有更好的方法,欢迎交流:
如上图所示,是根据招募 Pod 及其依赖的 Pod 构建的有向图示意图(为了方便识别,将两个直接依赖的 Pod 之间的线画成虚线线)。 基于这个数据结构,就可以实现上述App工厂依赖标准的检测。
2、检测下层pod对上层pod的反向依赖
下层pod对上层pod的反向依赖是App工厂依赖指南的首要禁止内容。 比如中间件层的这个Pod如果依赖于上层的主页Pod,就会因为依赖而导致业务迁移过程中携带不必要的主页业务代码。
基于上面的有向图,反向检测在技术上很容易实现:
3.Pod循环依赖检测
在App 中,除了业务层代码不能有依赖和循环的原因非常明确之外,即使其他层的pod之间存在循环,也有办法达到App 中不携带冗余代码的目的。 但抛开App工厂不谈,环的存在本质上是大多数情况下两个Pod之间存在不下沉的公共代码。 因此,为了让App 的依赖准则更简单、更容易实现,统一规定不能生成循环依赖。
检测有向图中是否存在环是一个基本的数据结构问题,这里不再详细讨论。
4. 标准中间件污染检测
标准中间件是App 的核心。 如果标准中间件在后续业务迭代过程中被污染,即引入不符合准则的依赖,将会带来额外的维护和解耦成本。 因此,如果能够在单个分支的开发过程中以及在集成分支上进行检测,那么污染的可能性就会*小化。
在App 中,标准中间件只允许依赖于基础库层的pod。 所以检测策略也很简单:
App 实践经验
应用工厂在58App上有广泛的应用。 已应用于房地产垂直商务翻译、招聘垂直App生成,并已上线。
房地产垂直商务翻译实践(木星项目)
去年以来,58同城的房产业务和安居客的房产业务进行了调整,租赁和二手房业务重新拆分并整合在两个独立的App上。 业务调整后,原来的58同城租赁和安居客二手房业务成为垂直业务,即同时运行在58同城App和安居客App两个独立的App上。 业务调整给技术架构带来了巨大的挑战:
你可以想象一下,如果基于App 不实现上述目标会发生什么?
于是,58无线技术部与房地产技术部(安居客房地产技术部、58房地产技术部)一拍即合,将App 应用到房地产垂直业务翻译中。
1. 项目里程碑
这里我们重点以项目里程碑来说明多App垂直业务翻译过程中接入App 的思路。
序列号
里程碑
取决于前一个节点
58APP无线技术封装并提供公共图书馆垂直服务所需
58APP接入上述垂直商业公共图书馆
安居客APP接入上述垂直商业公共图书馆
租赁业务适配双APP,支持双APP内业务翻译。
1, 2, 3
二手房业务线适配双APP,支持业务双APP翻译。
1, 2, 3
从上表和依赖关系可以看出,该项目主要分为三个阶段:
**阶段,提取公共图书馆大约需要1个半月; 第二阶段,每个独立App接入公共库需要1-2个版本(平均每3周1个版本),主要根据测试资源情况而定; 第三阶段,使用2-3个版本进行垂直商务翻译。
二、项目实施概况
2.1 公共库的提取
这里的公共库是指垂直业务依赖的中间件层代码库和基础库层代码库。 这一步非常重要。 如果处理不到位,后续业务在接入过程中将不断返工。
针对具体垂直业务的中间件代码与基础库代码的耦合分析上面已经详细介绍了,这里不再赘述。 这里我们将讨论实践中一个非常重要的问题:如何统一两个独立应用程序的公共库?
这个问题非常复杂。 以网络中间件为例。 每个独立的App都有自己的封装,封装的API差异很大。 通过调整API协议很难消除差异。 在这种情况下,*简单、*高效的方法就是以一个App为基准,另一个App提供兼容性要求并放弃其原有代码,然后将它们分开并一起维护。
考虑到App的规模以及对业务的影响,当时的讨论是以58App为基准,安居客会根据二手房业务代码的调用要求提供兼容性要求。 58App撤回后,安居客重新连接。
*终剥离出来的公共库(标准中间件)如下表所示:
中间件
功能说明
网络图书馆
封装了网络访问的基本操作
数据库
封装了城市App中涉及到的城市列表、地铁列表、商圈数据、历史浏览记录、足迹信息等存储和读取的接口。
基础库
封装了交互功能、分发功能以及一些标准化的功能
反应基础库
封装了RN的基本功能,包括承载页面、热更新、性能优化以及一些标准化
定位库
封装了定位触发和定位原始数据获取的基本策略
缓存库
封装了缓存的底层实现和一些基本操作
路由跳转库
基于主App跳转协议封装了对跳转分发逻辑的支持
协议库
()部分是为了支持底层跨平台业务调用的具体实现而提供的。 具体实现由不同平台实现。
公共参数库
封装了一些公共参数的生成和获取API。 直接访问可以自动获取58同城App中的请求头、等公共参数。
剥离公共图书馆有两个要点需要注意:
2.2 每个独立的App都连接到公共图书馆
下表列出了四个具有代表性的中间件在实施过程中对独立App的访问方案。
中间件
安居客二手房
58App租房子
网络图书馆
√安居客二手房代码迁移至58App,使用58网络库支持,并对安居客业务代码进行适当修改。
√58App租赁代码迁移至安居客,安居客打造适配API层。 58App房地产业务代码无需更改。
数据库
√安居客二手房代码迁移到58App因为不涉及业务,所以不需要考虑数据库问题。
√ 58App租赁代码迁移至安居客,仅承载58上的数据库和数据表,业务代码无需更改。
√安居客二手房代码迁移至58App,业务代码兼容变更。
√ 58App租赁代码已迁移至安居客,搭载58端精简版SDK。 扩展能力在安居客独立实现,业务代码无需改动。
跳跃中心
√安居客二手房代码迁移至58App,修改业务代码以适应58跳转协议;
√58App租赁代码迁移至安居客,无需修改业务代码。
……
……
……
由于是基于从58App中提取的中间件,因此在58App租赁代码的翻译过程中,业务代码基本不需要更改。 但安居客的业务代码需要做相应的改变,这个成本是省不了的。 从目前上线的安居客二手房功能代码的稳定性来看,这部分的改动非常成功。
2.3 垂直业务翻译
上述垂直业务所依赖的公共图书馆被独立App访问后,并不意味着垂直业务可以迁移。 App 的核心目标是不携带无关代码。 除了依赖公共库之外,垂直业务还依赖自己应用程序中的其他模块代码。 只有*大限度地去除对这些非公共库代码的依赖,即将其拆分为业务中间件,才能真正实现App 的目标。
这里我们不再详细描述如何解耦业务中间件。 我们主要介绍一下操作过程中的几个指引。 只要掌握了这些准则,基本上就不会出现大问题:
三、项目成果
该项目由三方共同完成。 以下只是无线 iOS 方面的一些成就:
成就
结果描述
1套App工厂架构
分层架构和各层的依赖标准作为 Pod 解耦的基本标准。
2 种类型的应用程序生成支持
支持创新应用和独立应用的垂直业务代码生成
3 个自动化质量保证工具
标准中间件污染检测、中间件包大小检测、中价静态库自动编译与同步
4类核心问题的兼容性解决方案
统一跳转,垂直业务翻译,兼容统一化、个性化服务
14个标准中间件
比如中间件、RN中间件、网络中间件、跳转中间件等。
430 个类,3309 个方法
14个标准中间价涉及430个类、3309个方法
以上结果仅涵盖App 标准化结果。 这些标准化成果不仅支持房地产垂直业务翻译,还适用于支持其他业务,例如58同城招聘App(已完成)和58同城租赁App(即将推出)的生成。 和部落垂直商业翻译(正在进行)。 业务中间件的解耦与具体业务相关,这里不详细讨论。
App 在 中接入后对包大小和稳定性的好处如下表所示:
指数
58App访问应用工厂
安居客App连接App
数据显示
包装尺寸
将58出租移至安居客App,节省约73MB
租赁依赖的中间件(41.2MB)+租赁依赖的第三方库(43.8MB)-安居客接入标准中间件(11.4MB)=73.6MB
将安居客二手房移至58App,节省28MB
二手房依赖的中间件(13.08MB)+二手房依赖的第三方库(14.88MB)=28MB
保存的包大小是根据访问App 前后需要携带的代码来计算的。
崩溃率
集成前的8.22版本崩溃率为1.1‰,集成后的8.23版本崩溃率为1‰。
集成前的12.14版本崩溃率为千分之一,集成后的12.16版本崩溃率为千分之1.3。
安居客接入应用工厂12.16版本崩溃率增加3万与应用工厂无关,主要来自于其他业务的崩溃。
从上表可以看出,包大小对于58App和安居客App来说都有着巨大的好处。 接入前后崩溃率没有明显变化,代码上线性能稳定,性能良好。 尤其是崩溃率和功能稳定性方面,如此大范围的改动,想要避免线上事故确实不容易。
58同城招聘APP(创新APP)生成实践
创新App和极速App是同一类型的App,大部分基础功能都可以使用App 的基础能力。 由于苹果对马甲包审核规则的限制,如果功能相似度超过一定程度,就会存在较大的审核风险。 因此,无论是创新版App还是快速版App,由于Apple的审核限制,肯定无法生成100%所需的代码,部分代码还需要额外开发。 至于额外代码开发的比例,目前还没有明确的答案。 能够向苹果解释商业模式的差异并通过苹果的审查是关键。
与项目中App工厂的接入不同,下面将从不同的角度来描述创新App代码的生成,重点关注Pod依赖的排序和解耦。
1、耦合梳理Pod依赖关系
耦合 pod 依赖排序的目标是:招募 pod 直接或间接依赖于哪些 pod? 其中哪些依赖项不符合应用程序工厂依赖项准则? 如何切断某些依赖关系以满足应用程序工厂依赖关系准则?
上面的依赖图中有两条灰色虚线。 整个图分为三部分,从上到下分别对应App 架构中的业务层、中间件层和基础库层。 交叉箭头表示那些不符合App工厂依赖指南的:
可以看出app开发,如果去掉上述不符合App工厂依赖准则的依赖,招聘Pod就不会再对个人中心Pod和首页Pod产生依赖,App代码加载时也不会携带不必要的代码。生成(个人中心和主页pod的代码以及它们依赖的一堆代码)。
2、消除Pod之间耦合的措施
Pod 之间的解耦*终涉及到 Pod 之间的调用关系的解耦。 例如,如果招聘Pod依赖于用户中心Pod,则必然是招聘Pod中的某个代码文件依赖于用户中心Pod的代码文件。 解耦的实现是在代码文件中找到代码的耦合,并酌情解耦。
我们常用的代码耦合解耦方法包括:
Pod解耦,尤其是业务层代码和中间件层代码的解耦,一开始很难有一个标准来衡量Pod的耦合做得对还是错。 因为很多业务一开始并没有从产品层面考虑到这个业务是一个垂直业务,会跨多个App进行转化。 但一旦某个业务确定支持多个App,那么该业务所涉及的Pod的依赖关系就必须满足App 的依赖准则。 这一点在后续的业务迭代中要特别注意。
风险控制
App 整个代码重构涉及面很广。 58App今年对应用工厂进行了史无前例的代码更改。 每个公司的业务和架构不同,代码的复杂程度和重构的难度也不同,所以面临的线上风险也会不同。 在重构过程中,除了严格的技术方案审查、代码审查、全面的案例测试外,还必须特别注意两点容易被忽视却容易引发问题的点:
在58App中,随着App工厂的不断深入和业务的逐步接入,中间件层和基础服务层被拆分得越来越细。 The total of pod data 50. While the App is being out, daily are being in . this , the same code may be in the App , and there may also be and to new .
The span of the App is long. For , a price is based on the fork of 8.0, but it may take to go . this , new of code must be into the App . And some codes must be . of layer code and basic layer code has been a pain point, and it is to cover all . , and codes must be to .
Data means that codes on and rely on data. , data be found at time and most , which makes it very to find . For , the data, data, user phone call , post , etc. on the App all fall into the of data .
Like the issue of in above, the of data risk is to a and of all that data, and to deal with key nodes such as , , and data .
总结
Any is from and is to solve pain and , and App is no . Since each has a App , forms, and forms of R&D , there is no one-size-fits-all App and .
the , 58App also the of the App . The part of and non- . , and non- may into each other with . In the , 58App will to to more to to solve and and .
App is the of , thank you to the who . From to to , App is a rare big move made by 58 in years. the , , and of the at all of the User Value and the of the in the group, there are no and from the Real ( Real , 58 Ganji Real ), and other . Such a large be and and .