代销是 vivo 商城已经落地的成熟业务,本文提供给各位读者 vivo 商城代销业务中两个异构系统业务融合的对接经验和架构思路。
一、业务背景
近两年,内销商城业务的发展十分迅速,vivo 商城系统的架构也完成了从单体往分布式的演进。我们在 vivo 商城服务化方向做了很多的努力,基础服务的能力逐渐沉淀下来。
2019年我们也开始在产品功能上玩起了多元化的营销业务。目前手机品类仍是我们销售的主力,但是非手机品类的sku单品数量还是很少,巧妇难为无米之炊。
为了解决非手机品类商品丰富度问题,运营考虑和电商平台进行合作,希望用代销的方式为商城扩充更多的非手机类商品品类。
先跟大家解释下“采销”和“代销”的区别,简单来讲就是一个货权归属的问题,采销是买货到我们仓库进行售卖,可*定价;代销是货权归属于平台方,也就是货还放在对方的仓库,用“以销定采”的方式进行售卖,有利润空间,但是自主定价受限。
所以代销业务一开始就带着明确的目标出发了,我们希望通过接入其他的电商平台能够做到以下几点:
- 改变商品品类匮乏的现状,品类变多能进一步丰富促销玩法;
- 提升运营效率,解决代销类商品从选品到商城上架周期过长的痛点。
二、平台选择
一开始选择了几个平台方,为了提升选择效率,我们先对平台方定了几个重要的参考指标,目的是要能过滤存在对接风险的平台。
对接参考指标:
- 【文档清晰】必须要有完整的API文档,文档逻辑要清晰,不能模棱两可;
- 【接口完备】至少具备满足全流程的数据同步接口(能实现数据的全量和增量)、异步通知(商品变更、订单状态流转等异步变更)等;
- 【商品模型】提供的商品模型要结构化。例:遇到sku信息采用内嵌html的方式,尝试用Demo预研后,效果很差;
- 【成功案例】这个具有非常重要的参考作用。一般在对方的站点上都会宣传一些成功案例,可以去体验下,因为很大可能最终接入的效果会和他们一样;
- 【沟通机制】健全的沟通机制也很重要(刚开始我们没有重点考虑,导致对接过程沟通还是不太通畅)。
但是参考指标只能作为一个筛选器排除不能对接的。剩下的平台方,需要我们从技术和产品的角度进行深度的调研分析,预研期间也主动和各个平台方电话沟通了几次,最终我们挑了一个各个方面都比较合适的候选人“网易严选”。
三、挑战
这次对接任务是通过对方提供的API接口,把他们的商品同步过来在我们商城进行售卖。
我们要求的是商城能正常地展示,用户能正常的下单并支付,同时支持逆向的用户取消订单,退款退货等等。
但是外部系统的对接存在很多的风险,尤其是非公司的第三方异构系统,而且对接的是包含商品、订单的全流程,我们要面对很多的挑战。
1. 未知挑战
- 首先要考虑商品数据能不能完美地融合进来?
- 其次订单的正逆向流程能不能打通?
- 对方是否有环境能够测试验证?生产环境接入有没有过多的限制?安全性如何保证?
- 对方能不能及时、准确地解决我们遇到的问题?
2. 前期预研
为了保证全流程完整接入的可控,我们先和对方沟通了测试环境配置,尝试调通他们的接口。
紧接着我们开发人员分成了两批,一批尝试通过手工组装字段把对方商品接入vivo商城,一批预研订单正逆向的全流程,这次我们尝试接入的目的很明确“打通全流程”。
3. 预研结果
最终通过使用 Demo 拉取对方报文,手工组装数据,快速试错,实验结果和前期预研的一样,通过实践证明全流程确实可行,链路能打通!实验结果让大家信心大增,也预示着我们可以整装待发,正式踏上代销系统的架构之路了。
四、代销业务的设计
1. 开篇
在正式设计之前,我们需要对新系统有点畅想,因为我们不仅仅只是完成这次对接的任务,我们更希望它拥有更抽象的业务功能,具备一定的扩展能力。
架构代销平台的意义:
- 对接外部系统,提升我们自身的系统架构、设计的能力;
- 填补代销的空白,未来我们希望这个平台能够达到快速对接的目的;
- 积累一定的经验,未来定制我们自己的标准API,低门槛接入品质好的第三方。
2. 系统设计
我们把系统简单地归类,划分成了三部分,从左往右分别是平台方 → 代销平台 → 商城内部系统。
代销系统整体的设计的思路有点类似API网关,但在细节方面又有很多不同,代销系统的设计还是整体偏业务实现,也提供了额外的平台方信息的查询服务供内部系统调用。
2.1 平台方系统
对我们来说是个黑盒,他们的系统设计、数据交互我们是无法得知的,不过如果仔细研读文档的话,也能从他们提供的API中窥探一二,但是相比于对方的设计我们更需要把精力花在和他们的沟通和环境联调上。
2.2 代销平台
是这次设计的重点,它承接着外部和内部系统,是系统交互的重要纽带。目前摆在我们面前的还是一张白纸,我们需要先梳理下所有的基础功能,把它的框架先搭建出来。
为此,我们制定了简单的设计原则“无侵入,对内屏蔽掉底层适配的细节,关注服务本身,并具备一定的业务抽象和扩展能力”。然后在此设计原则基础上我们做如下比较精心的设计:
模块化设计
对接严选之后,再对接其它平台方的话。我们希望各个平台分成模块化进行对接。保证各接入方之间业务完全隔离,互不侵入。
能够做到可插拔,如遇到合作终止的情况,能以最小的成本关闭对接通道。
路由层
- 商城内部系统发过来的报文/请求能识别并路由到对应的平台模块中处理。
- 平台方回调的报文能够准确解析并路由到模块中去。
适配层
- 来自于适配模式(Adapter Pattern),适配能力是整个系统横向的核心能力。
- 模块化设计之后,各个对接的平台都会具备独立的适配层。
- 商城 ↔ 平台方的商品和订单维度的字段映射。
- 持久化双方的主键映射关系,如:<vivoSpuId, YxSpuId>,<vivoOrderId, YxOrderId>。
服务暴露
- 提供映射关系查询,如:商品spuId、订单关联关系映射。
- 提供对账信息查询。
- 提供平台方冗余信息查询,如:平台方更丰富的商品信息。
统一回调
- 开放外网访问接口,提供接口给平台方进行消息的异步回调。
- 建立访问白名单,接收并将消息通过路由层分发到各平台模块进行处理。
- 异步回调的消息包含:商品信息变更、库存预警&校准、订单状态流转等。
统一配置
- 利用配置中心统一管理各平台方对接账号、秘钥等信息。
- 系统监控指标阈值、告警、开关等。
横向能力
- 接口调用异常监控、业务异常告警等。
- HTTP底层通信服务。
2.3 内部系统
2.3.1 商品中心
【高可用】
之前对外提供的都是高QPS的只读Dubbo接口,这次要开Dubbo写接口提供给代销系统来创建商品。
了解接口设计的小伙伴都比较了解,写接口最主要的是保证事务的同时要能做到防刷防重。为此我们在写接口上加了统一验签(内部系统弱校验)和接口幂等性设计。
【接口设计】
大家平时在浏览电商网站的时候,商详页呈现出来的内容是十分丰富的,这也间接说明了商品的模型本身还是比较复杂的,所以在设计商品写接口的时候,开发内部产生了争论,讨论出了两个方案。
方案一:部分开发认为应该按现在的商品模型,把接口打散,代销平台对接多个写接口,好处是局部更新比较方便,也避免一次性提交一个大事务;
方案二:另一波同学认为就应该是一个接口,否则会出现接口散乱、乱序的情况。
最终我们还是采纳一次性提交的方案二,虽然会有大事务的风险,但是可以通过代码层面来缓解,而且架构设计本身就是一种权衡,设计接口的时候还是要多站在调用方的角度,对方肯定不会希望服务方的接口是散乱、无序的,这会增加调用和维护的成本。
2.3.2 订单中心
【正逆向的流程】
订单的难题最主要还是双方流程的融合,所以我们针对代销逻辑做了部分的流程改造。
这边只给大家举一个下单的例子,严选提供的创建订单API实际上包含的是下单+支付两个动作,为了适配他们的流程,我们做了点改造。
当用户在商城下完订单之后,代销系统仅对接严选做库存和配送区域的校验,确保订单能下成功。等用户在商城侧支付完成后,代销再次发起创建订单的请求给到严选。如果遇到创建异常(从数据上看很少几乎没有),我们也会有自动的取消流程。
3. 严选对接逻辑
上面的设计确定了各个模块的功能,划分了业务的边界,让我们看清了整体的骨架和脉络。但是我们还需要画一张切实可行的调用关系图,让整块逻辑立体丰满起来,最终让每个开发都知道这次网易严选该怎么去对接。
五、呈现效果
代销商品覆盖了官网商城列表页、活动频道页、选购页,展示效果如下:
六、展望未来
我们在前期也遇到有些品类比较好的平台方,但是由于技术原因无法和我们系统完成对接,也挺遗憾的。未来我们希望代销平台也能自己制定一套API标准,对方按照我们的标准,自己开发接口把数据传给我们就行了,这样就少了很多沟通和接入的成本。
作者:vivo官网商城开发团队