三方系统集成(低代码)平台实践
作者:vivo IT 平台团队- Wang Qin
本文从作者实际痛点出发,到产生愿景,最后再到落地的全过程,并结合实例案例,介绍了一些核心设计思路,希望读者阅读后对 vivo 分销业务,能有一些了解,也希望能对读者在应用的认证鉴权、流程编排、低代码等方面有所启发。
一、背景和痛点
本文首先对 vivo 分销业务系统(简称 V-Work,V-Work 是分销系统的 Portal,非 1 个系统)做个简单的介绍,V-Work 作为 vivo 手机/智能终端等全系产品的分销系统,覆盖了全球范围线上/线下的供应和销售网。
线下业务:主要支撑各省市代理,以及下属零售商,零售商下的门店,门店到消费者的货物流和财务流,这些业务的操作入口一般直接在 V-Work 页面发起。
线上业务:核心是通过对接各类 B2C 平台、O2O 平台、政企平台、运营商系统等,将订单同步到 V-Work 进行履约,通过调度自有 WMS、三方 WMS、三方 TMS 进行仓库作业和物流发货,同时返回发货的信息给到各类下单系统。
全球部署:V-Work 共部署了 4 套集群(分别是国内机房、海外 1 机房、海外 2 机房、海外 3 机房),服务于全球用户。
类似很多互联网公司系统的迭代,V-Work 系统经历过的架构演进:
单体架构: 2022 年前 V-Work 是有多个包括订单、履约、库存、策略模块的独立单体系统。
微服务架构: 2022 年开始进行了系统架构升级,将通用模块进行了抽取,形成了独立的服务,避免了重复造轮子的问题,目前整个架构升级工作还在持续进行中。

