抖音架构演进_第1页
抖音架构演进_第2页
抖音架构演进_第3页
抖音架构演进_第4页
抖音架构演进_第5页
已阅读5页,还剩17页未读 继续免费阅读

付费下载

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

抖音架构演进前言介绍2016.09.26,抖音版本1.0.0上线,随后不断迭代优化和丰富产品,截止目前,抖音日活跃用户突破6亿,短短4年间,抖音从零爆发性增长。快速的业务发展也对技术支撑提出了更高的要求,为了保障敏捷的业务开发,提升跨团队的协同合作效率,提高本地研发和

CI/CD效率,抖音iOS

App工程架构在不同的阶段进行了不同的技术方案的改进,满足合理的架构演化,同时又不影响正常的业务迭代速度。抖音工程架构演进合理的架构设计可以解决大型项目跨团队协作分工和多业务线并行开发的效率问题。抖音工程代码从一开始就采用了组件化思路,依赖管理工具是定制版的Cocoapods。组件化在大型项目快速发展的过程中,要保证敏捷开发迭代的最大障碍就是快速膨胀的代码体积导致的编译效率问题,依赖关系复杂化问题,以及业务线代码冲突问题。移动端项目可以类比后端项目中采用的微服务架构,要解决多业务线并行开发、并行测试问题,采用流水

线式迭代开发,提高发版、集成、交付、提审、发布效率,结合分治思想技术选型上可以采用组件化的方案。大部分小型项目,组件化仅仅做到代码分仓,使用Cocoapods的来管理组件依赖,就像抖音项目最初的工程形态。但是对于几百号人、几十个业务线规模的大型项目,需要设计一套合理的组件分层架构,理清组件间依赖关系,需要CI/CD工具链支撑组件发版与集成,需要本地研发工具支撑本地代码同步、工程配置、依赖管理和效率优化。抖音工程架构演进流水线式迭代开发流水线(pipeline)技术是指在程序执行时多条指令重叠进行操作的一种准并行实现技术,该技术可以充分提高资源的利用率,同时缩短产品的研发周期。对于客户端项目,流水线技术能很大程度满足敏捷开发迭代的节奏。01抖音原始工程架构(Original

architecture

of

project)03单仓多组件工程架构(Multicomponents

in

single

repo)0204分离壳工程后的工程架构(After

splitting

of

host

shell

pod)Example子壳工程架构(Subshell

for

bizcomponent

inexample

project)抖音工程架构演进抖音工程架构演进阶段一:抖音原始工程架构(Original

architecture

of

project)抖音项目一开始是单体架构+Cocoapods,业务代码、工程配置、资源文件全部放在一个大业务仓库。由

Podfile文件描述第三方仓库的依赖版本。抖音项目原始工程架构图抖音工程架构演进阶段一:抖音原始工程架构(Original

architecture

of

project)抖音项目一开始是单体架构+Cocoapods,业务代码、工程配置、资源文件全部放在一个大业务仓库。由

Podfile文件描述第三方仓库的依赖版本。抖音项目原始工程架目录结构抖音工程架构演进阶段二:分离壳工程后的工程架构(After

splitting

of

host

shell

pod)分离壳工程后,工程配置、部分系统资源、工程主入口被拆分到主宿主壳工程。部分基础能力代码被拆分成基础仓库,跟第三方仓库一样独立发版。本地研发工具支持单仓开发和多仓开发,不参与代码修改的仓库通过二进制的方式进行链接。同时

CI流程上也支持通过二进制打测试包,提高打包效率。Podfile拆分出版本依赖管理文件Podfile.seer,由依赖管理平台进行各个版本的容器化管理,业务仓跟随宿主集

成发版,打平依赖,解决版本依赖决议

耗时问题。拆分壳工程后的工程架构抖音工程架构演进阶段二:分离壳工程后的工程架构(After

splitting

of

host

shell

pod)Podfile拆分出版本依赖管理文件Podfile.seer,由依赖管理平台进行各个版本的容器化管理,业务仓跟随宿主集

成发版,打平依赖,解决版本依赖决议

耗时问题。大业务仓中的代码和资源被拆分到各个业务线的仓库下,由

podspec文件描述内外依赖。业务线仓库增加

ModuleInterface

subspec,存放对外接口,采用依赖注入方式实现接口隔离,初步建立接口层。业务仓库之间规定只能依赖其他业务仓库的

ModuleInterface

subspec,通过lint进行编译检查。抖音项目拆分壳工程后目录结构抖音工程架构演进阶段二:分离壳工程后的工程架构(After

splitting

of

host

shell

pod)壳工程为了满足一个工程同时支持多个项目、部分业务线功能复用、部分业务线中台化发展的需求,我们把所有业务线抽象成独立的Pod,所有业务Pod必须通过宿主的壳工程进行集成发版。壳工程包含了项目依赖的Pod信息描述,

同时还包括工程的配置、部分系统级别的资源文件、工程主入口代码。基于多份宿主壳工程,一份代码可以打包出抖音、抖音极速版等项目。同时,基于宿主壳工程,一些业务线可以通过自动化同步生成自己的子壳工程,实现业务线自己的Example工程,进行独立开发,比如有语音通话的Example工程,有工具的

Example工程,有直播的Example工程等等。壳工程抽象子壳工程配置同步同步抖音工程架构演进阶段二:分离壳工程后的工程架构(After

splitting

of

host

shell

pod)接口层接口层顾名思义,只提供依赖的抽象接口,所有接口都是

protocol协议声明。接口层限制了所有其他依赖,类、枚举、外部协议都采用前向声明,podspec上只允许声明对

DI(依赖注入)框架的依赖。接口层满足封装、隔离和组合的原则。业务层面对外封装了实现代码;

