2019.3.12:修改第三部分
1. 引言
现实工作中经常可以听到一些言论:框架的升级带来协议性能的提升、编程模式的变革带来业务的飞跃...... 姑且不论这些表述是否有问题,实际上如果系统地看待事物,可能会有不太一样的发现。以LINUX为例,尽管其内核大获成功,但如果不是遵循POSIX、并成为一个开源、精简的UNIX实现,很难想象其最终会有何种发展。因此,对事物进行全局探究有时会有更多启发。本文将从这十年我们熟知的Android系统开始,立足于笔者视角,阐述其意义,并结合自身团队进行思考。
2. Android设计的现实意义
架构的工程意义在于:定义并解决一类问题、为需求到实现的平稳过渡提供保障。传统意义的Android架构(图1)已被人熟知。但不同角色的视角各有不同,例如认为Runtime和框架是其核心、或者将Android看做是一种特异性JVM平台、还有从嵌入式出发将其看做是Linux……但实际上,Android是极少数几个用设计来解决自身发展问题的系统,其核心在于通过硬件抽象、组件化、接口层三种能力来为发展提供基础,并为诸多变数预留大量可操作、斡旋的空间。
![1.png 1.png](http://ata2-img.cn-hangzhou.img-pub.aliyun-inc.com/da35b6deba2a97f1d4fd32bd56125fdf.png?x-oss-process=image/resize,w_1400/format,webp)
2.1 发展的前提-硬件抽象
2008年,我国迈入3G时代前夜,基础设施的变革带来充满变数的移动领域,无论设备、硬件还是软件的形态均未定型;擅长架构和软件的Google在这一领域要获得生存和长足发展,需要团结一切可能的、甚至是未知的力量。取得移动运营商、芯片供应商、手机制造商的支持则是生存的第一步。
硬件抽象层(HAL)在一定程度上起到这样的目的:它为移动领域五花八门、标准不统一的硬件驱动定义标准接口,避免Android过分依赖Linux,让后续的扩展和整机集成更为高效,满足了手机制造商的重要诉求;同时还起到隔离Linux内核的作用,避免厂商充满硬件秘密的驱动源码受GPL协议影响而开源,保障了芯片等硬件制造商的核心利益。
传统手机OS的定制和集成流程需要修改大量代码,负担不少,从这个角度来看Android HAL其设计是领先的。结合AOSP优良的代码分支、模块管理,加上基于GNU automake巨集形成的Android build system,厂商享受到超越以往的便捷。然而HAL并无固定做法(如图2所示),Android 8.0之前,最初大量采用HAL旧版方式,表现为framework直接加载*.so并依赖,主要集中在网络、蓝牙等模块;旧版方式导致framework与具体驱动接口耦合过紧,后来形成HAL传统方式,即提供一定规范和接口进行改进,从而减少直接耦合,但每次厂商支持新版Android依旧需要更改不少代码;为更有效解决这一问题,Android 8.0开启Treble项目,于是芯片厂商通过基于Binder的HIDL提供稳定接口,制造商则可不受芯片厂商影响而直接更新Framework,甚至获得无需重新编译HAL即可OTA的能力。
![2.png 2.png](http://ata2-img.cn-hangzhou.img-pub.aliyun-inc.com/dfd01f11e192bd5dcb93b6332f4e3ef3.png?x-oss-process=image/resize,w_1400/format,webp)
受益于HAL设计和其改进,Google在全球获得更广泛的支撑,尤其是Android 8.0在国内厂商的迅速适配可见一斑。HAL为Android设备量的持续增长打下基础,并促进有实力的厂商向设备上层以及基础设施两个领域进一步纵深发展(图3)。无论是掌握核心技术的厂商(如高通、华为、MTK),通过挟5G标准支持及端侧设备系统能力不断加强与上层APP联动,还是具备渠道和资源整合优势的手机制造商(华为、OPPO、小米、VIVO等),立足OS持续构建应用层面的能力版图,都体现出Android HAL设计对整个产业凝聚和影响,间接弥补Android自身的诸多不足。
![3.png 3.png](http://ata2-img.cn-hangzhou.img-pub.aliyun-inc.com/81e24094b3604b78868e753e0108a37c.png?x-oss-process=image/resize,w_1400/format,webp)
2.2 能力的枢纽-组件化
对能力进行如何组织和复用是架构的最大挑战,借鉴现有能力是发展的捷径。无论是Mircosoft的COM,还是OMG的CORBA,或是从EJB到Spring、从SOA到Serverless,随着基础设施如网络、终端设备的能力提升,这些技术的发展呈现出从重量到轻量、从对中心(总线)的重度依赖到轻量级依赖的趋势。Android充分结合各领域先进技术,并基于移动端资源受限这一最大特色,形成了自身的技术特色:AIDL衍生自复杂的CORBA IDL,组件由SOA精简而来,各独立生老病死的System Service类似一个个微服务,Binder可以看做是对一种弱化总线、性能更好、可点对点通信的DBUS,UI布局系统则极大程度受到SWING的影响、manifest实际上就是APP与系统通信所必须的组件接口描述文件......
上面提到的这些领域技术的确有利于Android发展,但远远不够。回想之前谈到的HAL以及整体架构,我们看到Android实际上就是个大杂烩,使用的是诸多技术的混合。过去除PalmOS外,无论是基于Linux/Unix构建的系统如Meego,还是Symbian、MTK、UCOS、WindowsCE,无论是实时系统还是非实时系统,这些移动端系统都以C/C++为主且小巧精悍,对内存使用和要求极为考究,虽然满足了资源受限设备的使用诉求但带来了门槛;虚拟机类的平台如KJava、.NET on Windows Phone虽然内存使用和能耗方面比较大方,却胜在研发效率和容错性,因而受到不少开发者欢迎。所以选择混合架构对于缺乏完整移动领域产业链支撑的Google既符合其自身技术理念、又胜算最大,所以量身定制的组件化能力便肩负起这一使命,使得各组件得到有机组合、应用之间以及应用和系统的沟通更为明确和有约束,最终帮助整个系统灵活运转,能力被迅速放大。
观察Android系统的启动运行流程(图4)以及APP对系统能力的使用(图5),可以发现其上各类能力已按照组件化标准和粒度进行组织(能力的注册发现、接口和通信的标准化、运行空间的隔离等),让快速迭代的手机硬件和持续升级的系统能力以最小代价透出,将复用的价值在移动设备系统上具体化并最大化,从而具备更高的灵活性和兼容性;其背后软件工程的意义在于为软件需求、设计之间架起一座桥梁,解决了系统结构和研发需求向实现平坦过渡的问题。
![5.png 5.png](http://ata2-img.cn-hangzhou.img-pub.aliyun-inc.com/24384c83ba0004670990016774d1e564.png?x-oss-process=image/resize,w_1400/format,webp)
当然,历史上其他公司面临这类挑战时也有不一样的想法,例如Windows Phone 8.0选择了另外一条路,无论是提供媲美JAVA的C#及VB.NET框架、还是基于Sliverlight Dependency Property + XAML的UI系统、甚至是为了支持C++研发出来的C++/CX及一套运行时,都仿佛无时无刻标榜着其系统技术的多样化与复杂性,可以算是一场技术盛宴。但这种解决方案更多是从公司自身优势出发,通过不断增强并加大Runtime复杂度来支撑混合技术能达到目的,实际却是过分迷信技术本身以及技术先进性,缺乏对客观情况的深入分析。Meego则是另外一个例子,号称救Nokia于危难,由Intel联袂推出,通过各种开源能力的组合来完成系统的建设,如Linux内核+QEMU模拟器+QT+QML界面,但实际上昙花一现。这样一个系统是否迎合时代并满足发展需要,本质上是否有任何更先进的变化?从当时与Nokia & Intel共同研发的经历来看,其更像是一种仓促应战的产物,难以扭转趋势扶大厦于将倾,自然更无法与打磨多年、处心积虑又步步为营的Android匹敌。
2.3 应用的基础-接口层
系统能力基本就绪,如何迎来更多开发者对Android长远发展至关重要。选择JAVA作为上层语言,既需要勇气又足够彰显其野心;为迎合资源受限这一移动领域过去、现在也是未来的最大客观事实,设计了基于寄存器架构、可执行文件更小的Dalvik虚拟机,并通过净室工程来高质量实现,最终结合诸多工具对外提供了流畅的JAVA编程方式,摆脱类似MTK feature phone只能用KJava写些小游戏的局限,使得Android研发兼具JAVA的便利和不错的性能。
天有不测风云,SUN在09年4月被Oracle收购,距离Android 1.0发布还不到一年。虽然最初选择Apache Harmony来提供JAVA API已是不错选择,但依旧遭遇到技术上如不支持JAVA 7/8特性、版权上如Oracle接踵而至的诉讼等诸多挑战。为应对这一切,Google从Android N开始,将对JAVA的支持变更为OpenJDK。虽然OpenJDK是Oracle开源项目,但用上它恐怕依然如芒在背,加上Android体量已不可同日而语,进一步规避JAVA的风险被提上日程,映入眼帘的Kotlin因为特性相近、又可被编译为class或者dx字节码,获得Google青睐和收编(图6)。
![6.png 6.png](http://ata2-img.cn-hangzhou.img-pub.aliyun-inc.com/22f3e19496edfa609a934f3a1a46b770.png?x-oss-process=image/resize,w_1400/format,webp)
实际上,之所以Android敢这么做,也还是因为有其设计基础的支撑,根据个人的一点粗鄙了解,从Android API的调用链路(图7)上能发现一点端倪:无论底层依赖、实现和流程如何变化,上层的使用形式并不会改变。
![7.png 7.png](http://ata2-img.cn-hangzhou.img-pub.aliyun-inc.com/39f9e80290401cc8017ef700b29f47f3.png?x-oss-process=image/resize,w_1400/format,webp)
这意味着几乎所有系统能力的核心,已在native library被实现殆尽,并结合上层提供良好屏蔽,为其他语言实现Framework提供可能,尤其是一门特性与JAVA相近的语言。所以是什么语言、是不是kotlin都只事先设计规范下的一种合适的选择。 尽管未来Kotlin和JAVA将依旧将琴瑟和谐,但考虑到Google不遗余力地追捧Kotlin以及自身的良好设计,这为将来Android与JAVA版权问题的彻底了断埋下一种极端可能(图8)。
![8.png 8.png](http://ata2-img.cn-hangzhou.img-pub.aliyun-inc.com/0f1b50a68a55f637eca80a92d87c4b94.png?x-oss-process=image/resize,w_1400/format,webp)
3. 对于我们的象征意义和实践
综上所述,Android从三个方面来解决其发展的关键问题:
硬件驱动:形成厂商的合作基础,并反过来对整个产业施加影响
组件化:高效组织各种内部能力,寻求自身的更快发展
接口层:满足上层对系统和硬件能力的各种使用诉求
移动互联网产业巨头发展因为起点以及执行理念不同而有所不同,Apple围绕着其AppStore构建其整个体系并精心维护,而且在现代化API编程、整机体验、垂直领域技术如网络/算法等各纵深领域走在前列;Google则用Android带路,需要在各个层面维护和团结不同力量走出一条自己的路。所以,Android本身为系统如何发展提供了另外一种解答:除关注系统自身能力的发展,如何维护好系统不断发展的基础和前提、如何更好地暴露和让外界使用系统能力也至关重要(见图九)。
![913.png 913.png](http://ata2-img.cn-hangzhou.img-pub.aliyun-inc.com/d5e3a39ea7cde3169c06e78f496083da.png?x-oss-process=image/resize,w_1400/format,webp)
回到我们自身,在重用户、重交互、手机即人的今天,终端中间件有理由也有必要用自身丰富的内涵延展和放大服务的价值。要做到这一点并非易事。首先,业务迭代越来越快,各种应用层出不穷对中间件意味着广泛的需求;其次,环境在改变,无论是运行硬件和设备的五花八门,还是对接服务以及集群的丰富多样,都对集团原有端侧中间件带来巨大冲击;再次,在基础技术发展变缓的今天,技术的价值需要被持续放大,我们希望基于自身能力来构建服务和业务的泛连接基础,并将其作为发展愿景。于是这要求我们基于集团背景以及核心APP发展的主要目标下,来统性思考这个发展问题(图10)。
![922.png 922.png](http://ata2-img.cn-hangzhou.img-pub.aliyun-inc.com/47f6c366a2a907bf96db8105da2947dc.png?x-oss-process=image/resize,w_1400/format,webp)
通过Android的启发,结合环境和现状,在满足业务目标的同时我们从三个层面不断演进网络能力(图11):
- 首先,通过覆盖线上线下、各类场景、形态各异的设备,并不断打造高效私有、支持通用标准的协议,来构建设备和服务、用户与业务的泛连接基础。
- 其次,我们自底向上地抽象,将非阻塞IO复用、用户态网络栈支持、通道能力扩展以及可支持混合集群的多实例架构进行高效组织,从而保障了数据在不通层面的流转和管理诉求。
- 最后,基于SDK矩阵和接入能力的建设,我们实现了服务接入到业务、业务透出给用户这一双赢局面,并提供丰富的体验、性能甚至是业务和场景数据,为集团发展带来更多价值。
![990.png 990.png](http://ata2-img.cn-hangzhou.img-pub.aliyun-inc.com/046508dae6353e3cda447383743c90fa.png?x-oss-process=image/resize,w_1400/format,webp)
通过多年以上工作的不断迭代,目前我们已能触达海量设备和用户,成为接入集团内外各服务和平台的接口,并为终端和服务分别屏蔽集群的多元化及设备的多样性,实现新零售系统能力与用户的泛连接(图12)。
![10.png 10.png](http://ata2-img.cn-hangzhou.img-pub.aliyun-inc.com/5fee679111fbe156ac8592e89592a858.png?x-oss-process=image/resize,w_1400/format,webp)
4. 小结
结合传统的C/S观念,服务端获取的信息来源于各网络终端,网络+协议屏蔽或规范了外界对服务输入的多样性,使得服务端过去关注的是集群和高并发,但现在无论是上云还是利用率,背后都是业务、成本规模和边际效应在驱动,这里面发展的代际主旨鲜明。但回到客户端,由于受到环境和交互等多样性直接影响,即便是动态性的技术也难以代表端侧的全部甚至是主流。所以在某种局部技术比拼武功,成为过去客户端的一种行业“潮流”。
在局部技术和单点深入的确有其意义,笔者也曾有过一些班门弄斧,如非轮询方式获取手机栈顶Activity、面向阿里特有复杂集群的SDK多实例设计、Sophix热修复云上产品等。但结合过往经验及Android设计,立足于如何最大化技术的业务甚至是商业价值,可以更系统性地看待技术尤其是客户端技术的发展:即除了满足业务核心诉求外(因为投入大量资源,必须、肯定要成,至少小成),更应该关注技术如何更好地服务业务以及如何持续挖掘能力护城河这两头的问题。所以要打造好一个系统,除构建各中坚能力外,还需维护好系统发展的前提、组织好各系统能力的内聚、满足好外部对系统的诉求。
以上是个人从Android系统设计到技术支撑系统发展的一点浅薄看法。