大型系统应用边界设计原则与实践

本文涉及的产品
云原生大数据计算服务 MaxCompute,5000CU*H 100GB 3个月
云原生大数据计算服务MaxCompute,500CU*H 100GB 3个月
简介: 大型系统应用边界设计原则与实践

我曾经担任某央企千万级生产系统交付方的首席架构师,负责整个系统的架构设计和架构管理。整个项目主要由三家公司、四个团队构成(各个团队下还有各自的子团队),团队人数规模大约100人。

交付模式


整个项目的交付过程以我定义的所谓“大瀑布+小敏捷”模式开展,该模式的具体形式如下图所示:

image.png

之所以采用这一方式,在于项目的每个里程碑节点必须按照合同约定的时间交付,例如在系统设计阶段结束时,必须交付概要设计说明书等交付物,然而,项目组又不可能完全依据瀑布方式开展工作,否则交付风险为显著增加,就需要有选择地进行敏捷迭代开发。

如何将瀑布流程与敏捷流程有机地结合起来,确实是项目组必须面临的挑战。我之所以定义这一混合模式,固然是为了各取所长,但其起因还在于项目的交付模式。甲方客户作为一家大型央企,必然重视流程管理与合同履约,该交付项目规模庞大,属于甲方客户极为重视的战略项目,客户的IT部门必须重度参与到管理流程中,通过跟踪项目计划的制订与执行来跟踪进度。

实际验证,“大瀑布+小敏捷”相结合的混合模式在面对这样的客户和项目时,确实发挥了巨大的作用。我想,若有机会,我会撰写单独的文章详细阐释我提出来的这一方法。


架构管理


作为首席架构师,除了主导整个项目的整体架构设计,并对关键问题做出技术决策之外,还需要负责技术管理。为此,我组建了架构师团队,团队成员同时担任各个团队的技术负责人。我还建立了架构CoP(Community Of Practice)机制,通过定期召开架构CoP会议,跟踪项目组面临的技术问题,识别技术风险并给出相应的解决方案。

四个团队分别位于成都、北京、杭州,这样的分布式团队需要通过线上会议进行沟通,沟通成本极大。架构CoP在运行一段时间后,我发现相当多争执不休乃至悬而未决的问题出在对应用边界的定义上,这一问题在微服务架构之上体现得尤为明显。


微服务架构


整个系统采用了如下所示的微服务架构:

image.png

微服务架构采用了前后端分离的整体架构,后端的微服务层按照领域边界划分子领域,在各个子领域内部,则根据业务的边界识别微服务,对外提供客户端需要的业务能力。每个微服务都是一个相互独立完整的业务单元,其逻辑边界也包括支撑该业务所必须的外部资源,包括数据库、文件或消息队列等。

客户端层根据UI呈现方式与载体的不同分为Web前端、APP前端、其他智能终端等。原则上,设计时需要保证前端的轻量级,尽量避免在前端编写业务逻辑,目的在于:

  • 前端资源有限,不利于处理复杂的业务逻辑
  • 不同前端需要支撑的业务逻辑可能相同,如果在前端编写业务逻辑,会导致业务实现的重复

遵循“轻前端、重后端”的思路,在进行产品设计与业务分析时,应确保前端逻辑与后端逻辑的边界,并尽可能识别多个前端可以重用的业务逻辑,将其沉淀到后端的微服务层。

然而,客户端层的前端与后端的微服务层往往不能做到完全的一一对应,因为前端的划分依据是根据前端类型与用户体验进行划分的,后端的划分依据则是从领域维度与业务能力。

设计微服务公开的接口时,应从业务能力的角度定义,如此才能保证服务接口的重用粒度。根据这一设计原则定义的服务接口可能无法满足前端UI的呈现目标,当后端微服务还需要支持不同的前端时,这一矛盾就更加突出。

微服务的服务接口既然是为了满足业务能力设计的,就需要遵循“单一职责原则”,保证每个服务是正交的。对于前端的呈现逻辑而言,可能需要汇聚多个业务方向的数据,以降低用户操作的复杂度。对于前端的用户体验而言,后端微服务定义的单个服务接口可能无法满足前端的一次调用需求。

要解决这两个问题,在架构上的做法就是在微服务层与客户端层之间再引入一个间接层,它所处的位置属于后端,但设计的接口却完全是为前端服务的,因而被称为“BFF(backend for frontend)层”。它的主要功能包括:

  • UI适配:调用后端微服务,将微服务返回的响应消息转换为支持多个前端呈现的视图模型
  • 服务聚合:定义一个外观服务,内部发起对多个微服务接口的调用,然后将它们各自返回的数据聚合为一个整体的视图模型

BFF层与API网关共同组成微服务应用架构的边缘层。


康威定律


