从中台兴衰看能力复用:我司实践过程中的一些思考

本文发布于个人博客 从中台兴衰看能力复用:我司实践过程中的一些思考 | 灵感空间站 中,同步过来抛砖引玉,欢迎佬友们讨论 中台为什么那么诱人? 说到中台一词在国内最早的由来,大多绕不开阿里在2015年参访 Supercell 公司后提出的“大中台、小前台”战略,但这个事件其实只是一个引子。在此之前,...
从中台兴衰看能力复用:我司实践过程中的一些思考
从中台兴衰看能力复用:我司实践过程中的一些思考

本文发布于个人博客 从中台兴衰看能力复用:我司实践过程中的一些思考 | 灵感空间站 中,同步过来抛砖引玉,欢迎佬友们讨论

中台为什么那么诱人?

说到中台一词在国内最早的由来,大多绕不开阿里在2015年参访 Supercell 公司后提出的“大中台、小前台”战略,但这个事件其实只是一个引子。在此之前,阿里内部已经面临着多个业务之间重复建设的问题(淘宝、天猫、聚划算等),这些业务都有一些相似的能力如交易、会员、营销等,而新的业务却需要从头建设。这种各自为营的做法,演变成了大家说的烟囱式系统架构。所以在15年参访 Supercell 之前,阿里内部就已经出现了能力复用的诉求,并经历了一段痛苦的摸索。

随着中台思想开始被其他公司/行业广泛研究,中台这个概念被进一步泛化,扩展出了业务中台、数据中台、技术中台,乃至 AI 中台等多个概念。并且各个公司争相模仿,开始变成了一句架构口号。

然而事物的发展总是螺旋上升的,就连主流系统架构也经历从单体到微服务,又到“微服务已死,模块化单体当立”的变化。中台思想在这十余年来的发展中,同样引起过不少争议,包括但不限于以下几点:

  • 中台与业务之间的界限模糊不清,有些能力难以确定该归谁管
  • 中台与业务的迭代节奏不同频,业务提出的调整需要等待中台适配,违背了前台敏捷化的初衷
  • 中台做大做重之后,其本身也成了一个复杂的“烟囱式系统”

所以后来又看到另一种趋势:大家开始反对大中台。甚至连最早提出中台战略的阿里,也在 2023 年的内部全员信中提到,要将中后台“做轻、做薄”,将15年以来建立的“大中台”能力逐步被更强有力的前台吸收。

中台发展趋势

透过现象看本质,在笔者看来,中台最核心的概念其实就是能力复用

只要多个业务都需要同一种能力,自然就会产生复用诉求。这个复用可以是一个独立中台服务,可以是一个公共组件,也可以只是一套模板、规范或者最佳实践。而中台只是其中一种复用方式,一种有状态的、以复用业务能力为核心的服务化架构。

回顾我司中台化历程

笔者所在公司规模不大,属于中小型的物联网企业。24年底,在行业发展和相关政策出台的背景下,公司决定立项新的 SaaS 业务。新业务需要从头开发,而在当时回顾公司其他业务的发展现状、可以说是标准的烟囱式架构,各自为营,许多相同的能力到了新业务中,都得重新开发;并衍生出了问题分散,运维复杂等痛点。

第一阶段:新业务建设带来的平台化尝试

在如此现状下,基于长远发展考虑,公司决定建设内部的能力复用平台(下文亦称平台),将业务中重复的、可复用的能力抽象出来构建成不同中台,业务方根据需要接入对应中台。平台与新业务同步立项,同步建设。自然而然地,新业务也成了第一个吃螃蟹的。

为什么不直接拿现有业务开刀呢?现有业务相对成熟,业务逻辑久经考验,不会有太大变动,更适合在这上面做抽象,提取共同点。

这话本身没错,但是对于运行多年的业务系统来说,稳定是第一要务;更何况早期的代码质量属实不敢恭维,多年缝缝补补下来,早已堆成了屎山,在这上面做调整,去接入一个重新设计、还未得到验证的中台,无异于屎上雕花。谁也不愿意为了长期收益并不直观的目标,去承担短期改造带来的巨大风险。这点相信不少程序员都深有体会:代码能跑就不要动。