随着 V-Work 承接的业务场景越来越多(订单业务从线下分销拓展到线上电商平台+运营商平台等,仓储物流从 vivo 内部的代理 wms 拓展为支撑各个区域的承运仓),导致对接的三方系统也呈现陡增之势,在系统迭代过程期间,主要遇到了以下几个问题:
V-Work 履约流程相对是固定的,但每对接一个三方平台时,都要开发一套适配代码, 这种硬编码的方式效率不高。
从代码提交到可用时间慢,特别在联调和测试环节,因需转换的内容繁琐,转换的字段较多,很容易出现错误,这个时候要经过代码调整、提交,DEVOPS 流水线,应用启动,才最终可用,而不能即时生效。
三方集成的代码,对开发能力本身的要求不高,但因为是硬编码,所以还是需要开发人员,投入产出比不高。
不同三方系统,因会抽象出一些公共代码,这个时候就有可能出现比如改了抖音对接的公共代码,影响了其它平台。
每次对接一个平台,都要开发一套针对该平台的授权代码,定制开发导致效率低。
日志运维功能定制化,因每个平台的接口字段不同,导致日志的记录和展示等运维功能都是定制开发,成本较高。
透过问题的表面看本质,在有了多个三方平台集成的前车之鉴后,我开始反思能否针对当前的各种能力可以进行总结和抽象,最终形成一套配置化平台,即产生了一开始的三方系统集成平台,当初只是想解决 vivo 内部系统和 vivo 外部系统的集成,让内部业务系统开发人员仅需专注自身业务的开发,而不 care 外部的接口定义,能提升研发效率,来快速支撑业务的交付。
当三方集成平台成功上线,并经过 2 个月的推广后,很快发现他的应用场景不止能支持内外部系统的集成,内部系统之间的集成也很适合,比如结算中心和 ERP 的对接,2 个系统都具有各自的业务模型,结算需要把过账数据推给 ERP 系统进行财务结算,就涉及到数据的转换和适配,本平台也是较好的应用场景。
所以最终将本平台命名为通用集成平台(Common Integration Platform),简称 CIP,给他的定位是:适合多个核心业务系统直接进行对接,业务系统只需关注自身业务,通过本平台进行适配和桥接,可作为当前的适配系统、前置系统、业务网关系统,甚至渠道系统的配置化替代解决方案。
二、整体架构
2.1 架构目标
1.100%配置化(低代码)
要完成一次有实际意义的系统间的集成,肯定不止会有源系统和目标系统参与,期间还会涉及其它系统的参与,即会存在多个系统的多个接口协同完成一次业务流程,那就需要有编排和串联系统和接口的能力,这种能力采用配置化的解决方案进行落地,力争达到低代码化。
配置数据的存储上,常见的有 XML 和 JSON 两种格式,考虑到使用习惯和灵活性,最终选择了 JSON 作为配置元数据的存储格式。
站在平台建设角度,要做到这一点,最考验的是过往经验,以及对经验的归纳总结,然后抽象的能力,同时要有对可能变化点的识别能力,即对不确定的方面,要留好扩展性,这样才能建设一个健康稳定发展的平台。
2. 自助式接入
这里自助式有 2 个层面的含义:
第一层:指的是可以由业务团队自行配置和调试,而不限于必须是 CIP 平台的人员,比如 V-Work 也会对接多个三方仓储系统,去提高我们的履约时效,就会涉及 V-Work 和顺丰 WMS、京东宙斯、EMS CTL 的对接,那完全可以由 V-Work 中履约模块的人员在本平台完成配置和调试。
第二层:配置化+可视化可以降低使用者的门槛,类似一名 HR 在 OA 系统给员工办理入职那样简单,只要简单培训,即可上手,目标是运维、产品、测试、甚至业务都可以轻松在本平台上进行操作,完成业务实施。
3. 开发效率提升
通过对相似的事物进行抽象,抽象成各个具有独自特性的积木,同时将变化的东西看作是数据,而非代码本身,可灵活支撑各业务的个性化需求,提高开发效率,降低人力成本。
4. 隔离性
物理隔离:通过部署多套集群,可以让项目之间做到物理隔离,比如“抖音对接项目”不会影响“顺丰 WMS 对接项目”(可以见后文的部署架构)。
逻辑隔离:不像传统的硬编码方式,因系统对接之间会复用某些代码,导致相互影响,本平台配置管理上天然就具有隔离性,通过项目和项目之间,项目下的流程之间,都是可独立配置,不会影响到其它项目和任务流,实现了逻辑上的隔离,即真正做到了不同的需求的应用之间集成,不会相互影响。
5. 配置即时生效
配置完能立即生效,而不需要经过代码提交,分支合并,持续交付流水线,应用启动的等待时间,也不会因为发布应用导致的服务不可用(现在 V-Work 做不到完全无损部署)。
2.2 系统架构

核心概念解释:应用、触发器、执行器、连接器、项目、任务流:
(1)“应用、触发器、执行器、连接器”:属于静态配置,只需配置一次,就可以在多个“任务流”中被引用。
应用:和我们的微服务是一一对应的,一个微服务维护成一个应用。
触发器:流程中的首节点,流程中的触发节点,一个任务流只能含有一个触发器。
执行器:流程中的非首个节点,即首节点后面的所有节点都属于执行器,一个任务流可以包括多个执行器。
连接器:是一种特殊的触发器或执行器,正常触发器和执行器通过配置完成,而连接器是需要预先进行定制开发。
(2)“项目、任务流”:属于动态配置,每一次项目的实施都是不同的配置。
项目:用于组织完成一次需求的实施,可包括多个任务流。
任务流:用于串联触发器、连接器和执行器且带有方向的一条流程任务。

三方系统集成场景,包括三层架构:
上层是外部三方系统,目前 V-Work 对接的三方系统主要包括:国内和海外的主流电商平台、O2O 平台、三大运营商系统,以及 V-Work 线下代理公司系统的集成。
中层由开放平台和 CIP 平台组成:开放平台主要对外提供了网关功能,包括统一的鉴权和限流方案。
底层是 V-Work 内的多个系统组成。

部署架构重点支持了不同项目的物理隔离,当前 CIP 部署架构:
CIP-CORE:主集群(包括电商、政企、代理赋能等业务)。
CIP-CPC:工厂业务集群(包括 vivo 的制造和供应域的各类系统)。
CIP-WMS:仓储和物流业务集群(包括各类 WMS 和 TMS 系统)。
CIP-Finance:财务业务集群(ERP 和三方财务系统)。
CIP-ADMIN:服务于以上 CIP-CORE、CIP-CPC 等的控制台,处理非核心功能,与核心功能分离。
三、关键设计
3.1 内置常见接口授权方法

