1.前言代码,一种可视化的应用开发方式,即“用更少的代码更快地交付应用”。如果说低代码在表现形式上确实不是什么新技术的话,它在1980年就已经存在了,但是随着各种前端新技术的出现和云原生时代的到来,低代码已经向我们展示了一个积极的一面边;为用户表示:图形化操作,简单易用;内置多种模板和组件,降低开发难度;可视化拖拽,开发效率高。对于企业:可以缩短产品周期;节约成本,提高效率;并且易于维护,修改后可以立即使用。low-code的优势如此明显,在vivo自然会发挥它的价值。随着vivo互联网用户数量的不断增加,传统开发已经不能满足井喷式的运营需求,而后羿则是在探索解决方案的过程中诞生的低代码平台,支持后台高效高质量的执行-结束行动。目前是vivo后端业务首选的在线可视化开发平台。我们在平台建设过程中也积累了很多经验。下面的内容将以后羿为背景进行详细展开。接下来,我们将从以下五个方面开始我们的低代码实践:前后端分离的低代码解决方案自研高性能渲染引擎千亿级内容交付的高效可视化配置方案如何低-代码和传统开发并存两种,前后端分离的低代码解决方案低代码平台往往有前端部分来牵头,所以早期我们采用了前端技术涵盖一切的解决方案。但是,随着业务量的快速增长,我们遇到了各种各样的问题。这样的需求,比如后羿端是否可以输出独立页面,或者支持纯服务端低代码能力,生产独立接口服务等。为了解决问题,及时响应业务诉求,我们进行了大刀阔斧的重构。在后续版本中,我们采用了前后端分离的低代码方案。当然,这种分离包括“前后端开发分离”和“低代码服务能力分离”,如下图所示,我们可以直观的看到web开发的两种最基本的方式。前后端分离更少,分工更明确,真正实现解耦;前端可以专注于页面交互、用户体验和兼容性,而后端主要负责高并发、高可用、高性能、安全、存储和业务逻辑,前后端的开发方式端分离也是当前行业的主流选择。让我们看一下开发应用程序的低代码方法的差异。一种方式是从产品的角度,或者说非开发的角度。当我们在低代码平台上构建和开发业务时,我们不需要关心整个产品的具体分层和实现细节。我们只需要使用平台提供的能力来构建我们需要的东西。这样,即使没有专业的开发知识,用户也可以构建简单的应用程序。这种平台往往是无代码平台。二是发展观。在这种思维模式下,用户至少会看到前端和后端两种服务。一般来说,这两个服务可能是页面和界面。这种模式更适合程序员。开发思路一致,平台学习成本极低,可以简单快速地开发出更复杂的应用;后羿主要面向开发者,自然而然采用了这种分层开发的模式。低代码平台本身也需要开发者投入大量的开发精力。一个好的开发模式,往往可以事半功倍。目前流行的大部分低代码产品都是在下图所示的两个类别中实现的。前后端不分离的实现会导致平台灵活性差、扩展性差、集成度低。相比之下,我们可以设计一个简单易懂的DSL,交给开发端进行编译和改造,以充分发挥各自的优势。;也可以实现前后端版本迭代和优化升级,互不干扰。如上图所示,得益于前后端分离的分层架构,我们在前端服务层分离了开发者平台和运营平台;开发者平台专注于可视化建设,运营平台面向最终的业务运营;一个负责开发体验,一个负责用户体验;后端通过微服务架构拆分不同的功能模块,实现平台逻辑和业务逻辑的解耦。前后端分离方案层次清晰,解耦,前后端各自的服务在逻辑上也是分层的。得益于这种架构,我们可以很容易地将前后端低代码能力分离出来,以满足更复杂的业务需求。前面我们提到,前后端分离也包括前后端低代码服务能力的分离。如上图所示,将开发者平台生产的DSL传递给端侧,经过各自的运行时分析,可以为不同的用户提供不同的低代码能力;这样用户就可以通过平台搭建页面来连接自己的服务,或者安排接口为自己的页面提供存储服务;可以单独配置页面,也可以独立使用接口服务。这就是前后端低代码能力的分离。一致,对开发者非常友好。此外,前后端分离的方案还带来了其他一些好处:前端通过引入BFF层可以轻松实现动态接口代理、认证、日志记录;服务端也可以做接口的微服务;组件的功能拆分和延迟加载可以提高性能;也能更好的兼容传统开发,各取所长;前后端独立部署,更加灵活高效;也更容易被第三方应用程序集成。3、自主研发的高性能渲染引擎渲染引擎由三部分组成:动态表单渲染器、列表渲染器和动态交互解释器。他们可以各司其职,相互合作。渲染引擎的主要功能是将生成的DSL可视化翻译成具有功能逻辑和交互的页面、模板或组件。我们先来看看表单渲染器。众所周知,表单场景一直是前中后台最复杂的场景。通过自主研发的表单渲染引擎,提供表单数据管理、表单状态管理、动态渲染、组件联动等功能;基于JSONSchema驱动的分层架构,逻辑与UI框架解耦;通常,用户只需要了解胶层的几个API就可以快速上手;在复杂场景下,用户还可以通过扩展组件属性或者开发自己定义组件的方式来满足需求;另外,我们还将表单实例挂载到动态交互的上下文中,这样我们就可以轻松实现各个块级组件的联动和数据交互。特别是自研,完全是为了满足业务需求。开源社区中有很多优秀的动态解决方案,比如formily2、x-render、formast。他们都有自己的优点和缺点。我们也是权衡利弊后选择的。当然我们也借鉴了x-render的api设计和formast的动态语法表达。我们追求的是简单、易用、高性能和完全可控。让我们看一下列表渲染器。列表是前中后台的另一个非常重要的场景。为了满足各种列表需求,我们重新开发了功能丰富的开源列表库vxe-table。各种工具,Complextables,treetables,editingtables,virtualscrolling(ps:大数据在自定义渲染器场景下表现不好)都是天然的支持,我们额外内置了图片等15个常用的渲染场景和视频;和表单渲染器一样,列表渲染器仍然是基于json-schema驱动的分层架构,学习成本极低,扩展简单,也支持自定义渲染器;同样,我们也将列表实例挂载到动态交互的上下文中,实现与其他块级组件的联动和数据交互。说到列表,让我们谈谈图表。图表也可以理解为列表的另一种展示形式。有了列表的开发经验,图表也很容易实现。你只需要设计一个合理的DSL去编译然后发送给第三方即可。只是一个库(比如Echart),主要思路是和表单挂钩,表单驱动查询条件,执行异步查询,将获取的数据格式化后绑定到图表上。有了表单和列表,已经可以搭建简单的页面了,但是如何实现弹窗、按钮交互、接口请求呢?动态交互是前端低代码中最复杂也最有趣的部分,下面我们来揭开它的神秘面纱。如上图所示,由用户点击按钮发起,弹出表单弹窗,填写表单,发起接口请求,根据响应结果提示并刷新列表,其中一些是用户交互,有的是程序驱动的;我们通过这样一个动态交互的流程建模,可以抽象出流程源头和各个流程节点;当用户触发交互时,每个交互节点形成一个动态交互队列,有序执行。虽然实际情况可能更复杂,有异步的,也有分支的,但是我们也用不到30行的代码实现了整个动态交互驱动。我们将这个核心解决方案称为动态交互解释器,如下面的伪代码所示。同样,动态交互解释器也是基于JSONSchema驱动的分层架构。解释器只是一层胶水和一个内置的交互流程节点;执行器的主要功能是存储动态节点、传递动态上下文、解释和执行动态交互、流动或终止流程。在上一篇文章中,我们多次提到“将实例挂载到动态交互上下文”。就像伪代码中的ctx一样,这是一个响应式上下文。我们会根据不同的业务场景,有选择地挂载表单、列表、图表。实例和相关方法以及用户可能需要的其他重要数据,如路由信息、全局状态、应用信息等,以便各个流程节点实时访问实例并动态修改对应的实例,从而实现之间的联动块相互作用。动态交互式解释器还支持自定义。在极其复杂的场景下,我们可以通过添加自定义流程节点来扩展功能以满足需求。4.高效的可视化配置方案不同于其他低代码平台。在后羿,我们将页面视为资源,按照资源等级来管理和发布我们的配置。这样做有两个好处:第一,我们可以根据资源的层级关系设计不同的导航样式,可以是tab-history模式,breadcrumb模式,任何你能想到的菜单管理模式。二、资源管理与页面可视化配置解耦,管理更高效;如上图所示,除了可以随时拖拽调整菜单结构外,还可以一目了然地看到资源的详细信息;得益于这样的设计,我们提供了资源级的版本发布功能,可以实现一键迭代,在线热更新;基于V消息的工单版本管理,安全高效可追溯,还可实现秒级回滚。如上所示,我们还提供了模板和代码片段功能。模板侧重于同类型页面的复用,而代码片段侧重于组件和功能逻辑的复用。通过复用,可以大大缩短开发时间,5分钟构建页面不再只是纸上谈兵。在系统功能方面,我们提供一键打开常用水印、菜单搜索、消息通知等功能。我们还可以配置各类客服信息,方便系统级版本发布通知和日常值班维护。我们采用大家最习惯的从左到右的拖拽配置方式来配置页面内容。可视化配置方式,方便高效,实时拖拽即刻预览。动态交互还支持可视化配置,流程的运行逻辑在画布上一目了然,直观易维护。此外,我们还提供了一些贴心的功能:内置动态接口代理,一键开启后,可以连接本地或mock服务,开发调试非常方便;统一的服务配置入口,既符合开发直觉,又便于系统级的接口管理和复用,系统会根据不同的环境自动进行接口匹配。我们提供页面结构的大纲视图。只需点击图标即可快速定位组件,解决复杂页面查找组件的痛苦;在开发或者迭代的时候,页面的变化无法回溯也是一个痛点,所以我们内置了版本对比功能,只需将任意两个版本拖拽到对比框即可实现精准对比二、便于故障排除;每个版本还提供版本快速回滚,一键回滚。右键功能也是提高配置效率的法宝。基于右键,我们提供了组件的复制粘贴,可以跨块、跨页面、跨应用进行复制粘贴;右键也可以快速定位到组件的schema,修改schema实时同步到视图;还提供了基于右键的代码片段的保存和复用。得益于开发者平台的分层设计,自定义组件也可以按照编辑器协议进行配置,享受可视化配置能力。多层嵌套配置在可视化上是一个很蛋疼的场景,所以我们提供扁平化的配置方案,相比层层弹出的配置,配置更方便,切换成本更低。此外,我们对新手用户也非常友好。除了引导式配置,我们还提供字段级功能说明和文档指引,降低配置门槛。说到文档(如上图),这可能是很多低代码平台都会遇到的问题。我们认为一个好的文档一定是能够引导用户由浅入深的去学习平台的使用,否则会直接说服大量的用户,我们的用户主要是针对开发者的,前端、后台也是分开的-端、应用、AI、大数据等。要让各个岗位的学生都找到自己想要的解决方案,真的是一件很棘手的事情,所以我们由浅入深,层层递进,从简单到手把手教,深入到整个核心库的原理和实现,还提供了大量实例,包括数据联动、动态交互、布局等。5、千亿级内容交付效率,将直接影响用户的选择。后羿通过通用的CURD接口和动态可插拔的业务模块实现数据的存储和处理。用户操作完成后,统一进行数据处理和入库,通过独立的交付服务快速分发到各个业务系统。对于各种操作数据,我们会胡乱存储在MongoDB中;通过自定义仓库策略确保业务隔离和可扩展性;当然,还会涉及到数据的多级关联、自定义检索等,最终的精准分发,唯有加持。后羿平台承载着大量的业务数据。面对庞大的用户流量,必须保证交付的高可用。如图所示,我们在架构中使用了独立的镜像服务来承载各种大流量的服务,每个独立的服务都有本地缓存??、磁盘缓存、独立的Redis集群来保证单体服务的高可用。除了高可用之外,还必须能够支持高并发。目前我们的QPS在百万级别,每个请求可能关联查询数百个表单,最终会扩展到数千甚至万亿的表单查询。我们通过异步和并发的方式提高服务的吞吐量,结合异步监控、动态更新、定时重载来提升系统的性能;各种方法的支持,最终保证了服务的高并发。针对个性化业务需求,我们还支持对后羿提供的SDK进行二次扩展,与传统开发几乎无异。6.低代码如何与传统开发共存?低代码会取代程序员吗?低代码会扼杀传统开发吗?首先我们要明确一点,两者并不冲突!低代码不是灵丹妙药,传统开发具有可定制、灵活、无限制的天然优势,配套技术也相当成熟;因此,我们认为只有两者共存、相得益彰,才能发挥更大的价值。那么后羿是如何修炼的呢?一方面,我们不断丰富场景模型,提升扩展能力和配置效率;另一方面,底层架构设计兼容传统定制化开发;我们双向支持iframe和微应用,这意味着后羿制作的页面可以嵌入第三方应用,第三方应用也被接受嵌入后羿;支持页面级、块级、组件级嵌入。这样的设计既可以充分发挥传统开发的优势,又可以让现有的老旧应用利用它们的余热。通过简单的改造,就可以将它们集成到后羿中,然后在此基础上继续使用低代码能力进行维护;得益于后羿的菜单与页面内容分离的设计方案,我们可以在不破坏自身菜单管理系统的情况下轻松实现对第三方应用的兼容。在传统开发场景中,为了让大家专注于业务逻辑,我们开放了树懒的快速资源部署能力,并提供了各类工程脚手架,支持脚本命令的一键发布和迭代;此外,还支持素材托管,拥有独立的商务空间,安全便捷。以上就是后羿的低代码实战经验。这么短的篇幅不足以揭示后羿的全貌,对于low-code来说只是九牛一毛。我们利用现有的资源、服务、基础设施(基础设施真的很重要)以最小的成本孵化出了后羿低代码平台。其实能做的还有很多。我们会继续探索,让大家享受低代码的乐趣。