一个好的开发团队与设计良好的架构应该遵循“康威定律”,也就是一个设计良好的系统,其架构的组织应该与开发它的团队组织保持一致。因此,要与微服务的应用架构相对应,就应该建立如下所示的团队组织:

image.png

遵循前后端分离的原则,通常需要为前端和后端建立不同的团队。在后端的微服务层中,各个子领域项目可以根据微服务的边界与团队规模,以微服务为边界组建特性团队。之所以子领域的边界没有贯穿前端团队,主要在于前端的边界划分并没有遵循子领域的边界,前端对后端微服务的调用,存在跨子领域调用的场景。

如果遵循康威定律,BFF层(边缘层的API网关属于微服务组件的范畴,无需单独开发,故而不考虑在内)也需要建立一个单独的团队。但是在实际情况下,该团队的建立需要考虑两个因素:

  • 交流成本
  • 技能要求

从交流的频率看,BFF与前端团队的交流更加频繁,为了降低交流成本,可考虑将BFF层的开发职责放到前端团队;从技能要求看,前端团队主要掌握JS技术栈,除非BFF的实现选择NodeJS,否则仍然需要将实现交给后端团队,这实际上是技术实现对边界的影响。


多团队协作的职责边界


组建团队时,团队的边界既是业务的边界,又是职责的边界。由于整个项目的参与方牵涉到三家公司的四个团队,且这些团队参与到项目的时间并不一致,要规避应用边界的问题,就必须为各个团队定义清晰的职责。

由于我们采用领域驱动设计方法定义子领域,这四个粒度较大的团队实际对应于整个应用架构的子领域,因此,可以结合子领域的类型与范围为团队规定各自的职责范围:

image.png

每个团队都有自己的前端(或微前端)与后端,共同实现垂直领域的完整业务功能。


多团队协作的数据边界


除业务边界外,组建团队时还需要考虑数据的边界,下图体现了数据存储和管理的范围:

image.png

由上图可知,移动App对应的移动子领域并未存储和管理业务主数据,它如果需要获得数据,需要调用业务A和业务B对外公开的服务。


应用边界设计原则


应用架构的边界受到业务边界、数据边界、团队边界、技术边界多个方面的影响,必须控制边界,否则会带来设计与开发的混乱,影响团队之间的协作。由此,这是我在参与多次架构CoP会议得到的亲身感受。

应用边界设计原则

为了避免大量类似问题的重复出现,也为了减少不必要的工作纠纷,我根据微服务的设计原则与团队的组建原则,结合项目的实际情况,确定了如下应用边界设计原则

业务的边界与数据的边界尽可能保持一致,应保证“谁拥有数据,即由谁访问数据”。例如,数据平台拥有全域分析数据,则由数据平台提供分析业务功能;业务A与业务B分别提供与其业务数据对应的业务功能,移动App没有业务数据,不提供访问业务数据的业务功能。

业务的边界与职责和能力的边界尽可能保持一致,一个业务功能的边界可以参考团队职责范围对其进行界定。例如,短信通知业务属于跨领域的公共服务,应交由业务A团队负责;数据平台的监控功能属于数据平台的管理服务,应交由数据平台团队负责;扫描二维码是移动APP才具备的能力,应交由移动App团队负责。

BFF层UI适配和服务聚合功能的划分取决于它所服务的前端。倘若它仅服务于移动APP和智能终端前端,原则上应由移动App团队负责;反之,应根据业务边界和职责边界,确定由除移动子领域之外的其他子领域团队负责。

服务接口设计原则

接口设计的不确定性也会影响到应用边界。每个服务接口都有服务提供方和消费方,若能定义一些普适性且具有实证主义的服务接口设计原则,就能清晰地规定各自职责,避免提供方和消费方的相互推诿。以下是我给出的服务接口设计原则

微服务对外定义的查询接口应确保其扩展性,即只需为服务接口提供一个实现以支持不同的查询条件与排序条件。原则上,查询接口在返回列表数据时,应支持分页能力。

服务接口的设计应遵循单一职责原则,对外提供高内聚的业务能力,保证服务接口彼此之间是正交的。如果调用者需要多个业务能力支持,以返回一个粗粒度的聚合数据,那么该服务属于服务聚合的范畴,应定义为一个对客户端公开的外观服务,放在BFF层。

服务接口的通用性优于专有性。例如,设计查询某资源的服务接口时,应考虑到多个客户端的调用请求,提供尽可能全面的资源信息,服务的调用者可以根据自身要求选择使用返回的对应数据,如此就可以通过增加服务接口的粒度来减少接口的数量。

开发团队在确定业务功能的应用边界时,应遵循以上原则,保证各个开发团队能够各司其职,以良好协作的方式完成业务功能的开发。如果存在业务功能的边界划分不适用于以上任何原则,或者对原则的适用存在分歧,则由架构师团队召集相关团队负责人进行讨论,根据具体的应用场景确定最佳的解决方案。