但新业务不一样。新业务本来就是从零开始,没有太多历史包袱,也不需要考虑存量数据的兼容问题。与其再复制一套旧系统里的基础配置、用户管理等能力,不如趁此机会把公共能力沉淀下来,让新业务直接基于平台能力往上搭;同时在设计上兼顾现有业务,为以后存量业务接入(也许)打好基础。这也是不少公司推动技术迭代的方式:老的动不了,那就先在新的系统里试试。

不过这个阶段的中台建设,其实并没有后来想象的那么正规。彼时中台还没有成为公司重点发展的战略化平台,做业务系统和做中台的都是同一批人。业务开发过程中发现缺少什么能力,转头就去中台里补;业务流程需要某个字段、某个扩展点,也很自然地会被加到中台服务里。

这种模式在项目早期很高效,因为沟通成本极低,也没有明显的协作边界。开发人员既知道业务要什么,也知道中台怎么改,很多问题当天发现,当天就能调整。平台还不成熟,业务又要往前跑,与其反复开会讨论边界,不如先把能力做出来。

但这也为日后的问题埋下了伏笔。因为中台和业务从一开始就是同一批人在做,所以很多设计到底是公共能力,还是当前业务的顺手抽象,其实并没有被严格区分。某些能力看起来被放进了中台,实际上只是服务了第一个接入的业务。等到后面更多业务接入时,这些早期的设计,才开始接受真正的复用检验。

第二阶段:初版平台能力的划分

初版的中台划分比较简单,围绕公司业务特点分为以下几块:

  • 基础管理(业务方案、租户管理、字典管理等)
  • 用户中心(B/C 端用户、角色权限、组织划分等)
  • IoT 中台(设备接入、物模型管理、设备影子/事件/服务等)
  • 车辆中台(车辆实体/型号、配件实体/型号,以及组合逻辑)

从当时的视角来看,这个划分并没有什么大问题。基础管理解决的是系统运行过程中绕不开的通用配置;用户中心解决的是账号、角色、权限这些几乎所有业务都会遇到的问题;IoT 中台则对应公司的物联网业务特点,把设备接入、物模型、设备影子这类偏技术领域的能力沉淀下来;至于车辆中台,则是因为公司大部分业务都围绕两轮车展开,抽出车辆和配件相关能力,看起来也是一件很自然的事情。

只从这一层来看,初版中台的边界甚至还算克制。它没有一上来就试图包揽所有业务流程,而是围绕“业务系统都会用到什么”这个问题做拆分,既没有完全脱离业务,也没有把所有东西都塞进一个大而全的平台里。

但现在回过头来看,这几个中台服务的抽象层级其实并不完全一样。基础管理、用户中心更偏稳定的通用能力,业务差异通常体现在配置和权限模型上;IoT 中台虽然复杂,但更多复杂度来自设备协议、设备状态和消息链路,至少它解决的问题相对明确;而车辆中台就不一样了,它看似是公共能力,实际已经很接近业务模型本身。

这也是后面问题的根源之一。越靠近基础设施和稳定能力,复用越容易成立,因为不同业务之间的差异不会太大;越靠近业务模型,复用就越需要谨慎,因为不同业务虽然都有“车辆”“配件”“组合”,但背后的业务语义未必一样。初版划分里真正埋雷的地方,也正是在这里。

第三阶段:更多业务接入后,平台价值开始显现

随着不断迭代和运营,平台趋于成熟,后续公司又扩展了多个新业务,也都在这个能力基座之上进行开发。

这时平台的价值就开始体现了。一个新业务从零开始做,如果没有任何公共能力支撑,往往要考虑一堆共性问题:用户怎么管理、权限怎么分配、租户怎么隔离、设备怎么接入等等。每个问题单独看都不算复杂,但全部重新做一遍,就会消耗大量时间。

而有了平台之后,新业务可以直接复用已经沉淀下来的用户、权限、设备接入、基础管理等能力,把更多精力放在自己的业务流程上。对于开发团队来说,这种收益是非常明显的:项目启动更快,基础功能交付更快,很多之前需要重复讨论和重复开发的东西,变成了按规范接入即可。

更重要的是,试错成本也随之降低了。业务能不能跑通,市场反馈好不好,并不是一开始就能判断清楚的。如果每一次尝试新业务,都要完整搭一套基础能力,那么自然需要更加谨慎;但如果底层能力已经有了,新业务只需要在平台之上补齐自己的核心业务流程,那尝试新方向的成本就会低很多。

