2018年,业界都在聊中台,美团外卖也在尝试搞中台,当然外卖不叫中台,而是叫交易平台。
因为对于外卖也好,其他的到家商品(鲜花、药品)最终可以真正复用的,或者复用有价值的也就是交易履约这个环节了。
所以整个交易平台包括了常见履约环节涉及到的一系列内容。包括商品、订单、营销、支付、api、会员等业务。
因为多个业务都在一个平台下,很多解决方案有一定的类似性。
今天看完订单平台化的建设,其实脑中就会形成其他方向的平台化,毕竟在其他方向的方案上有很大一部分的类似性。
先整体看下,订单从一个小的系统,变成一个支撑整个美团到家交易订单平台的演进过程,可以看到每个阶段的关键能力变化。
促成订单平台化的关键原因,是因为到家bu战略上的万物到家。
于是催生了多品类和多业务,需要用现有的外卖搭建起来的平台做复用。
不同品类或不同业务,在能力上还是有差异的,但在骨干能力上有一定的相似,所以订单系统需要变成一个平台化的系统。
那我们先全局看下订单平台的整体架构。
目标上,是对于多业务、多品类通用的系统,并且对于差异化能力可以通过配置化的方式快速支持。
一个系统,唯一确定的就是变化。所以,系统要对变化低成本。
整个订单系统被分为五层。
最下层是基础设施层,主要对公司的一些基础中间件进行了封装,并且外卖具备了异地多活、SET化,所以这部分具备了多机房流量调度,数据同步,一致性等基础能力。
再上一层是基础服务层,按照领域组织了相关能力。我们知道订单是需要和多个系统衔接的,包括支付、营销、商品,合理的边界划分,有利于解耦,也有利于独立演进。每个领域又包含自己的核心能力,以及一些扩展能力。比如对于实物商品和虚拟商品,支付手段就会有差异,所以对应的领域之内,要有基础的核心能力,还要有对应的扩展能力。这种扩展能力被定义成扩展点。
再上一层是业务能力层,因为底层的域能力是原子的,是独立的,这一层简单来说,就是将多个域能力组合在一起,形成一个靠近于业务的另一种能力,其实是域能力的另一种翻译形式。举个例子,域能力可以不变,但对于C端用户侧和B端商家侧,其实会被不同的需求场景再组织,这就是这层的价值。
再上一层是业务流程层,底层可以认为是一个个的基础能力,基础能力包括标准能力和扩展能力,这些标准能力和扩展能力被有机的串联在一起,就形成了一个串行的流程。我们知道一个业务可以被抽象成一个个的流程,反过来这么多流程串在一起就可以形成一个新的业务。比如对于实物商品、虚拟商品,通过对不同域核心能力和扩展能力的组合,就可以定义成实物商品和虚拟商品的不同履约过程。手段主要是编排,不一定必须是可配置的配置化,低成本的编写代码也是一种编排。
最上层是业务层,就靠近一个个的具体前台业务了,因为不同前台业务使用底层基础能力,需要在业务逻辑层面或者数据逻辑层面做好隔离和调度。这里就定义出来了业务身份的概念。这一层业务有执行侧逻辑和运营侧逻辑,为提升运营效率和运营精细化,所以引入了很多配置化的手段。
实现这个理想态的平台化架构,有几个关键问题需要解决,比如如何定义业务身份,如果业务身份不是正交分解的,就不利于后续的发展。如何解决通用能力和扩展能力的集成和路由,如果没有很好的框架层面的支持,那在迭代和稳定性方面就会遇到比较大的挑战。
业务身份,在定义上有两个关键词:业务身份+业务标识。
业务身份是一个个独立的业务线,业务标识对应的是一个个业务线下的独立玩法。
业务身份定义每家都有一些异同,我觉得越简单越好。
比如我们如果不同业务已经是独立的微服务了,那么这个微服务下流动的数据就是这个业务的,也就不太容易出现一个服务实例流转不同业务的情况。
比如有些定义了三级,人货场,说实话这东西不太好维护,因为一个平台化系统的前端业务运营团队大概率不是一拨人,人的运营、货的运营、场的运营本身就具有很强的业务独立性,发展阶段和精细化程度也不一样,杂糅在一起,早晚会撞车。
所以我推荐业务身份定义尽量简单,这样才可执行,才可扩展。
接下来,我们再看下如何解决业务的通用性和扩展性问题。
我们先想下,一个业务既有通用性,又有扩展性,那么这个通用性和扩展性应该体现在哪里呢?
最开始想到的就是数据模型,业务的通用部分,就有确定下的数据结构,而有些差异化部分,就需要做差异化处理。
比如我们在数据库设计时,经常有一个所谓的extra字段,留有扩展性。比如http协议里,确定的是协议头部分,扩展部分放在了请求体部分。
所以在业务模型设计上,有类似的方法。将共享的部分进行固化,差异化部分用一些强扩展,弱刚性的数据结构承接,比如map、json。
最好在代码实现上,也对通用部分和扩展部分进行独立处理,一部分对固化的部分做crud,一部分服务于这种弱刚性的数据结构的crud。
同样的,不仅需要在代码上对于通用逻辑和扩展逻辑做不同实现。在整个架构层面也需要对通用逻辑和扩展逻辑做实现。
比如CQRS,就把读写分离这件事情,从简单的代码层面上升到了架构层面。
整个架构中,要首先基于通用能力进行搭建,自成一体。在这部分架构实现中,不要杂糅扩展能力的代码和设计。
这是非常重要的架构世界观,一定要有分离意识,简单的读写分离,核心与旁路分离,静态与动态分离,执行与运营分离,无状态与有状态分离,各种分离术你可以自己枚举出很多,这种通用与扩展分离也是其中的一种方式。
为了更好的实现分离,可以通过建立独立模块,甚至独立微服务的方式实现这种硬隔离,不然只是简单的两个类,说不定哪天就有一个同学把代码写错位置了,后面很多同学照猫画虎,就都搞错了。
扩展点不需要每个地方都出现,可以在域服务内和前台业务层定义与实现即可。
因为其他分层下理论上不应该感知到业务的差异性,其他层要提供的就是所有通用+差异的基础能力,被怎么差异化的用是业务层面的事情,某种程度也是一种分离术。
比如在通用和差异化可以枚举出很多的扩展性和个性化的逻辑点。
还需要考虑在一个业务身份遇到不同配置时的问题,这其实不算是个大问题,解法我也推荐比较简单的方式,我见过一些在做不同业务身份配置兼容处理的复杂方案,说实话是更底层的抽象设计没做好,而期望在上层解决这些问题,就有些本末倒置,陷入了一种战术层面忙碌,战略层面懒惰的境地。
我推荐简单的方式是:如果业务身份是xxx-yyy-zzz,先找这个业务身份。没找到就找xxx-yyy。如果再没找到,就找xxx。
有了这种设计原则,就可以指导一些配置化或者隔离扩展的实现了,而不是反过来,先做扩展隔离实现,再考虑将不同实现反过来兼容,这是一个判断力的体现。
举一个例子,不同业务限额的逻辑和规则不一样,有的是根据用户限制次数,有的是根据sku限制次数。
方法是,优先抽象出限额域,提供各种业务所需的具体实现的原子能力,比如判断限额、用户维度限额累加、sku维度限额累加。
这些能力优先基于通用能力实现,并且每个原子能力提供扩展点能力,基于不同业务身份做扩展实现。
这些扩展能力,都可以基于业务身份进行不同的编排与实现。
在编排方式上,其实业界已经有很多种实现了,因为这个ppt是19年的,所以当时的生态下,只有activity这一些类似的方案。但activity比较重,改造成本比较高,需要定制的比较多,自研反而更简单一些。
在编排实现上,业界也有两者方式,一种是托拉拽,一种是编码DSL。
我个人比较认可第二种,因为这种编排框架的主要目标用户还是研发,对于研发来说,DSL更友好,如果目标用户是产品运营,那拖拉拽这种类似于低代码的方式更合适一些。
而且DSL这种可以侵入到代码的编译期,更可靠更稳定一些。如果是ui配置的,需要做很多高可用、一致性、稳定性的基础建设。
扩展点隔离之后的收益,首先体现在稳定性上。
因为业务逻辑和数据都做了业务身份的隔离,就不会出现改了一个逻辑影响到其他业务身份的情况。
总结一下,一个平台化系统,主要考虑两条线。
底线是稳定性,上限是可扩展。
通用性+业务身份隔离,实现了稳定性。
扩展点+配置化,实现了低成本扩展。
一个新业务接入订单平台大概过程是:
平台配置业务身份->根据具体需求判断复用通用能力,还是建立新扩展点->通过编码的方式(XML、JSON、DSL)方式进行逻辑流程的编排。
至此,一个标准的平台化系统架构的演进的全貌及细节就展现在了我们面前。
那未来还有什么需要做的呢?
所有业务系统架构都是为业务规模化服务的,背后的关键要素就是效率、成本、安全、周期。
围绕于效率,可以在对接效率,知识传递效率,协作效率上做文章。
效率提升了,研发成本和周期就降低了。
有了足够多知识和技术资产的积累,变更带来的稳定性风险也就降低了。
交易平台其他的平台化系统,比如营销配置化系统,商品配置化系统,供应链配置化系统,其实建设方案是类似的。原则和关键词是可以借鉴的。
希望对你有用。