关于为什么要选择跨平台的实现方式
Write Once, Run AnyWhere.
越来越多的业务需求都有统一的业务诉求,按照传统的方式,在开发、测试、维护上的成本都是乘以N的,体验也很难做到一致性,特别是复杂的业务,实现成本高,导致功能不能很快的上线,各端侧对齐存在成本,综合来看,这样或者类似的业务基于研发效率等考虑,选择用跨平台的实现方式是非常有必要的。
多角色的运营,多场景的触发,多重能力的支持,导致我们的消息系统十分的复杂,历史发展下的多通道消息系统底层由于历史发展衍生出3个子系统分别是:
分别在不同的BU维护,而这些在多平台运营下都是需要的,比如多角色的融合,多载体运行的诉求,每个载体又有多种平台。
基于以上背景,研发一个高可用、高复用、可定制的跨终端消息模块是非常有必要的。
关于语言的选择
选择编译型语言还是解释型语言,我觉得是没有绝对而言的,具体选择哪个要根据面对业务形态,适配的终端类型等多方面抉择而言,这里说下我们选择C++作为跨平台开发的首选语言一些背景。
C++作为天然的跨平台语言,可以高效无缝的调用系统能力,有丰富的技术生态,综合组内的技术栈,是比较契合我们的。
其实也跟集团里其他几个有类似需求的团队聊过,目前选择比较多的也是C++技术栈,本文也将以C++作为跨平台选型语言为主要来讲述。
即使是对于客户端而言,可选择跨平台语言也是众多的,通常跟随着跨平台技术方案一起来看会比较好一些,没有绝对的对和错,只有是否适合你。
关于基础库的选择
既然选择了C++作为我们跨平台开发的基础语言,那么面临的第一个问题是需要有一个功能较为完备,且符合当前诉求的基础库。我们调研了市面上几个主流的基础库
再结合集团内当时的现状,特别考虑移动端的现状:
综合以上因素,集团内没有合适的足够小的且满足需求的c++基础库,因此我们当时决定自研一个基于C++ STD的符合移动端现状的轻量级跨终端基础库。
这里是跨终端轻量级基础库(LITE)的一个功能集合图,在对这部分进行设计的时候,主要考虑的几个设计原则:
总结一下设计原则9个字:最小够用可扩展原则。
平台 | 包大小(kb, 基础功能) | 说明 |
ANDROID | 43kb | 动态库,v8a |
IOS | 116 | 静态库,实际占app大小 |
Windows | 47kb | x86 |
包大小情况如图(未包含淘宝天猫基础客户端能力,包含后略增加60k左右)。
目前Lite库已经作为淘系C++基础库集成在集团的近100个App里,除了包大小优势外,稳定性也极佳,百万分之1左右的崩溃率(淘宝双端统计),同时与淘宝天猫架构组合作,无缝提供淘宝天猫客户端基础能力(log、埋点、键值存储等)。
关于跨平台的架构选择
通常技术还是为业务服务,还是贴近业务来讲述,能更有体感一些,这样也更直观的把我们遇到的问题和背后思考透漏给大家,作为参考,还是以消息为例:
我们面临的问题和诉求:
基于以上,我们设计了MessageSDK的架构大致如下:
来整体看下上面的设计是如何解决这些问题的。
总体分5部分,Service层,业务层,数据层,数据通道层以及基础服务层。从上到下看整个架构设计
其实客户端按层分割的设计理念,无论是在PC时代还是现在的移动互联,都不是什么显而易见的事儿,主要关注下这里面的差异点也可以说是这种框架设计的优点。
于CPP程序员而言,线程模型是非常重要的,好的设计可以从架构上就避免掉后期一系列隐秘的bug,这里包括一系列问题,比如:
来看下跨终端SDK架构设计的线程模型:
整个线程模型的特点:纯异步,可定制,单业务无锁化,多业务并行化,IO网络无阻塞。
C++工程脚手架及C++工程标准化
C++作为天然的跨平台语言,可以高效无缝的调用系统能力,有丰富的技术生态。但是实际面向Android、iOS、Windows、Mac等多平台的开发过程并不顺滑,主要存在以下问题:
我们在想,SDK开发流程是否可以是一个可被SOP的过程?如果有统一的跨平台SDK开发SOP流程,特别是对于新入此行的同学,当然是非常友好的。想想coder如果可以上来就可以写业务代码,不用关心框架,工程模型,打包方案等等,是不是美滋滋。
为了解决上述共性问题,结合之前我们在消息SDK上的相关经验,我们启动了Eyas(雏鹰)项目。
Eyas旨在进一步结合集团技术能力,降低跨终端开发成本,为其提供标准化的作业流程,包括跨平台基础库组件化、业务框架通用化、配置一体化、语言转换层代码工具化,以及发布能力统一化等一整套解决方案,让开发者们可以在轻量级认识跨终端的同时,更专注于业务本身。
Eyas的中文是雏鹰,我们希望通过Eyas,可以一起在跨终端的蓝海中探索无限可能,同时可以孵化出更多跨平台的模块,让开发者低成本开发跨平台SDK,保证多平台业务一致性,提升业务开发效率的同时降低测试成本。
为了让开发者可以更快的上手跨平台的开发,我们拟定了一套跨平台SDK开发的作业流程,同时在每一步都提供了对应的解决方案,所有的解决方案均提供工具化的方式来高效、低成本的辅助开发者们进行跨平台SDK的开发。下图是MTL4上C++跨平台研发工作流:
其中 IDL(接口描述)的编写 以及 功能代码编写,需要开发者根据实际业务进行开发。我们从项目创建、代码生成、编译选项和构建四个维度分析。
跨终端团队在以往的桌面端开发中积累了很多SDK开发经验,也有一套成熟的SDK框架代码,但是我们在孵化新SDK时候,还是要花一定时间在SDK的通用代码的拷贝上,无法快速的复制出一个新的SDK项目。
开发者都是懒惰的,为了尽可能的复用代码,提升开发效率,开发者发明了宏,也发明了模板编程。为了支持复用SDK框架通用代码和项目配置,我们提供了基于项目模板创建项目的工具,快速实现项目工程从0到1的过程。
其实对于刚涉足到跨终端开发的开发者,创建了可以编译不同平台产物的项目就已经开启了跨平台的大门。
代码生成
代码生成即语言胶水层代码工具化,由于平台开发的语言差异,需要有一层胶水代码来进行语言的翻译,胶水代码本身是没有业务逻辑的,并且耗费开发成本,人工编写代码也会带来出错的风险。我们使用胶水代码自动化来解决该问题。
胶水代码自动化的原理:
根据接口的idl描述生成接口文件和胶水代码
JNI: C++ <-> Java交互的胶水代码
ObjCPP: C++ <-> ObjC交互的胶水代码
我们基于djinni(地址:https://github.com/dropbox/djinni)进行了二次开发,提升安全性的同时增加了多项feature,更容易对复杂项目做模块定制化能力。
编译配置+依赖管理
支持以下能力:
本文为阿里云原创内容,未经允许不得转载。