手淘启动框架:
启动框架目标:
1、保证这些 SDK 在正确的阶段、按照正确的依赖顺序、高效地初始化
2、合理调度任务,不让系统负载过高
3、最大化利用设备的性能,承接更多的业务
一、任务调度系统
实现难点:一是如何保证时序 、二是怎么控制拥塞。
借鉴Spark 的 DAGScheduler,面向阶段调度(Stage-Oriented Scheduler):把应用划分成一个个的阶段(Stage),再把任务(Task)安排到各个阶段中去,任务的编排则是通过构建有向无环图(DAG),把任务依赖通过图的方式进行梳理。
阶段划分
任务编排:正确梳理各项 SDK 之间的依赖
任务调度:多任务并发,调整各阶段的线程优先级
好处:
控制拥塞,又能保证时序,还能并发执行,让设备性能尽可能得到发挥
IO 性能,降低 IO 的并发
1、阶段划分
手淘:
2、任务编排
这里参考阿里的开源库Alpha做分析。
在GitHub中它介绍说:“Alpha是一个基于PERT图构建的Android异步启动框架,它简单,高效,功能完善。 在应用启动的时候,我们通常会有很多工作需要做,为了提高启动速度,我们会尽可能让这些工作并发进行。但这些工作之间可能存在前后依赖的关系,所以我们又需要想办法保证他们执行顺序的正确性。Alpha就是为此而设计的,使用者只需定义好自己的task,并描述它依赖的task,将它添加到Project中。框架会自动并发有序地执行这些task,并将执行的结果抛出来。”
PERT图:PERT图是一个有向图,图中的有向弧表示任务,它可以标上完成该任务所需的时间;图中的结点表示流入结点的任务的结束,并开始流出结点的任务,这里把结点称为事件。只有当流入该结点的所有任务都结束时,结点所表示的事件才出现,流出结点的任务才可以开始。PERT图不仅给出了每个任务的开始时间、结束时间和完成该任务所需的时间,还给出了任务之间的关系,即哪些任务完成后才能开始另外一些任务,以及如期完成整个工程的关键路径。
Alpha:
Task类:是一个异步任务。一个个关联起来的Task。
Project类:多个前后依赖的Task组成,可以通过Project.Builder将Task组成完整的Project,这个Project可以直接执行,也可以嵌套在另一个Project中当作一个Task。
AnchorTask类: 从图的执行角度来讲,应该要有唯一的开始位置和唯一的结束位置。这样就可以准确衡量一个图的开始和结束。并且可以通过开始点和结束点,方便地将这个图嵌入到另外一个图中去。但是从用户的角度来理解,他可能会有多个Task可以同时开始,也可以有多个Task作为结束点。为了解决这个矛盾,框架提供一个默认的开始节点和默认的结束节点。并且将这两个点称为这个Project的锚点。用户添加的Task都是添加在开始锚点后,用户的添加的Task后也都会有一个默认的结束锚点。
如前面提到,锚点的作用有两个:
标记一个Project的开始和结束。
当Project需要作为一个Task嵌入到另外一个Project里面时,锚点可以用来和其他Task进行连接。
假设我们有任务A、B、C、D、E、F、G、H,且依赖关系如下:
代码实现:
代码块
Java
private v