所以站在这个阶段看,中台确实发挥了它的价值。它从纸上谈兵变成了实际生产力,也让公司在探索新业务时拥有了更快的启动速度。哪怕后面暴露出不少问题,也不能否认,在这一阶段,中台确实解决了一部分真实痛点,以至于后来公司决定将平台作为战略化项目,组建团队单独维护。

第四阶段:平台能力扩张后,问题开始出现

中台的价值被看见之后,平台自然被寄予了更多期待。它不再只是新业务建设时顺手沉淀出来的公共能力,而开始被视为支撑后续业务发展的统一基座。但这时中台与业务的矛盾也随之而来:

中台应该以稳定为先,而业务天然追求快速迭代。

对于业务方来说,需求往往是紧急的。业务要上线、流程要验证,很多需求都带着 DDL。而对于平台方来说,一个改动要考虑的方面会更多一些:后续的兼容性、业务的接入成本、长期的维护难度…这些往往不是一拍脑袋就能决定的。如果平台团队没有足够的话语权(事实上大部分公司都是业务方的话语权更大),就会不断被这些紧急需求打断,有些改动就会欠缺更深远的考虑。

车辆中心的问题,某种程度上就是这种矛盾的早期体现。

车辆中心最初的设想,基于公司业务围绕两轮车展开,车辆、配件、型号、组合关系这些概念看起来天然具备复用价值。既然后续业务大概率也会接触车辆,那把车辆能力提前抽出来,似乎是一个很合理的选择。

但随着这个业务不断往前发展,各种复杂规则也不断被加进来。今天改一下配件组合规则,明天多一种车辆状态流转,后天又要兼容某个特殊业务流程。这些改动不断叠加后,车辆中心的模型也越来越贴近这个业务本身。

直到某个时间点再回过头审视,才发现车辆中心已经变成新业务的形状了:sob:。它虽然仍然叫车辆中心,但里面沉淀的领域模型、规则和扩展点,实际上都和这个新业务强绑定。如果未来真有其他两轮车业务想接入,面对的不是一个清晰、轻量、稳定的车辆能力,而是一套与特定业务深度绑定的复杂模型。

公共名词不等于公共模型

这件事带给我们一个教训:公共名词并不等于公共模型。多个业务都有车辆概念,不代表大家都是同一套车辆模型;大家都说配件,也不代表配件之间的组合规则可以被统一抽象。越靠近业务模型的能力,越不能只因为名字相同就急着中台化,否则很容易在持续迭代中,把某个业务的模型包装成公共能力。

如果说车辆中心的问题是“过于贴合早期业务”,那么后来规划的交易能力(订单、支付、分账)的中台化,则暴露出另一类问题:设计过早追求绝对完整,结果还没真正接入业务,复杂度已经爆炸了。

交易中台最初不是由某个具体业务需求倒逼出来的,而是平台团队主动提出的。面向C端的商业化项目,往往绕不开支付、分账这类交易能力。所以当时平台团队的设想是,由中台把这些复杂度统一包下来,业务侧只需按照平台提供的交易模型接入,就不用再关心很多底层细节。

但问题也正是从这个“统一包下来”开始的。

最开始,我们想解决的是第三方支付能力的复用;但是实际业务中,一笔交易订单可以由多种支付能力组成:内部钱包、优惠券、第三方支付…既然打算统一包下来了,那就都做了吧。于是交易中台的边界不断扩大,复杂度也明显上升:交易订单需要考虑各种支付组合场景,且退款时也要兼容各个渠道的退回;支付成功后,可能立即分账,也可能延迟分账;如果一笔支付已经被分账了,退款时该如何处理?类似问题越往后退,边界场景就越多。并且由于中台作为公共能力的特点,天然要求更加稳定,覆盖场景更充足;更别说这类能力是和钱打交道的了。

这就导致一个尴尬的局面:交易中台还没真正落地,内部复杂度已经隐约开始失控了。到了后期,除了项目负责人之外,团队内其他成员都不一定能理清这一整块的复杂逻辑,更何况后续业务方接入呢?

