在开始下面的话题之前,我们先看一看有赞原有的核心交易架构。
初步看去,这套架构方案似乎看不出什么问题。事实情况也这样,我们做这套交易方案支持了日百万级的交易规模,取得了很不错的成果。
在2016年,公司经历了飞速的成长, 整体团队人员扩张了数倍, 公司整体业务线从单一的微商城电商交易型态扩张到支持多个垂直行业。交易团队也碰到了很多尴尬的情况:
垂直行业接入交易很困难,交易团队对于业务团队的支撑响应速度赶不上业务的迭代速度,最后垂直行业被迫自己完全重做了一套针对垂直业务的交易系统。比如:商业化服务订购,收营,批发等业务。浪费了公司宝贵的技术资源。
交易团队的新同学,上手交易核心的开发非常困难,在没有完合弄懂整套系统之间,不敢放手让新同学开发。学习成本极高。
很多的玩法不能进行组合,如果想进行组合,必须要求进行重新编码,把组合的方案当做一个新方案来做。比如:虚拟商品的拼团业务, 酒店的分销业务,等等, 都不能用很简单的方案做支持。 产品运营同学的创造性想法,得不到很快的支持。
上线了一个小需求,导致的主流的核心交易大面积出现故障。影响范围不能进行隔离。
我们的困难根源
在此之前,我们先看一看公司对于交易团队的要求,以及业务团队对于交易能力的诉求。
从上图中,可以看到,从业务团队的视角上来看,交易能力,其实是一种云化能力。不管是什么样的业务场景,只要交易场景存在,那么交易能力就应该能覆盖。换句话说,交易团队存在的价值,就是”能够很快速地支持所有业务的交易“。
这个时候稍微清晰了一点当前的困难的原因:原来的我们,一直是在做微商城的业务,认为”微商城的业务规则=交易的能力“。这个定位与垂直业务的期望很不匹配。
既然”微商城的交易规则“不等于”交易能力“,那么交易能力是什么? 有什么内容?与垂直业务又有什么关系?
这三个是很有意思的问题。 在弄明白这三个问题之前,我们先把我们从一个互联网从业者的角色,转变成一个普通的人。假设我们要去做三件事情,我们看一看现实生活的交易细节:
我要去路边摊买一斤瓜子。
“老板,多少钱一斤瓜子” 。“12元一斤奶油的” 。“给我称一斤”。 然后老板给我称了一斤,我付钱, 拿瓜子,走人。
我要去楼下吃一碗面。
“老板,热干面多少钱一碗” 。“15元一碗”。“给我来一碗” 。然后我坐下, 吃完面,付钱, 走人。
我要去售楼处,买一套期房。
这个场景就更复杂了,我需要先看房周边的环境,看价格,然后弄清楚开发商的承诺, 然后,找售楼小姐聊价格,拿合同,签字, 付现金首付,然后找银行贷款付完余下的钱。 待房子开发完之后,再找开发商确认收房。最后整个交易才算完毕。(PS:如果房子跟原来说的面积不一致,还需要补款。如果差距太大,还要房闹退款等)。
上面例子,都很平常。但是平常的事情,蕴含着几千年的交易规律。我们仔细品味一下上面的细节,发现从大到小的交易,有几个共同的点:
交易必须有买卖双方。
在初期,买卖双方必须达成一致(如何付钱,如何交货)。达不成一致,就不存在交易。(契约)
达到一致之后,买方付钱,卖家交货。PS:可能是先交货,再付钱。也可能是多次付钱。也可能是多次交货。
只有买卖双方达不成一致,才存在交易退款维权的情况,包括售后服务。
从理论上来说, 线上系统处理的也是真实世界的问题, 只是手段略有不同。我们再回顾一下自己平常碰到过的交易场景,都逃不出这个范畴。 我们完全有理由把这个结论当成线上交易系统的指导思想。我们对于交易系统的抽象理解就是: 交易的本质是:买卖双方就付款细节/交货细节/商品质量细节/赔偿细节,先签定一个契约。而后双方履行契约的全过程。订单仅仅表示双方履约的过程和凭证。
我们看一下新交易的最骨干的模型。
破局之道
搞明白了我们的核心问题, 那么很多事情就迎刃而解了。
快速接入问题:如果我们的交易核心是稳定的,不是给某个业务定制的,那么只要是契约精神可以解决的问题,就应该是交易系统能解决的问题。业务系统只需要做一些适配,就可以无缝接入。接入速度会极大提升。
搞定小需求,影响主流交易的问题:这个是原系统在代码组织层面,只要做好隔离,就可以解决的。
新人学习成本高的问题: 同理,交易的核心是稳定的,不需要关心太多的业务上的问题,理解成本就会极大的降低。新人接手速度会提升。
玩法不能组合的问题:这个问题同样是原设计上的一些缺陷,没有区分横向业务,跟垂直交易。PS:这个会在后面阐述。
要根治交易系统当前碰到的困局,除了重构之外,没有别的捷径可走。
架构演进
在进行本章节的讲解之前,我们再回顾一下,上面讲的三个生活中的交易场景,我们继续仔细品味一下,三个交易场景的细节点,突然有了一个惊人的发现:
如何付钱是标准化程度很高。在日常生活中,付现金/刷卡/三方支付, 可以覆盖大部分的场景。
跟卖家商量,签定契约的过程,标准化程度稍低点。但是,似乎一个行业一个标准。但是都没有逃出,“如何付钱,如何交货,售后保障约束,以及如何违约赔付”的范畴。
如何交货,是标准化程度是最低的。每个场景似乎都不一样。就算是同样行业的不同的店也可能略有不同。PS:比如一顿饭,可以上门吃然后饭馆准备餐具,也可以是送货上门自己吃。
整条交易的流程,是最不可控的,每个阶段的过程,可能是乱序的。PS:比如去餐馆吃饭,可能先付钱再吃饭,也可能是先吃饭再付钱。
弄明白这些特性,直接决定了,我们跟垂直行业的关系。即:什么东西应该交给垂直行业,什么东西,交易系统应该搞定。
以下的新交易的架构大图:
在上图中,明显出现了几个原来没有出现过的一些名词。我们做一下解释:
buy: 业务的buy,由垂直业务掌控,它不一定是一个独立系统, 它的核心使命是包装交易平台提供的各种能力,根据垂直业务规则,做定制。例如,美业的理发业务调用下单接口的时候,可能要做预约时间的选择,buy系统需要做一下这方面的校验与参数拼装。另外,垂直业务的交易确认页面,也是有不同的显示规则,这个需要buy系统做支持。
流程编排引擎:这个是整个新交易的核心思想。业务规则是通过配置化形成的。流程配置化的最小颗粒度是组件。引擎把所有的组件形成一个串,执行业务规则。流程编排引擎的配置规则,是DB中的数据,可以随时添加数据。 所以这个引擎的设计,对于快速支持新的业务形态,起了至关重要的作用。
交货/退货路由引擎:对于交易系统来说,所有的交货/退货过程,都可以看成黑盒子。只要知道路由引擎会把相应的交货过程做掉就可以的。原因是:我们认为交货是一个不可归纳的行为。交货的细节,是需要交还给垂直业务自己去做的。
组件:对于流程中所有元素来说, 所有的东西都是组件,都可以纳入到流程编排的范围之内。如:扣库存组件,校验用户合法性组件,校验地址可达性组件,进入支付组件等等。
对于上面的解释,可能还有三个问题核心未回答:
1. 既然是通过流程编排来配置出一个业务流程,那么,如何定位到一个业务?
行业维度(酒店预订,普通实物交易,外卖,虚拟交易,批发,美业等)
商品类型维度(酒店商品,普通实物商品,会员卡商品,二维码核销商品等等)
营销维度(积分商城,拼团,秒杀,老拼团,普通营销/无营销,等)
交货方式维度(上门自提,快递,同城送,二维码核销,酒店入住,会员卡授权等)
付款方式维度(线上付,代付,货到付款,线下收银等)
2. 交易的核心流程阶段与主模型数据模拟是怎么样的?
横向业务与垂直业务
垂直业务:垂直业务就是我们要支持的业务场景,如“微商城的普通商品拼团的业务”。
横向业务:各种横向业务通过一定规则相互拼装,可以形成垂直业务。在新交易里,横向业务被包装成一个一个的组件,可以通过流程编排的形式串成垂直业务。如:拼团组件。
实施路径
交易是非常核心的系统,新交易系统的上线流程,无异于飞行中换发动机,难度可想而知。我们把实施路径定为以下几个阶段:
1. 正向交易优先启动重构,用新的模型做业务支持。
正向交易实行双写策略,即新模型写一份,再同步写到老模型数据一份。为了不影响外围系统。
上线时,优先灰度内部商户,而后小商户,最后大商户的原则。
上线后,通知外围业务,做消息机制的改造。
优先支持新业务,然后灰度老业务的原则。
2. 订单管理启动重构,在正向交易做完全量切流程之后,再做灰度上线。
订单管理的同步策略,不再依赖DB做数据的导出/查询业务的存储介质。采用宽表的一些介质,做到dump可配置化,导出可配置化。通过这样的方式,一次性丢弃老的数据模型,同时获到业务配置化能力。如ES、HBase。
3. 逆向交易启动重构, 在正向交易做完全量切流程之后,再做灰度上线。遵循逆向交易流程配置化的原则。
4. 等到逆向交易与订单管理做完全量分流之后, 再停用双写策略(原有的老模型自然全量失效)。