相关实践学习
基于MaxCompute的热门话题分析
本实验围绕社交用户发布的文章做了详尽的分析,通过分析能得到用户群体年龄分布,性别分布,地理位置分布,以及热门话题的热度。
SaaS 模式云数据仓库必修课
本课程由阿里云开发者社区和阿里云大数据团队共同出品,是SaaS模式云原生数据仓库领导者MaxCompute核心课程。本课程由阿里云资深产品和技术专家们从概念到方法,从场景到实践,体系化的将阿里巴巴飞天大数据平台10多年的经过验证的方法与实践深入浅出的讲给开发者们。帮助大数据开发者快速了解并掌握SaaS模式的云原生的数据仓库,助力开发者学习了解先进的技术栈,并能在实际业务中敏捷的进行大数据分析,赋能企业业务。 通过本课程可以了解SaaS模式云原生数据仓库领导者MaxCompute核心功能及典型适用场景,可应用MaxCompute实现数仓搭建,快速进行大数据分析。适合大数据工程师、大数据分析师 大量数据需要处理、存储和管理,需要搭建数据仓库?学它! 没有足够人员和经验来运维大数据平台,不想自建IDC买机器,需要免运维的大数据平台?会SQL就等于会大数据?学它! 想知道大数据用得对不对,想用更少的钱得到持续演进的数仓能力?获得极致弹性的计算资源和更好的性能,以及持续保护数据安全的生产环境?学它! 想要获得灵活的分析能力,快速洞察数据规律特征?想要兼得数据湖的灵活性与数据仓库的成长性?学它! 出品人:阿里云大数据产品及研发团队专家 产品 MaxCompute 官网 https://www.aliyun.com/product/odps 
相关文章
|
5月前
|
存储 设计模式 前端开发
软件架构设计的原则与模式:构建高质量系统的基石
【7月更文挑战第26天】软件架构设计是构建高质量软件系统的关键。遵循高内聚、低耦合、单一职责等设计原则,并灵活运用分层架构、微服务架构、客户端-服务器架构等设计模式,可以帮助我们设计出更加灵活、可扩展、可维护的软件系统。作为开发者,我们应该不断学习和实践这些原则与模式,以提升自己的架构设计能力,为团队和用户提供更加优秀的软件产品。
|
6月前
|
人工智能 数据可视化 大数据
项目管理软件:从单一工具到全面解决方案的演进
【6月更文挑战第24天】从单一工具到全面解决方案,项目管理软件伴随企业复杂性增长而进化。初期专注任务分配和进度,现整合云、大数据、AI,提供集成、灵活、可视化及智能的全面解决方案。技术革新如云计算增强实时访问和数据分析,大数据支持决策,AI助力预测和自动化。未来,软件将进一步智能化、集成化,优化项目管理效率和满意度。
|
5月前
|
存储
业务系统架构实践问题之为什么按模型划域可能是比按领域划分更好的选择
业务系统架构实践问题之为什么按模型划域可能是比按领域划分更好的选择
|
5月前
|
网络协议 Python
系统工程是一种跨学科的方法论,旨在通过分析和设计系统的各个组成部分、组织结构、信息流和控制机制,以实现系统的整体最优运行。
系统工程是一种跨学科的方法论,旨在通过分析和设计系统的各个组成部分、组织结构、信息流和控制机制,以实现系统的整体最优运行。
|
7月前
|
运维 Cloud Native 数据库
开发人员必须知道的软件系统架构分类知识
日常工作中或者是看各种资料或阅读书籍时,大佬们关于软件架构的描述中经常会看到SaaS和云原生,微服务,事件驱动型这几种词汇,其实这几类架构描的角度是不一样的。
151 7
|
7月前
|
存储 运维 安全
软件体系结构 - 信息系统架构
【4月更文挑战第20天】软件体系结构 - 信息系统架构
208 13
|
7月前
|
前端开发 关系型数据库 定位技术
WEBGIS系统整体设计
WEBGIS系统整体设计
96 6
WEBGIS系统整体设计
|
架构师 算法 程序员
提高软件系统设计和架构理论水平之路
提高软件系统设计和架构理论水平之路
|
存储 架构师 Java
架构风格与协同之间设计考量
一次关于架构风格与协同之间的讨论,激发出来自己的很多思考,遂整理出来,与大家分享。 讨论的主要内容有三点: 1、架构风格与应用框架 2、时间、成本和范围的平衡 3、演进式架构的考虑 关于**第一点**,在读《架构整洁之道》一书中就提到过,包的组织形式决定了架构的设计风格,如下图所示,从左至右分别是按层封装、按功能封装、接口和适配器和按组件封装。 ![](https://ata2-img.o
269 0
架构风格与协同之间设计考量