编译层面隔离了组件间依赖传递,减少头文件

import嵌套提高编译缓存的命中率,对于

swift业务组件,还能达到减少编译传递的问题;架构层面声明抽象协议支持接口组合;DI容器框架同时支持

stateless

DI容器,也支持

stateful

DI容器。抖音工程架构演进阶段二:分离壳工程后的工程架构(After

splitting

of

host

shell

pod)依赖打平

采用Cocoapods本身自带的版本依赖决议进行版本分析会消耗大量的时间;Podfile.lock过于繁琐,可读性很差,难以解决Podfile.lock的冲突;

隐式依赖被动/不符合预期地升级,难以确定性地声明所有依赖,防止隐式依赖被升级;

依赖版本在Podfile/Podfile.lock重复声明,增加了解决冲突的成本;

Podfile.lock参与依赖版本决议流程比较复杂,会出现不符合预期的情况。

hook掉Cocoapods采用podfile.lock进行版本决议的逻辑,采用Podfile.seer文件直接描述所有组件的版本信息,打平依赖。把版本管理和仓库源信息迁移到Podfile.seer文件抖音工程架构演进阶段三:单仓多组件工程架构(Multicomponents

in

single

repo)采用单仓多组件后,每个业务线仓库支持添加

podspec增加组件,实现更小粒度的二进制依赖。业务线仓库内划分业务实现层、业务接口层、服务层和基础层,都是通过集成方式发版。新增的服务层主要存放公共的业务逻辑和通用服务,限制

UI。一、满足业务逻辑复用;二、满足子壳工程最小化二进制依赖。拆分单仓多组件后的工程架构抖音工程架构演进阶段三:单仓多组件工程架构(Multicomponents

in

single

repo)同时服务层的服务接口也达到隔离依赖传递的目的,在不同的宿主上,支持通过改变服务层实现替换后台能力或者底层能力。建立分层间的依赖准入规则,完善

lint编译链接检查。编译链接完备性校验编译校验:分开编译各个

subspec,确保每个subspec的依赖是正确的(由于

subspec没有编译隔离)接口符号校验:校验当前接口组件(ModuleInterface)中符号是否完备的,以保证其他组件单独引用是否能正常使用。如

extern声明的全局变量。单仓多组件目录结构抖音工程架构演进阶段三:单仓多组件工程架构(Multicomponents

in

single

repo)分层依赖准入规则:高层依赖低层实现依赖接口接口层无依赖前向声明优先服务层去"UI"业务实现层和服务实现允许依赖的分层抖音工程架构演进阶段四:Example子壳工程架构(Subshell

for

bizcomponent

in

example

project)每个业务仓从宿主同步工程配置构建子壳工程。增加

AWELaunchKit为子

壳工程提供运行时的基础能力。通过服务层提供业务间运行时共享的服务能力,满足代码复用和更小二进制依赖。子壳工程架构抖音工程架构演进,阶段四:Example子壳工程架构(Subshell

for

bizcomponent

in

example

project)每个业务仓从宿主同步工程配置构建子壳工程。增加

AWELaunchKit为子

壳工程提供运行时的基础能力。通过服务层提供业务间运行时共享的服务能力满足代码复用和更小二进制依赖。子壳工程目录结构抖音工程架构演进。阶段四:Example子壳工程架构(Subshell

for

bizcomponent

in

example

project)AWELaunchKitAWELaunchKit框架为宿主和其他子壳工程提供了基础服务的依赖和初始化配置同时提供了一套启动加载的

BootTasks

管理框架,部分业务涉及启动相关的逻辑可以在业务仓对应的服务层中实现,并通过

BootTasks管理框架注册到启动加载器里面。同时框架还提供了一套宿主

UI入口和自定义入口框架。为了方便测试和调试,也整合了整套测试调试框架。子壳工程依赖关系抖音工程架构演进组件化探索过程中遇到的一些问题:二进制污染组件之间的依赖除了显式的依赖,还存在很多隐式依赖,代码层面,除了普通的接口依赖,还有宏依赖、枚举依

赖、全局变量依赖以及内联函数等的依赖。单仓

lint进行编译链接完备性检查并不能解决依赖变动对其他二进制的影响。因此需要借助源码层面的依赖分析,判断当前组件的变更对其他依赖当前组件的二进制是否有影响,在

CI流程中及时发现并拦截。否则错误的二进制发版,会直接导致整个

CI研发流程和本地研发都受到影响。编译优化编译优化最高效的方式就是提高缓存的利用率。对于本地研发和CI流程,都涉及分布式编译缓存同步。同时通过编译参数优化、依赖优化、hmap优化也能不同程度的提高编译效率主干分支稳定性问题对于多业务线并行开发,几百号人的业务开发团队,如果主干分支一旦出现问题,那么解决问题的时间就需要乘上几百倍。因此,需要从编译层面和运行层面都要有足够的机制去保证一个稳定的主干分支,才能保证业务侧的长期稳定性。抖音工程架构演进组件化探索过程中遇到的一些问题:业务层的依赖耦合问题大型项目动则千万行的代码,代码间的依赖关系是复杂的网状关系。需要基于代码的语法树模型,从语义中去分析不合理的依赖,并输出治理的方案。因此内部自研了源码依赖关系分析平台用于依赖关系分析监控和代码治理,长期监控组件间的依赖度。同时,需要建立依赖健康度模型,从长期演进的角度去监控防止代码的劣化。spider组件依赖分析平台总结大型项目的组件化工作是一个系统性工程。涉及工程架构的改造、CI/CD研发工具链的支撑、本地研发工具链的支撑,业务架构的设计优化,需要从各个方面综合考虑成本和收益。没有最好的架构,只有更好的架构,在架构演进的过程中,需要充

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论