所以后来我和一个新业务的技术负责人交流时,他提到一个很现实的问题:由于平台侧交易能力的设计周期较长,业务为了尽快上线,已经自行实现了相关功能,并且功能也逐渐稳定。此时再要求业务等平台能力完善后全盘接入,对业务方来说其实很难理解。业务还在起步阶段,最需要的是稳定和快速响应客户需求,现在却要花大量时间把已经跑通的核心链路迁移到一个未经充分验证的平台能力上,本身就会让人抵触。

交易、分账这类能力固然具有复用价值,而且越往后发展,越容易成为多个业务都会遇到的问题。但首先不同业务对其中的细节可能有不同的客制化需求,如果平台过早把这些灵活性都包进来,为业务提供一把“万能钥匙”,那么平台本身的业务复杂度也会直线上升;并且这类能力有一个特点:它非常看重稳定性。业务一旦上线并形成稳定交易链路,就不会轻易愿意迁移。因为迁移交易链路带来的风险,不只是多改几行代码,而是可能影响资金流、现有订单、对账、售后等一整套业务流程。

交易中台复杂度扩张

这让我意识到,对于交易这类复杂能力来说,平台能力做得越完整,交付周期会拉得越长(指数上升),并且业务方的接入成本也更高。因为完整往往意味着平台已经预设了一整套流程、模型和边界,业务方接入时不仅要调用接口,还要理解平台的设计,并判断自己的业务流程能不能塞进这套模型里。搞不好业务为了兼容平台,反而要调整现有已经跑通的设计。

从前端组件库看“复用方式”的变化

前段时间,我在 vibe 个人小项目的过程中,接触到了 shadcn/ui 这个组件库。以前写前端时,对于各种控件、表单,通常都会引入组件库,大家熟知的 Ant Design、Element Plus 都是成熟的组件库。组件库使得页面交互行为更一致,视觉风格更统一,开发效率也更高;但相对的,组件库能调整的地方有限,通常只有少数几个 props。

对于后台管理系统这类场景,大部分页面不追求太强的个性化,长得千篇一律也无所谓。但是对于个性化要求较高的应用(比如本博客),在设计之初就希望展现出强烈的个人风格(先不论好看与否),而非千人一面。而组件库作为页面风格的重要体现元素,自然有着客制化的需求。在当时,我面临两个选择:

  1. 找一个设计风格上对我口味的组件库
  2. 自己实现一个组件库

后来我选择了第二种方案,并经历了一段痛苦的探索。有些事情往往动手之后才知道不简单:

  • Tooltip 怎么被按钮遮住了?
  • 文本框内怎么显示滚动条了?
  • 多个 Notification 轮流消失时,下方的怎么是瞬移上去的?

诸如此类问题不断出现,修复,出现下个问题。

所以后来我看到 shadcn/ui 的思路时,觉得它很有意思。它并不直接提供组件库作为项目依赖,而是换了一种复用方式:直接把组件源码添加到项目里。你得到的是一份已经设计好的默认实现,包括交互、结构、可访问性和基础样式,但这份代码属于你的项目,你可以随意修改组件的样式、行为,正如它文档中对自己的定位:

This is not a component library. It is how you build your component library.

回到中台这个话题,这个例子给了我一个启发:复用不一定非要通过一个强中心来完成。公共能力可以提供默认实现和最佳实践,但不一定要把业务方锁死在一个不可修改的模型里。对于变化比较多的部分,让业务方拥有一定的调整空间,可能比强行统一更具灵活性,也更容易被业务接受。

当然,前端组件库和后端业务中台不是一回事,这个类比不能简单套用。组件源码复制到项目里,后续维护成本由项目自己承担;而后端中台往往涉及数据一致性、系统边界、稳定性和跨业务协作,复杂度高得多。但它们背后的思想是相通的:复用的目标不是制造依赖,而是降低重复建设;公共能力的价值,也不一定要以牺牲业务灵活性为代价。

另一个例子:异步任务中心的状态归属

shadcn/ui 这个例子,让我想到另一个后端场景:

对于B端业务,不少场景下会涉及到数据导入/报表导出等相关功能,这类场景的一大特点就是数据量大,执行时间往往较长。如果直接通过接口同步执行,很容易遇到接口超时、页面刷新后状态丢失等问题,用户体验较差。并且,由于这类任务都是用户在业务流程中实时发起的,也不适合用定时任务来处理,所以通常做法都是对这类功能进行异步化改造。