以下用最常见的 2 种授权方式(hmac 和 oAuth2)举例说明
(1)hmac 授权
加签方式定义:
语法定义:
key-values:要加签的业务字段的字段名和字段值
start:待加签串的起始额外内容
end:待加签串的结尾额外内容
connector:多个业务字段的连接符
signType:加签的加密类型
target:业务字段名和字段值的连接符
exclude:要过滤的业务字段
extra:扩展配置
① “innerFormat”=false //嵌套对象是否格式化,默认 true
② “innerSort”=false //嵌套对象是否参与排序,默认 true
③ “salt”=”qbc12” //hmac 加盐
④“innerExcludeKey”=true ,“outerExcludeKey”=true //是否过滤字段 key,默认 false
⑤resultType=base64/hex //返回的数据格式
(2)oAuth2 授权
仅需 2 步就可配置一个 oAuth2 授权类型系统的集成。
第一步:接口授权配置,以下以 tiktok 举例:
第二步:点击 CIP 分配的 URL:https://xxx.vivo.xyz/app/auth?project=ina-vk&app=douyin&shopId=sfdsa3t8fds,会跳转到 tiktok 登录页面,输入用户名和密码,即完成整个 oAuth2 授权流程,并且在 token 失效之前,CIP 会定时进行检查,在后台进行 token 刷新。
CIP 数据库会有这样一条数据,为后续业务接口调用提供授权相关的信息:
3.2. 支持流程编排
一次数据传输定义为“任务流”,我们需要控制节点的执行顺序,支持逻辑转换和数据补全,逻辑转换比如时间的转换,外部电商的时间格式有很多种,我们需要转换成一种标准的格式,推到内部系统,数据补齐一般只是的是拉到外部数据后,会通过查询主数据去补充信息,转换成标准的数据格式,推到内部系统。
以下用 V-Work 中 tiktok 退款状态查询功能举例:
3.3 内置数据池存取方法,支持流程中节点对数据池共享访问
任务流中每个节点的执行,即系统接口的方法调用,都会有输入输出参数,CIP 会把每个节点的执行数据存储到流程数据池中,这样后续的节点,就可以对数据池数据进行访问,从而获取前面节点的执行数据,保证本节点能正常执行。当前定义了 4 种变量引用的方法:
接口输入字段:{# ih.xxx #}、{# ib.xxx #} 、{# ip.xxx #} 、ih = input-header,ib = input-body,ip = input-param ,当前请求执行关联的输入字段。
接口输出字段:{# oh.xxx #}、{# ob.xxx #} 、oh = output-header,ob = output-body,当前请求执行关联的输出字段。
项目授权账号:{# ad.xxx #},ad = auth-data,当前请求执行关联的授权账号和 token 信息。
项目常量:{# pc.xxx #} ,pc = project-constant。
以 ib 举例:ib 表示从当前节点获取数据、ib3 表示从别名为 3 的节点获取数据;ib.order.orderId 表示获取 ib 的 order 对象的 orderId 字段值、ib.order 表示获取 ib 的 order 对象、ib 表示获取 ib 的所有字段值、ib[0]表示获取 ib 列表中的第 1 条数据。
3.4 支持远程 dubbo 方法、本地方法、MQ、HTTP 配置调用
具体看下每种调用类型的配置方法。
(1)Dubbo 方法
本地方法和 RPC 类似,主要用在对电商平台 SDK 的调用场景。
(2)HTTP
(3)MQ
3.5 支持分支、循环、合并、webhook、数据存储和文件存储
这些内置的能力,我们定义为“连接器”,可作为任务流配置的节点,同触发器、执行器配合,共同完成多个系统之间的集成,当前定义了以下几种类型的连接器:

3.6 内置 EL 表达式语言
表达式引擎并没有选择自研,主要是因为市面上有成熟好用的规则引擎,没必要重复造轮子,调研了几个规则引擎框架,最终选择了 QLExpress 作为基础引擎,在它基础之上,根据实际业务,进行扩展开发,CIP 扩展的表达式,主要包括以下几大类:

3.7 异步流程执行
同步任务指的就是遇到比较多的场景,系统集成实时返回结果。还有一种我们称之为异步任务,比如仓库出库结果,同步外部系统场景,履约系统抛出的是 MQ 出库结果消息,这个时候我们就要先接收下来,不能阻塞 MQ,然后异步的将 MQ 消息转换适配后,推给外部对接系统。
异步任务可能出现在任何节点,都有可能:
针对 MQ 类型的触发流程,那任务流的第一个接口执行完成后,就需要 commit,然后异步从第 2 个节点开始执行。
外部推送的一些同步数据,先进行初步校验,校验通过后,就需要返回成功给外围,这时候可能已经执行了比如 3 个节点,那后续异步执行就要从第 4 个节点开始。
即可以指定任何节点开始重试,但目前我们只有可能在第 1 个节点后和最后 1 个节点异步执行,所以限制 node=first/last。
异步任务必须要具备重试的能力,所以需要能够指定重试次数和重试间隔:“count": 3,“interval": “1/2/3”。
3.8 错误机制
关于任务流(即某个系统间的集成任务)执行失败的控制机制,站在简化任务流配置方面考虑,即任务流中每个节点执行成功失败的判断,并没有放在任务流中通过分支条件去控制,我认为任务流的核心关注点是指定参与节点,节点主要指的是操作了某系统的某个方法,而不是有很多的判断配置,降低了任务流的可读性。当前错误码可以在 2 个层级进行定义:
应用层级:它的适用范围比较广,可影响本应用下的所有触发器和执行器。
节点层级:仅影响某个触发器或者执行器。
目前遇到了 2 种返回情况,第一种是直接通过 http 的状态码,第二种是 HTTP 状态码为 200,通过 JSON 数据返回,这种情况更常见。节点成功判断规则:
配了执行器的 httpSuccess 和 success,只看执行器配置,否则看应用的 httpSuccess 和 success。
httpSuccess 和 success 判断规则:
① httpSuccess 和 success 都没配:如果 http 的 status code 为 2XX,就认为成功,否则失败。
② 只配 httpSuccess:以 httpSuccess 为准。
③ 只配 success:如果 http 的 status code 为 2XX,再与 success 进行比较,否则失败。
④ httpSuccess 和 success 同时配:必须同时满足。
四、应用
从 2024 年 2 月份提出创意开始,并经过三四个月的规划,设计和开发后,最终现在已经推广半年多的时间里,当前已经能覆盖 vivo 分销的主要应用场景,使用数据情况:覆盖 vivo 分销核心业务场景(仓储管理系统对接执行订单出入库作业、财务系统对接完成结算过账、电商平台对接实现销售订单履约、分销商系统对接实现交易数据的共享等)、50+系统、25 个项目、300+的集成场景、日调用量 10 万级,较正常开发预计节省人力 50%以上。
五、总结和展望
本文从作者实际痛点出发,到产生愿景,最后再到落地的全过程,并结合实例案例,介绍了一些核心设计思路,希望读者阅读后对 vivo 分销业务,能有一些了解,也希望能对读者在应用的认证鉴权、流程编排、低代码等方面有所启发。
站在本平台规划起初的目标上,已经算基本完成了目标,但如果想进一步在部门或者公司层面进行推广,我们还需要进一步提高平台可视化和易操作性,因为当前可视化功能,还没有把配置语义转换成业务语义,而是直接把里面存储的语法暴露给开发人员去配置,最终目标是系统集成的开发,能够转化为系统集成的数据管理,暴露给不懂开发的人员去配置,这是未来要重点提升的方面。
版权声明: 本文为 InfoQ 作者【vivo互联网技术】的原创文章。
原文链接:【http://xie.infoq.cn/article/c24e55afc59ba869f5cd5005d】。文章转载请联系作者。
评论