当前位置: 首页 > 科技观察

跨全端SDK技术的演进_0

时间:2023-03-21 21:11:55 科技观察

仔细想想,团队已经进行了三年多的跨平台开发,也是集团内较早涉足该领域的部门之一C++方向。随着业界跨平台技术的发展和演进,我们也积累了一套基于C++的跨平台技术体系。为什么选择跨平台的实现方式WriteOnce,RunAnyWhere。越来越多的业务需求统一了业务需求。按照传统方式,开发、测试、维护的成本是N倍,体验上也很难做到一致性,尤其是复杂的业务,实现成本高,导致功能无法上线很快,并且每个端侧的对齐都会产生成本。总体而言,此类或类似服务是基于研发效率等考虑。使用跨平台实现是非常有必要的。这里我们以电商新闻为例。多个角色的操作,多个场景的触发,多种能力的支持,让我们的消息系统变得非常复杂。历史发展下的多路消息系统底层,由于历史发展,衍生出三个子系统。分别是:BC消息——最早的阿里旺旺就是基于这个AMP消息——淘宝天猫的各种运营都是以此为基础,衍生出来的主要业务有商家群、淘友、人才业务等,IMBA消息——主要是数字方面的相关新闻,包括BC通知新闻、人才运营、品牌运营等,是在不同的BU维护的,这些都是多平台运营下需要的,比如多角色融合,多运营商运营的诉求,每个运营商有多个平台。基于以上背景,需要开发一个高可用、高复用、可定制的跨终端消息模块。关于语言的选择,是选择编译型语言还是解释型语言,我觉得没有绝对的观点。具体选择取决于业务形态、适配终端类型等诸多选择。这里我们选择C++跨平台开发语言的一些背景选择。我们的团队本身就是一个客户端业务团队。目前的跨平台业务主要是消息和消息派生服务的开发、维护和创新。主要终端包括移动IOS、移动Android、MAC、WINDOWS。主要载体有淘宝APP、天猫APP、千牛APP、淘特APP、1688APP、ICBUAPP等。C++作为天然的跨平台语言,可以高效无缝调用系统能力,拥有丰富的技术生态,综合组中的技术栈更适合我们。其实我也跟群里其他几个有类似需求的团队聊过。目前更多选择C++技术栈。本文还将重点介绍C++作为跨平台选型语言。即使是客户端,也有很多跨平台的语言可以选择。通常最好遵循跨平台技术解决方案。没有绝对的对错,只有适不适合自己。关于基础库的选择,既然我们选择了C++作为我们跨平台开发的基础语言,那么我们面临的第一个问题就是需要一个功能比较完备的、满足当前需求的基础库。我们调研了市面上几个主流的基础库,结合当时组内的情况,特别考虑到移动端的现状:包大小的问题各种中间件(mtop、db、accs等)群里都已经跨端了,要不然各端都有比较优秀的独立SDK提供。基于第一个考虑,这部分不需要在基础库中重新构建。基于以上因素,组内还没有合适的足够小的C++基础库来满足需求,所以我们决定基于C++STD开发一个符合移动端现状的轻量级跨终端基础库。下面是跨终端轻量级基础库(LITE)的功能集合图。在设计这部分时,主要考虑几个设计原则:要覆盖基本能力,综合考虑封装尺寸、性能和功耗。除了提供volume等默认实现外,当系统层面有更好的能力或更好的解决方案时,可以统一嫁接复用端的能力。比如组中间件mtop、accs等,或者Crypt等模块,我们希望用一种比较简单的方式实现,调用Openssl的加解密接口,熟悉Openssl的同学都知道它的库大小是1M左右,同时IOS系统直接提供了OpenSSL能力,所以在做这部分的时候,我们提供一个默认的实现,同时开放统一的接口接入系统能力,达到最优数据包大小。用9个字概括设计原则:最小足够可扩展性原则。平台包大小(kb,基本功能)说明ANDROID43kb动态库,v8aIOS116静态库,实际应用大小Windows47kbx86包大小如图(不包含淘宝天猫基本客户端能力,包含后略增加约60k)。目前Lite库作为淘宝系统的C++基础库已经集成到集团近百款APP中。除了包大小的优势,稳定性也很出色,崩溃率在百万分之一左右(淘宝双端统计)。淘宝天猫架构团队协同,无缝提供淘宝天猫客户端基础能力(日志、埋点、键值存储等)。关于跨平台架构的选择,通常技术还是为业务服务的,还是贴近业务来谈比较好。示例:我们面临的问题和诉求:屏蔽通道,统一数据模型对外提供:底层需要连接3台服务器(多通道),每台服务器提供的能力和功能高度相似,这需要抽象出来统一屏蔽给上层,相关数据需要跨通道或者屏蔽通道存储。调用者线程不统一:业务部分需要处理来自不同线程的高并发(对于客户端)请求。多语言:接入层需要适配不同的平台,ANDROID-JAVA、IOS、MACOS-ObjectC、WIN-C++。多维度支持定制:业务定制:业务需要面对不同的APP,可以有不同的功能定制,包括可配置的支持渠道,可定制的业务能力等。例如:Taotri服务中没有群聊,但是这部分是需要淘宝。在千牛,需要有商家群,但不需要淘友关系群等,基于业务和包裹大小的考虑。线程调度定制:基于功耗、系统资源、平台特性等考虑,需要定制线程调度方案。移动端对功耗敏感,系统资源有限,而PC端对性能要求更高。如何在统一的解决方案中支持平台级乃至业务级的线程调度定制化。网络流量管理定制:一方面要对网络能力进行统一监控,方便分析MTOP的各种API调用。另一方面,需要具备统一的切面能力,对MTOP调用进行二次业务级网络流量接口的优化和定制。DB管理定制:基于FD和平台特定的考虑,要求DB管理可以根据不同的平台有不同的定制策略。移动端采用单用户一库多表的形式,PC端采用多库多表的形式,性能最大化甚至可以定制需要支持不同APP的不同的db管理方案.基础能力的复用:对于组内通用的基础组件,需要有统一的能力从外部获取,方便C++层的使用。稳定性保障:是否方便做单元测试,设计中如何避免单元测试对内部代码的侵入。基于以上,我们对MessageSDK的架构进行了如下设计:我们来看一下上面的设计是如何从整体上解决这些问题的。总体分为5个部分,Service层、业务层、数据层、数据通道层和基础服务层。从上到下看整个架构设计Service层:也就是我们通常所说的Wrapper层。它的目的是翻译业务层的C++接口,提供Java、Oc、C++三种方式的直接访问。需要说明的是,除了语言转换,不要在这一层做任何代码。一是便于故障排除。包装器不进行额外的处理和故障排除。其次,业界有很多自动语言翻译的工具。我们稍后会详细讨论这部分内容。.业务层:业务逻辑的组合。以消息为例,按模块分为三个子模块。第一消息模块、第二配置文件模块和第三群组模块。模块相对独立,强制隔离,代码解耦,功能可定制数据层:分为本地存储和网络存储两部分,目的是屏蔽数据源,提供给业务层统一方式,让业务感知不到通道源Eat所有的耗时操作,IO和网络请求,其中Adpter主要是屏蔽通道间的差异。这部分支持整体可替换性,目的是提高可扩展性,可以自定义接入第三方通道数据通道层:这部分是数据源的通道,主要包括SYNC、WXNet、DB等基础服务层:它是一个跨平台的c++基础库。其实,客户端层层划分的设计理念并不明显,无论是在PC时代,还是现在的移动互联网。关注这里的差异也可以说是这种框架设计的优势。便捷:服务我们只做语言级别的胶水,缩短了后期排查的整个环节,方便后期排查和定位问题。同时,自动化的实现也再次降低了维护成本。开放性:上图右侧是Openpoint能力,主要是通过一些标准化的开放点来开放一些能力,让接入方可以做更多的业务属性。形式公开]定制化:业务定制化:模块之间完全独立,代码不耦合,强制隔离,功能可定制,让业务方自由组合业务形式,同时实现最优的封装大小,线程调度定制:统一的线程调度处理方案,抽象的线程配置策略,多个app可以自由配置,上层可以选择最优的平台级线程调度方案。网络流量管理定制化:网络调用点统一切面处理。一方面,它拦截并合并相同的瞬时请求,大大减轻了服务器的压力。各地统一管理处理,方便客户监控呼叫流程。DB管理定制:同线程调度定制,统一DB管理分配方案,抽象库分配策略,多个APP自由配置,上层可选择最优方案进行平台级线程调度。扩展:对外提供整体能力,可动态更换。目的是为接入方提供一种放入自己的数据通道的能力,从而实现业务的扩展。这种方式也极大的方便了后期的统一单元测试。对于CPP程序员来说,线程模型非常重要。一个好的设计可以从架构上避免后期隐藏的一系列bug,包括一系列的问题,比如:在移动端,通常调用者不关心调用Threads,但是在数据层,统一数据业务层需要频繁调用修改和聚合能力。锁太多可能会导致死锁,不利于性能最大化。如果某些接口的IO和NET时间过长,可能会导致整个流程中断或异常。下面看一下跨端SDK架构设计的线程模型:接入层:无限调用线程,降低接入成本locking同时实现单业务无锁,多业务并行模型层:主要针对IO和网络操作,目的是针对业务线程IO,网络非阻塞整个线程模型的特点:纯异步,可定制,单业务Lock-free,多服务并行,无阻塞IO网络。C++工程脚手架与C++工程标准化C++作为天然的跨平台语言,可以高效无缝地调用系统能力,拥有丰富的技术生态。然而,Android、iOS、Windows、Mac等多平台的实际开发过程并不顺利,主要存在以下问题:平台特性、开发语言、开发工具链、编译打包等方面的差异。高多平台下的项目配置和维护成本Glue(语言转换层)代码人工接入成本高,重复性工作大,门槛高(主要针对C++开发者)业务和技术框架选择困难;建设和发布计划缺乏标准化;集团研发平台专为跨平台构建和发布而设计不足我们在想,SDK的开发过程是不是可以是SOP的过程?如果有统一的跨平台SDK开发SOP流程,尤其是对于新手来说,当然是非常友好的。想一想,如果coder能上来,他就可以写业务代码,不用关心框架、工程模型、封装方案等等,是不是很美好。为了解决以上常见问题,结合我们之前在消息SDK方面的经验,我们推出了Eyas(Eagle)项目。Eyas旨在进一步结合集团的技术能力,降低跨终端开发成本,为其提供标准化的操作流程,包括跨平台基础库组件化、业务框架通用化、配置集成、语言转换层代码工具化、发布能力A统一等全套解决方案,让开发者在轻量级理解跨终端的同时,更专注于业务本身。Eyas的中文是YoungEagle。我们希望通过Eyas,共同探索跨终端蓝海的无限可能,同时孵化更多跨平台模块,让开发者低成本开发跨平台SDK,保证业务一致跨平台。提高业务开发效率,降低测试成本。为了让开发者更快的上手跨平台开发,我们制定了一套跨平台SDK开发的操作流程,同时在每一步都提供相应的解决方案,所有的解决方案都提供工具。高效低成本协助开发者开发跨平台SDK。下图是MTL4上的C++跨平台研发工作流程:其中IDL(接口描述)的编写和功能代码的编写需要开发者根据实际业务进行开发。我们从项目创建、代码生成、编译选项和构建四个维度来分析。?创建项目跨端团队在过去的桌面开发中积累了大量的SDK开发经验,也有一套成熟的SDK框架代码,但是我们在孵化一个新的SDK时,还是需要花费一定的资金对SDK通用代码copy的时候,无法快速copy一个新的SDK工程。开发人员很懒惰。为了尽可能重用代码,提高开发效率,开发人员发明了宏和模板编程。为了支持SDK框架的公共代码和项目配置的复用,我们提供了基于项目模板创建项目的工具,快速实现项目工程从0到1的过程。其实对于刚上手的开发者来说涉足跨终端开发,创建一个可以在不同平台编译产品的项目,打开了跨平台的大门。?代码生成代码生成是语言胶层代码的插桩。由于平台开发的语言差异,语言翻译需要一层胶水代码。胶水代码本身没有业务逻辑,消耗开发成本。存在出错的风险。我们使用胶水代码自动化来解决这个问题。胶水代码自动化原理:根据接口的idl描述生成接口文件和胶水代码.com/dropbox/djinni)进行了二次开发,提高了安全性,增加了多项功能,更容易为复杂的模块定制项目。?编译配置+依赖管理项目结构:支持以下能力:使用GN管理项目和源码文件,保证多端C++项目配置一致。统一多平台业务模块的定制能力。支持多平台下不同IDE编码调试。结合集团技术能力,统一依赖管理方案,支持通过单一配置文件管理多平台下的依赖关系。团队介绍我们是淘宝技术部的行业和商家技术跨终端技术团队。在业务上,我们负责为千万商家打造最高效的一站式工作台千牛,为淘宝上的亿万商家和消费者提供稳定高效的终端服务。端到端消息IM服务;技术上,深耕C++跨终端和PC桌面技术(Windows&Mac),为商家和消费者提供稳定、可靠、高效的客户端产品。