原创 孙棋(空蒙) 淘系技术 2020-12-22
淘系业务高速发展,淘宝、天猫、淘宝直播、淘宝特价版、闲鱼等平台上业务不断创新,同时也对技术效率提出了新的更高的要求。而当前移动互联网客户端服务端分离的研发模式,存在跨技术栈+多端协同的挑战,也面临一些基础的技术和业务能力无法有效的复用的问题。在此背景下,结合云基础设施的演进,结合端技术的发展,淘系技术探索实践了业务云端一体化的研发,围绕应用架构的跨代升级,构建新的研发过程、研发体验,在研发期、交付期、运行期重新定义了前台业务的研发模式。
业务研发模式演进的核心驱动力
“能力复用”、“跨端”、“技术栈归一”是移动互联网业务效率提升的三大底层核心驱动力,围绕这三个点业务研发模式不断的演进,以适应业务高速发展的诉求。
整个软件工程发展的历史,就是复用的历史,一个行简单的“hello world”,背后是一个工程奇迹,比如内核2700w行代码,以及整个技术开源生态提供各种能力的组合,互联网业务应用无不是站在巨人的肩膀上。能力的复用从使用模式上可划分为代码复用、服务化复用、组件化复用三种形态,背后是业务效率、隔离、成本上的平衡。
移动互联网android、iOS两大技术生态,给业务在跨端一致性、业务效率上形成了巨大的挑战
技术栈归一,并不等同与跨端,也不是开发语言的统一,类似当前有业务全栈工程师的一种探索,这种模式是对开发人员提更高的要求,他要解决客户端、服务端,用不同的技术栈来完成业务研发的闭环,这并不是技术栈归一。技术栈归一是面向业务的技术栈收敛,让业务回归自身,通过合理的分工边界来减少协同。
我们来看淘系移动业务研发模式演进,最开始是“客户端-单端”的研发模式,一句话概述是“write repeatedly,run independent”,核心的问题是业务逻辑要重复的开发,并且面临业务多端一致性的巨大挑战;既然如此我们自然想到“客户端-跨平台”的研发模式,即“write once,run everywhere”,用一份代码实现业务的交付,这个阶段很多跨端技术框架层出不穷,典型的代表,从渲染模式上分类,可以分成基于webview渲染的各种hybird,以及通过jsbridge调用native原生渲染的RN和WEEX,以及直接从底层渲染引擎出发的flutter,这很好的避免了重复开发,业务多端一致性的挑战业务收敛到跨端技术框架上;
当前淘系业务研发挑战与应对
这样的研发模式是否已经完善,我们来看当前的一些现象。
移动互联网业务研发这些现象背后的核心问题是什么呢?
可以看到当前的业务研发模式,是以技术栈划分了客户端和服务端的强边界,中间基于API协同的模式,而API的定义随着业务快速发展是易变的、这层API并不是如TCP与IP层之间那样,有清晰的边界,不同的职责分工,易变这就造成了高昂的协同成本。同时也因为不同的技术栈,人力资源配比会对业务发展形成制约。伴随着业务平台化发展,业务平台化本质也是“能力的复用”来提升效率,大量业务都形成了面向前台业务页面的backend for fronted这一层,这层典型的特征是编排组合能力,快速的完成业务交付;比如一个活动页面,获取用户信息、商品信息、积分信息等,这本来是个内聚的业务,却因为技术栈的边界而割裂。
这些问题背后的主要矛盾,是一体化的业务,与技术栈为边界、基于契约分工协调研发模式的不匹配。举个反例子,泥水匠砌墙分两步,先是依据砖块要处的位置决定在某几个面涂上水泥浆,然后把这块砖放到合适的位置上;如果这两步分开为砌墙工程师+涂水泥浆工程师来协作,两个人在砌墙的时候还要对眼神确定应该给砖块某个面涂水泥浆,涂多少水泥浆,这样砌墙的效率还能快吗?
因此我们自然而然想到,让前台业务实现云+端一体化的研发交付,即“write integration run everywhere”,简类比研发模式变化,从原来的三个和尚没水喝,到两个和尚抬水喝,到一个和尚担水喝。那关键问题,如何让简单的编排逻辑的BFF层,由端同学实现闭环呢,从割裂的客户端+服务端研发,转变为前台业务研发,这里会有哪些困难
业务BFF现状是一个单体巨石应用,分析可见他由工程框架、通用技术、领域复用和业务逻辑共同组成,客户端研发首先面临开发语言门槛问题,技术栈上是不一致的;其次是业务隔离性问题,业务这一层与其他三层是紧密耦合的关系,而且业务平台的富客户端有高昂的开发语言约束的壁垒,也正因为这些客观因素,导致一个应用里面的业务越来越多,最后变成了业务间的耦合,造成研发效率的底下;最后是BFF运维的复杂,对客户端技术同学而言是巨大的壁垒。
那么这些问题怎么解决呢?核心2个策略,“多容器应用架构”+“组件化应用架构”,我们先看前者。
云原生技术发展,容器设计模式提供了多容器支持,为业务和依赖解耦提供了新的路径,原来业务之外的领域复用层、通用技术组件和工程框架,全部隔离到bottle runtime,业务逻辑独立运行在biz runtime,两个容器共同组合gaia application的容器规范;这里带来一个显著的变化,业务变轻量了,因此biz runtime的多语言变为可能,支持跨端研发语言门槛被解决。
这里还有另外一个问题,领域复用层内,包含了多种多样的领域能力,虽然与业务剥离了,但他们之间还是缺乏有些的隔离,同时富客户端高昂的使用成本怎么解决,如何让前台业务研发达到开箱即用的效果?
组件化应用架构就是实现平台能力快速复用的核心。首先bottle runtime支持开放扩展架构,支持组件的按需加载使用;从流量进出视角划分,定义了两种基本组件类型,其次不同的组件都有其自有数据协议,gaia定义了binding协议统一封装,面向业务研发则抽象了OnInputEvent、InvokeBinding、InvokeService三个基本接口,把组件能力标准化,这样OnInputEvent对应了InputBinding类型的业务组件,InvokeBinding、InvokeService对应了OutputBinding组件,两个容器见基于本地通讯的grpc收口。
有了组件化的应用架构,围绕这个架构的组件生产、交付、使用的配套体系也需要同步的建设。从组件生产者而言,他只需要按照bootle component规划来开发,交付时候gaia平台会自动生成各种语言原生的SDK,上传到组件库;对前台业务开发者,仅需要声明引用组件,编写自己的业务逻辑,后续的构建交付平台会自动的把组件交付。最终实现组件的开箱即用的效果。
总结来说,通过“多容器架构”+“组件化架构”的演进,业务函数化研发,解决了客户端同学实现云+端一体化闭环的技术栈门槛问题,领域能力开箱即用,让“前台业务研发”跨端闭环从设想到落地。
业务云+端一体化探索实践
有了这些架构能力升级,我们来看淘系业务云+端一体化的实践,基于业务的特性划分为3种典型的应用场景探索,分别是“一体化快速创新迭代”、“复杂交互逻辑”、“模块化搭建复用”。
▐ 一体化快速创新迭代
面对简单的业务编排场景,因gaia提供了跨语言的函数化研发能力,整个研发生产关系发生了变革,前台业务研发可以实现BFF到客户端flutter研发的闭环,用统一的Dart开发语言,不再需要协同开发,原来碰到的各种协同问题天然不复存在,实现内聚业务的“技术栈归一”;同时业务平台领域能力,成为gaia的组件,实现高效的“能力复用”。我们来看闲鱼足迹,这个典型的应用场景。
原来客户端+服务端基于API协作的研发模式,现在由“前台业务研发”一个角色来跨客户端和服务端的闭环,他从足迹的保存、查询、删除实现完整业务的交付,商品平台的领域能力提供商品信息查询,这个领域能力通过组件化开箱即用。
这种方式下,API还是一个显性存在的,强嵌入研发交付和运行过程当中的;大家估计也会碰到大量的API需要维护;同时API的粒度很难把控,一个页面,到底是一个API编排所有的服务,还是细分多个API,都有利弊,尤其是复杂业务交互逻辑的场景,是否有更高效的方式?
▐ 复杂交互逻辑
基于redux的一体化研发框架,是解决复杂交互逻辑场景的钥匙,其核心是基于store的state状态变化,驱动页面渲染,交互产生的事件,再由reducers函数化业务逻辑更新state;这套框架我们定义为Nexus一体化研发框架,对事件进行了抽象封装,把常见事件的统一定义,同时支持业务自定义事件类型,并打通客户端到服务端闭环。
比如闲鱼的交易下单场景,页面上涉及多块的数据,包括闲鱼币、详情、收获地址、运费、红包服务等,如果1个API编排所有的服务,势必造成业务的耦合,而多个API又对客户端交付复杂性、用户体验等产生影响,同时这个页面又存在修改地址、使用红包等用户业务交互的场景,最终情况往往是沉重的客户端逻辑,兼容与扩展性存在巨大挑战。
一体化研发框架则优雅的解决这些问题,页面级的orderPageState,他是由详情、收获地址、红包等state组成,页面初次渲染时候是init action,gaia业务函数响应并更新state,同步到客户端驱动页面的渲染;当后续有修改收获地址等事件发生,也是同样的处理流程闭环。
以此实现了页面和业务逻辑的解耦,业务通过自定义扩展事件驱动,把业务逻辑下沉到了云端,客户端轻量化交付,也解决了客户端版本化发布重逻辑带来的碎片化挑战,同时业务逻辑基于state的扩展组合和事件驱动,实现业务细粒度的解耦,提升了业务效率。这种研发模式下,API已经弱化不再需要基于强协议的开发。
▐ 模块化搭建复用
看淘系业务页面组成,肉眼可见的存在复用的可能,“能力复用”本身就是业务效率提升的核心驱动力,同时业务高速发展也提出了通用的诉求,不可能所有的业务都是从0到1的开发,那怎么样去实现页面的复用呢?
分析页面的结构,其实质是由模块组成的;模块则由layout节点和普通节点共同组成,layout是信息流、stick等多种形态按业务的选择,普通节点是一个个端组件,端组件是UI控件模板和数据源共同组成,实现最终的端组件渲染展示与交互使用,我们自然想到,通过页面模块化的搭建,实现快速的业务交付。
DinamicX是淘系端组件化的产品,与gaia的结合提供数据的编排能力,建设页面搭建平台,让业务交付从开发编码,变成一次快速的配置交付过程,所见即所得。
看淘宝特价版活动页的例子,通过搭建平台把多个模块组合起页面,模块则由布局节点和普通节点端组件组成,端组件后面是对应的数据源服务,让这些业务快速交付。
总结展望
淘系前台业务云+端一体化的探索,核心是通过多容器应用架构的升级,打通了技术栈的边界,实现了业务跨云+端的闭环;通过组件化的应用架构实现领域能力复用的透明化;通过函数化的研发交付让运维透明;通过云端一体化框架以及页面模块化搭建,让“前台研发”专注于业务。
云端一体化研发模式闭环,沉淀典型应用场景模式。前台编排型场景交付效率提升30%(bug数量减少20%);闲鱼求购、悬赏端到端简单需求变更一人半天上线,这在过往从0到1的开发模式下是不可想象的;研发期修改调试10秒内交付生效,真正做到秒交付的研发。
当前gaia平台已经实现百万级QPS、百亿级流量运行,包括闲鱼、淘宝互动、淘宝特价版、淘宝拍卖等等众多的业务场景已经广泛的使用。
总结淘系前台业务云端一体化研发模式的探索,本质仍是围绕“能力复用”、“跨端”、“技术栈归一”这三个核心的驱动力的探索;云+端一体化“前台业务研发”,是业务研发分层职责与关系的再定义,从基于物理的技术栈边界,转为以业务内聚的逻辑边界;底层则是应用架构的升级,基于单一职责,多容器+模块化的方向演进,让业务聚焦自身。
展望未来,首先是在研发工程体系上,要端到端打通一体,对应研发配套基础能力,如调试、问题排查等,是后续研发模式成败的关键,这个点上往往是大家做技术平台产品容易被忽视的点,很多产品大逻辑是通顺的,最终往往死于细节。其次要实现运维自动化,组件的管控,面向业务透明升级,基于流量驱动的容量管理,运维透明化是个巨大的挑战。最后,技术不是银弹,当前这种架构和研发模式有其适用的场景,也有其负向的效应,比如机器资源overhead的成本,运维职责逐步转移到平台后如何用技术能力系统化解决,是未来可期待的突破。