简介: 首次上线应用,面对业务框架搭建你是否曾感到无从下手?维护线上应用,面对大量历史包袱你是否正避坑不及深陷泥潭?为何同样是业务应用,不同人的设计风格千差万别?为何最初的设计经过多个迭代后总是面目全非?新人来到团队,怎样才能快速了解业务,不被大量技术细节折磨?如果你也有这些困扰,希望本文能提供些许帮助。
作者 | 木沉
来源 | 阿里技术公众号
首次上线应用,面对业务框架搭建你是否曾感到无从下手?维护线上应用,面对大量历史包袱你是否正避坑不及深陷泥潭?为何同样是业务应用,不同人的设计风格千差万别?为何最初的设计经过多个迭代后总是面目全非?新人来到团队,怎样才能快速了解业务,不被大量技术细节折磨?如果你也有这些困扰,希望本文能提供些许帮助。
1 细节割裂架构
业界的成熟应用框架有很多。无论是SpringMVC/SpringBoot还是SofaBoot,都对工程结构给出了明确的规范约定,职责边界看似非常清晰。但在实践中,再简单的业务应用都避免不了业务逻辑分散各处,打破module边界出现隐式耦合的现象。分散的业务细节必然导致应用架构的割裂,如果没有持续的重构调整,最终总会变得复杂臃肿(当然,是持续有新需求的前提下),老人沉默新人流泪,只能依靠天降猛男重做2.0。究其原因,个人认为主要在于:
若以法律和道德的关系做类比,通用框架约束了技术编码的“法律”底线,而设计原则就是开发人员对自身的“道德”要求。在简单的业务场景下,满足需求是第一优先级,设计能力的诉求并不突出。但在多方协作的业务团队下(真实情况大多如此),没有统一的“道德标准”,将很难形成合力完成复杂项目。《Java开发手册》(阿里巴巴Java开发规约)在推进编码标准的道路上迈出了很大一步,极大提升了工程人员的专业素质,大大提高了“道德共识”。那么在业务架构设计的领域里,是否至少能在某个问题域内,也建立一套面向业务研发同学的“设计规约”。
2 技术沉淀流失
另一方面,进入阿里巴巴后,自身研发经历虽然并不多,但接触过不少优秀设计。这些产出无论是否最优方案,都体现出了技术同学对优秀设计的美好愿望和强大落地能力,也确实在一定的历史时期内高效地保障了业务发展。然而,令我困惑的是,尽管每个业务项目和业务产品都能沉淀出一些可复用的组件或框架,参与研发的同学也能总结出一套面向未来需求的设计原则和实践经验,但这些财富始终难以维护和传承。可能的原因有(对前端/测试/数据/平台等研发经历不太了解,这里仅针对一线业务研发):
相比于缺少“设计规约”导致的低效协作,已经沉淀的“规约原型”被轻易抛弃更加令人可惜。业务研发的日常工作,本质上是拆解问题域的复杂性,用分层解耦/工具化/平台化/业务抽象的多种思路将子问题逐个击破。如果部分子问题已被很好解决,为何不站在前人肩上?放弃造不造新“轮子”的纠结心态吧,或许我们更需要搭“积木”的心态。
结合蚂蚁链-应用技术团队近年来的技术实践,我们试图从自身需求出发,搭建一套或许能满足更多业务场景的业务架构设计规约。重点说明下,本文是从有限的问题域出发提出的解决思路,不奢求成为通用解决方案。如果其他业务线也有类似的痛点,希望能有些许借鉴。
1 标准——减少细节
理想情况下,业务技术只需关注领域建模,但现实中却不得不考虑更多通用的技术细节。以供应链金融场景下简化版的应收账款发行流程为例,需要考虑的有:
在以上未完全列举的几项中,除了“领域建模”以外,基本都是与具体业务无关,但对于一个稳定可靠的业务应用不可缺失的部分。如果能建立一套标准化的框架方案,用统一的规范解决掉业务无关的大量细节,是否就能让业务技术同学真正的专注于“领域建模”?
2 沉淀——能力复用
沉淀和复用是技术群最常出圈的几个词,可见认同度之高。能力复用不局限于形式和粒度,能够切实降低技术成本,提高业务扩展性,就是不错的沉淀,可作为“积木”供后续使用。以蚂蚁链应用技术团队场景为例,近年来沉淀的能力包括但不局限于:
技术类
业务类
平台类
3 重构——持续优化
沉淀来源于业务需求,却常常落后于新需求。对于设计者以外的人来说,维护他人的“积木”常常会踩到不少坑,反倒不如自己重写。这也是为何每个团队都在说沉淀,但能够横向复用,甚至在同一个团队内持续复用的能力都少之又少。虽然这个现象没有完美解法,但个人建议采取以积极的心态看待这些“积木”:
这里没有强调重构复用和重写这两种方案的ROI对比,是因为个人看来,即使前者成本更高,重构的过程对个人技术成长和团队文化统一都是有利的。相对于不断推翻和发明新“积木”,持续优化的过程,是对自己和他人经验的不断回顾和反思,看清历史的坑,才能避免新风险的出现。
4 集成——灵活搭建
标准能够落地,除了有足够趁手的“积木”库外,更重要的一点,是要有灵活便捷的“粘合剂”,以完成业务功能的快速搭建和灵活调整。在供应链金融的场景下,业务需求主要体现为各种各样的业务流程,比如发行/转让/清分等等。为了简化“积木”搭建,灵活复用底层能力,我们基于以下目标,设计了面向业务的服务编排引擎:
5 产品——业务大图
“积木”+“粘合”能够满足技术落地的低成本高扩展,但从业务视角,还需要一个全局大图来描绘业务线的全域能力和功能流程。本文中暂不涉及。
如前所说,只靠文档形成的共识,对技术没有足够的约束,极难维持。因此,我们基于上述规约的各项原则,搭建了一套标准化的业务架构设计方案,通过组件化工具化的方式约束业务应用,形成团队共识。一个标准的业务应用架构如下:
1 组件——规范技术细节
通过组件化约定,约束通用技术细节的行为,包括但不局限于:
交易模型
描述业务流程的核心交易模型,用于管控状态推进,维持与业务模型的关联。
仓储行为
数据持久层的通用行为,包括锁定查询/插入/更新/普通查询等。
事务模板
定义事务边界,确保模版内业务逻辑的事务一致性;支持幂等能力。
通用业务模板
定义业务逻辑边界,无事务性保障,但包含了异常处理/日志埋点等通用能力。
通用查询模板
定义查询逻辑边界,与通用业务模板类似,但主要面向单项/批量/分页等查询场景。
消息
对消息中间件的简单封装,适配业务应用规约,降低配置成本。
调度
对调度中间件的简单封装,适配业务应用规约,降低配置成本。
服务开放
api组件规范对外服务能力,通过注解识别服务定义和服务实现,自动生成接口文档,描述接口参数/返回/业务域/错误码等等。
其他——日志/异常处理/请求参数/返回类型
这里不做展开。
以上是所有业务应用都会遇到的技术细节,用组件屏蔽细节的思路也没有复杂之处,我们想要表达的重点是:尽可能沉淀和复用技术组件,尽可能使用他人的成果,不要重复搭建,把重心放到业务上!
2 领域——专注业务建模
再次强调,对业务技术来说,业务建模是核心,业务建模是核心,业务建模是核心!本文的初衷和方案都是为了让开发解放出来,直面核心业务的设计和思考。本小节仅给出领域产出的基本要求,后续在【案例分析】再做详述。
领域实体
建模的核心是抽象出领域实体及其关联关系,不同的业务场景和设计思路,会有很大差异,最终会体现为一到多个领域模型。需要明确在不同业务流程下,各交易模型内需要包含的领域模型(比较抽象,后续在【案例分析】再做详述)。
领域仓储
定义数据模型,及其与领域模型的对应关系(各种converter)。基于上文提到的仓储组件,配置数据库表和连接,实现锁定查询/插入/更新/普通查询等业务行为。
领域服务
基于业务行为,抽象出原子化的领域服务能力。该服务无需关注数据仓储,无需关注业务流程,仅抽象出领域实体的原生能力。以上文中提到的应收账款模型为例,至少需要包含:
等等基本行为。
交易实体
用于承载交易流程的业务实体,上文中交易模型的业务实例,内部关联一到多个领域实体。
交易仓储
用于管控交易实体以及内部各领域实体的仓储行为。
3 服务编排引擎 —— 积木+粘合
但凡涉及复杂业务流程的应用,都需要引入流程引擎来编排状态机的流转。业界有很多成熟的流程引擎框架,也有很多足够可用的简化版本。但如前文所说,这类通用引擎的优点也是其最大的弱点:过强的灵活性无法对设计风格形成约束,大量业务细节会分散在不同状态节点间,不直观也难维护。从自身需求出发,我们设计了面向业务的服务编排引擎,以遵循业务设计规约的方式约束技术,以直观的形式描述业务流程。与传统流程引擎相比,其业务友好性主要体现在:
总的来说,服务编排引擎基于通用组件屏蔽技术细节,重点专注于业务行为的编排和复用,对“积木”进行“粘合”,以编排出符合业务需求的业务流程。
本文从业务技术团队的现实痛点出发,尝试以业务架构设计规约(理论标准)结合业务架构标准方案(工程约束)的思路统一团队的技术风格,将技术同学从细节中释放出来,专注于技术能力的积累和对业务价值的思考。希望传达的想法有:
原文链接
本文为阿里云原创内容,未经允许不得转载。