有一个事情已经困扰我很久了——大中台、小前台作为战略已经提出很久了,在业界也掀起了不小的波澜,可是反观阿里的业务中台,为什么总觉得旁边有朵小乌云,感觉哪里不对劲。
建一所房子,你要挖坑打地基,铺钢筋,然后一块砖头一块砖头的往上磊。没办法,原子世界就是这么物质,一块砖头都少不了。软件是比特世界,软件开发很少是从买服务器开始,特别是在这个Cloud Native的时代,很多基建的事情云厂商都已经帮我们做好了。IaaS是对算力、网络、存储、操作系统等基础设施的复用;PaaS是对中间件的复用;
基于这样的演进路径,有没有可能做一个Business-PaaS(业务中台), 提炼出业务共性的东西,让前台业务少做点事情,提升研发效率呢?
单看上面的图示,这个逻辑似乎是通的。于是乎,在“大中台、小前台”的大旗帜下,星环诞生了。可是不管是从一线研发同学的反馈,还是高层的质疑声,都在表明星环似乎并没有解决问题,反而是制造了更多的阻碍、困难,这是为什么呢?
中台战略没有错,大中台也没有错,什么技术中台、数据中台都没问题,为什么到业务中台就有问题了呢?我想问题就出在这个“业务”身上。
IaaS也好,PaaS也罢,之所以能提效是因为其业务无关性,它们和业务的边界很清晰,彼此正交,互不干扰。IaaS、PaaS解决的是技术问题,业务解决的是业务问题。(偶尔PaaS也会侵入业务应用,为了与应用隔离解耦,于是有了PandoraBoot、Service Mesh等技术)
业务中台却没有这样的好命,它解决的是复杂、多变的业务问题,如果你拉近距离看业务和业务中台的关系,就会发现,他们并不像上图描绘的那样,中间有一道清晰的边界线,而是犬牙交错的耦合在一起:
前台业务要借助业务中台一起去完成业务逻辑,所以是有一部分埋在业务中台里的,至于埋的有多深,取决于使用中台能力的多少,用的多就埋的深,用的少就埋的浅。
因此,业务中台低效的根因,用一句话来说,就是因为前台业务和业务中台的“深度单体耦合”。这种耦合性,至少在三个方面严重影响了整体的研发效率:
研发≠写代码,实际上我们大部分时间不是在写代码,而是在沟通协调上。而且跟人打交道要比跟机器打交道要麻烦的多。这也是为什么《人月神话》中会说加人只会让项目更糟糕的原因,因为你额外增加了更多的协作成本。
因为中台的深度介入业务,导致组织协作成本倍增,详细分析可以参看 复杂组织下协作成本倍增的起因、影响及可能的解
除了组织协作成本倍增之外,因为耦合带来的工程协作成本也很高,试想一下如果几百个研发人员在同一个代码库上修改代码、部署,会是怎样的体验。
以下是一个同学的真实反馈:
“星环在外面宣传的是业务方7*24想发就发,实际远远做不到,很多限制,效率很低,体验过才知道多恶心。”
整个星环体系不可谓不复杂,里面有一堆的新概念——业务身份、活动(Activity)、领域服务(Domain Service)、领域能力(Ability)、扩展点(ExtensionPoint),扩展实现(Extension)、奥创、Lattice、业务容器…
KISS是一种美德,正如尼古拉斯所说:
“在现代生活中,简单的做法一直难以实现,因为它有违某些努力寻求复杂化以证明其工作合理性的人所秉持的精神。”
《反脆弱》里说:越是精巧的东西越脆弱。
现在的业务中台很精巧,同时也很脆弱。跟所有的“Big design up front”犯了同一个错误,即忽视了unknow unkowns。业务的灵活性、差异性,导致我们很难提前抽象,因为抽象是归纳之后的抽象,可是新的业务需求还没出现,你让我怎么归纳,怎么抽象?
理想的情况是我能预见所有的业务变化,提前做抽象,把所有的业务扩展点都预留好,这样不同的业务只需要在扩展点中定制就好了。但没人能预见未来,难免会动到平台代码,加一个扩展点啥的,因为平台代码是被所有业务共享的,这就给稳定性带来了极大隐患。会出现A业务改了平台代码,B业务啥事也没做,就出了故障。
这就是为什么对稳定性要求比较高的业务场景,比如APOS,宁愿冗余代码,也不愿被动出故障。实际上,代码冗余(Repeat)也是一种代码复用(Reuse),在很多情景下,Repeat是解耦更彻底,更简单高效的做法。比如在写测试代码的时候,用copy-paste的方式去准备测试数据就是很好的解耦方式,通过代码的Repeat,可以更好的隔离不同test case之间的相互影响。
总之,在精巧的、不稳定的复用和简单、高效的重复之间,后者会是一个不错的选择。软件架构无其他,只是权衡(trade-off)。DRY(Dont Repeat Yourself)和Decoupling(解耦)都是对的,选择哪种方案,应该是仔细权衡后的选择,而不应该是“拍脑袋”或基于”屁股“的选择。
针对上面的问题,如果让我来重新设计业务中台的话,我会尝试做以下事情:
协作成本、稳定性问题皆是因为前台业务和业务中台的深度耦合造成的。因此,星环的这种集中式的代码管控和部署的“大单体”模式亟需得到解决。
其实解决方案大家都知道,解决“大”的问题就是分而治之,解决“单体”的问题就是服务化。
也就是说,前台业务和业务中台的关系,必须从代码和部署的耦合状态,变成分布式的服务关系,就像BPass这个名字所隐喻的一样,让业务中台真正变成服务(Business Platform as a Service)。
解耦不难,关键是这一刀要从哪里切?我个人认为这一刀可以切在“业务无关”这个切面上。
所谓的“业务无关”就是想办法在业务中台中找到和具体业务无关的内核(kernel)。这样可以最大程度的复用中台能力,又可以保持业务的灵活性。比如所有的业务都需要对数据进行CRUD操作,这个就是业务无关的,而业务的各种校验逻辑就是业务相关的。
当然,这个边界具体放在哪,还是要具体情况具体对待,但是肯定会比现在的业务中台要薄。
举两个例子,比较合理的方式可能会像这样:
然而,即使是这样的薄中台也是极其有价值的,因为它帮助我解决商品的存储、存储扩展、性能、稳定性、工具(商品360、forest类目管控)、搜索构建等一些列和业务无关的非功能属性问题。说实话,这就足够了。
通过上面的解耦工作之后,星环这一套基本就可以deprecate掉了,因为业务中台只会保留“业务无关”的通用原子服务,自然也就不需要那套扩展机制了。
于此同时,因为前台业务和业务中台从之前的星环耦合关系,变成简单的服务调用关系、组件组合关系,系统的复杂度和认知成本也会极大的改善。这样前台和中台的同学就都解放了。
我相信,如果能按照这种“业务的归业务,中台的归中台”简单设计,边界清晰,职责清晰。不同BU的业务的演变、部署都在自己的掌控中,彼此正交、互不干扰,便可以极大的提升业务团队和中台团队的研发效能。
简单不等于简陋,帮助业务快速奔跑的职责不能丢。
假如有这样一个场景,一个全新的业务需要启动,因为中台做薄了,之前在业务中台沉淀的业务能力很多都释放给业务自己了,中台要怎么帮助新业务快速搭建呢?
这里可以考虑借鉴DevOps里的IaC(Infrastructure as Code)的概念,我暂时给它起个名字叫PaC(Platform as Code)。
如下图所示,可以由中台的PD、研发同学设计一个针对不同业务场景的业务解决方案库。
具体的实现方式可以是Maven的Archetype,并用版本的方式进行迭代,这样针对一个全新的业务,业务方可以快速的通过Archetype,生成一个functional的业务应用。再由前端业务部署到自己的服务器集群,按需修改完成自己的业务诉求上线即可。之后需求变更时,业务方便可以按照自己的意愿,在自己的“一方乐土”上自由奔跑了。
实际上这也是一种Reuse(重用),只不过是用代码Repeat(重复)的方式在重用。这样做,可能会导致不同的业务代码之间出现一些代码冗余(实际上,有些业务为了快速发展、稳定性的考虑,已经在采用copy代码的方式,比如陶特、APOS)。但是请相信我,这点代码冗余,在稳定性、可理解性、可维护性、工程效率的综合权衡之下,会显得微不足道。
正如《Fundamentals of Software Architecture》一书中所说:“There is no best architecture, but the least worst architecture"。
在PaC的基础之上,再进一步,可以考虑组件化,即把一些共用的逻辑封装成组件,打造一个“中台组件库”,业务可以按需组合这些组件去实现业务,同时,业务也可以把自己沉淀的组件反哺给“组件库”,形成一个良性循环的“大集市”:好的组件会被大量使用、迭代和演化。不好的组件会被冷落,躺平。
然而,还是那句话,业务是VUCA(Volatility Uncertainty Complexity Ambiguity)的,很难标准化,如何设计组件,如何让组件和业务之间松耦合——即不要让组件绑架业务,困住业务的手脚,将会是一个蛮大的挑战,需要一些智慧。这也是为什么我一开始提出PaC的时候,没有提组件化的原因。
总之,不管是PaC也好,还是PaC+组件化也好。大的方向都是把“中台大单体”给拆了,让业务回归业务本身,让业务和中台解耦,让中台更纯粹,让业务更灵动,让同学更幸福!