所以当新业务中开始出现大数据量导入导出的需求时,我没有急着按异步化的思路进行开发,而是开始思考:公司几乎所有业务中都有导入导出这类场景,而这类需求也都可以抽象为以下执行模型:

  1. 用户发起一个任务
  2. 系统记录一条任务信息
  3. 后台异步执行任务
  4. 用户可以随时查看任务状态
  5. 任务完成后记录结果,可供用户查看

对于此类需求来说,上面的流程(任务生命周期管理)都是固定不变的,真正变化的,只有任务执行逻辑本身。既然如此,我们为何不尝试将这种能力抽象出来,供各个业务复用呢?

所以我根据这个思路设计了一个异步任务中心 SpringBoot Starter,帮助业务屏蔽掉任务落库、调度执行、服务重启恢复等与业务逻辑无关的细节。业务只需按照约定实现业务逻辑,并提供对应的任务提交与查询能力,就能轻松实现长任务的异步化,无需关心其他细节。但是这里出现了一个纠结点:异步任务中心需要持久化任务记录,同时需要添加定时任务用于提交未执行的任务。那么,这些数据和定时任务应该放在哪呢?我们想到了两种方案:

  1. 平台托管:放在一个单独的服务中,由该服务维护管理,并向业务侧提供相应接口
  2. 能力下沉:只提供数据表 DDL 和定时任务模板,需要用到的业务自行添加,自行管理

这两种方案各有优劣。平台托管的优势是业务方无需维护数据与定时任务,接入更加简单,但灵活性稍差,且该服务不可用时会影响所有业务;而能力下沉的优势是使用上更加灵活,且没有中心化的单点风险,但相对的,需要自己维护数据与定时任务。

后面评估时,我们认为平台托管所带来的收益有限,且使用上不够灵活。这种场景下,我们更看重业务侧的控制权,不同业务可能任务的归属主体不一样,任务的筛选条件也不一样。通过能力下沉将这些细节留给业务决定是更好的选择。

现在回过头来看,这个异步任务中心的设计其实有点像前面提到的 shadcn/ui。我们没有选择把所有能力都收归到一个强中心化平台,而是只抽象了任务生命周期管理这个真正稳定的部分,把数据查询、任务归属等容易变化的部分交回给业务自己管理。从这个角度看,能力复用并不一定意味着需要“统一托管”,而是稳定的部分由公共能力提供,变化的部分留给业务控制。这个判断,也正好能回到前面提到的能力复用平台的问题:并不是所有能力都适合做成强中台。

中台不是目的,复用才是

其实很多中台的问题不在于能不能复用,而是用了不合适的复用方式。不同能力的复杂度、边界、稳定性都不一样,适用的复用方式也自然不同。

车辆中心的问题,是把相同的业务名词误认为相同的业务模型;交易中台的问题,是在业务模型还没有充分验证之前,就试图把未来可能出现的复杂场景提前纳入;而异步任务中心最终选择能将能力下沉为组件,则说明有些能力真正值得复用的,并不是完整的平台服务,而是其中的执行模型和默认实现。

现在看来,真正适合中台化的,往往是那些边界清晰,能力模型稳定的业务:比如用户认证、权限模型、或者标准的渠道支付。这些能力的差异性往往可以通过配置等非代码适配的方式来抹平。同时也要警惕“过早抽象”,避免最后变成了某个业务的映射。但这里又涉及到一个矛盾:有些能力过早抽象,容易出错;但太晚做,又会遇到存量系统改不动的问题。想要在早期设计中规避这些问题,往往需要功力深厚、深入理解业务的架构师才能做到,这也是为什么小公司在推动中台化时更容易踩坑。

而对于那些更偏向解决确定性技术问题、或者状态可以由业务自己控制的能力,做成技术组件或许是更聪明的做法。常见的接口幂等、流量控制,亦或是上面提到的异步任务中心都是很好的例子。这种复用方式只关注流程中不变的部分,把变化的部分通过扩展点留给使用方自己决定,没有中心化的单点风险,也不剥夺业务侧的控制权,自然更容易被业务方接纳。

毕竟,好的复用,是用合适的方式,在平台沉淀的稳定性与业务演进的变化性之间找到合适的边界。

2 个帖子 - 2 位参与者

阅读完整话题

来源: LinuxDo 最新话题查看原文