Day31-41|12.2.1 架构风格:用结构约束组织信息系统的整体形态
Day31-41|12.2.1 架构风格:用结构约束组织信息系统的整体形态
一、教材定位
本节进入《系统架构设计师教程(第2版)》第12.2节“信息系统架构”,主题是“架构风格”。前面的 12.1 节解决信息系统是什么、如何发展以及如何定义边界,本节开始进入架构设计方法,回答“系统的整体组织形态如何选择”。
架构风格是综合知识、案例分析和论文写作中的高频概念。它不是某个产品、框架或编程语言,而是对系统组成、连接方式、控制关系和约束规则的抽象。常见风格包括数据流风格、调用/返回风格、分层风格、数据中心风格、事件驱动风格、客户端/服务器风格、面向服务风格和微服务风格等。考试不会只让考生背名称,更会要求根据性能、可维护性、可扩展性、实时性和安全性选择适合的风格,并说明代价。
二、什么是架构风格
架构风格是对一类系统在组件类型、连接器类型、控制方式、数据组织和约束方面的共同模式进行抽象。它规定了系统“允许怎样组织”,但不等于某个具体系统的完整设计。
一个架构风格通常包含四部分:
- 组件集合:系统中允许出现哪些类型的计算、存储或交互单元。
- 连接器集合:组件通过什么方式通信,如调用、消息、数据流、事件或共享数据。
- 约束集合:组件如何连接、谁可以调用谁、数据如何流动、控制权如何转移。
- 语义原则:这种组织方式希望获得什么性质,如复用、可扩展、低耦合、实时或数据共享。
例如,分层风格要求系统由多个层次组成,每层主要依赖相邻层;管道-过滤器风格要求数据依次通过多个处理组件;事件驱动风格要求组件通过事件发布和订阅协作。风格提供结构约束,具体组件、接口和部署仍需结合业务设计。
三、架构风格、架构模式与技术实现的区别
1. 架构风格
架构风格是较高层次的组织原则,强调系统结构的类别和约束。例如分层、事件驱动、数据中心和调用/返回。
2. 架构模式
架构模式是针对某类重复问题的可复用解决方案,通常比风格更具体,例如 MVC、微内核、发布-订阅、主从复制、六边形架构和 CQRS。一个模式可能建立在某种风格之上,也可能组合多个风格。
3. 技术实现
技术实现是使用具体产品、框架、协议和部署方案落地,例如使用消息队列实现发布-订阅,使用容器实现服务部署,使用数据库实现数据中心。技术产品可以替换,架构风格和模式的决策应保持独立。
| 层次 | 关注问题 | 示例 |
|---|---|---|
| 架构风格 | 系统整体如何组织 | 分层、事件驱动、数据流 |
| 架构模式 | 如何解决常见结构问题 | MVC、微服务、发布-订阅 |
| 技术实现 | 用什么技术落地 | API、消息队列、容器、数据库 |
考试答题时不要把“采用 Kafka”当成架构风格,也不要把“采用微服务”写成无需解释的万能答案。应说明风格和模式解决的质量问题,以及技术选择如何支撑它。
四、架构风格的作用
1. 降低设计复杂度
面对复杂系统,风格提供共同词汇和结构边界,使架构师可以从已知经验出发,而不是每次从零开始设计。风格还能够帮助团队理解组件职责和依赖方向。
2. 支持质量属性
不同风格对性能、可维护性、可扩展性、可靠性和安全的影响不同。例如分层有利于职责隔离和替换,事件驱动有利于解耦和异步扩展,数据中心有利于共享一致数据,管道风格有利于复用处理步骤。
3. 形成设计约束
没有约束的“灵活架构”容易变成任意依赖。风格规定组件关系、接口方式和数据流向,有助于限制不合理连接,减少架构腐化。
4. 促进评审和演进
架构评审可以检查系统是否遵守选定风格,演进时也可以判断新功能是否破坏原有边界。风格并非不可变化,但变化要有理由、影响分析和迁移计划。
五、数据流风格
数据流风格以数据变换为核心,数据从输入经过一个或多个处理组件,逐步形成输出。处理组件关注输入、转换和输出,组件之间通过数据流连接。
1. 管道-过滤器风格
管道是数据传递通道,过滤器是独立的数据处理单元。每个过滤器完成一个相对明确的转换,多个过滤器可以串联、复用和替换。
优点:处理步骤清晰,组件复用性高,便于并行处理、批处理和测试;一个过滤器的变化通常不影响其他过滤器。
缺点:不适合需要复杂共享状态、交互式事务和随机访问的场景;数据格式转换会增加开销,错误处理和事务回滚较复杂。
典型应用:编译器、日志处理、ETL、视频处理、数据清洗和流式分析。
2. 批处理风格
批处理将输入数据按批次收集,经过一个或多个处理阶段后产生结果。它适合结算、报表、离线分析和大规模数据转换。架构关注作业依赖、窗口、重跑、断点、幂等和结果校验。
3. 数据流风格的案例判断
如果题目强调“原始数据经过清洗、转换、聚合、分析后输出结果”,可以考虑数据流或管道-过滤器;如果强调订单状态、审批、回滚和用户交互,则需要结合调用/返回或事务风格,不能只使用数据流。
六、调用/返回风格
调用/返回风格以过程、函数、服务或对象之间的请求和响应为主要连接方式。调用者发起调用,被调用者处理后返回结果,控制权通常在调用链中传递。
1. 主程序/子程序
主程序控制整体流程,调用多个子程序完成任务。结构简单、易于理解,适合流程清晰的应用,但模块耦合可能随调用层次增加而增强,复用和并行扩展能力有限。
2. 面向对象风格
系统由对象组成,对象封装状态和操作,通过消息或方法调用协作。面向对象有助于封装、复用、继承和多态,但对象关系复杂时可能产生循环依赖和共享状态问题。
3. 分层风格
分层风格将系统组织为多个层次,每层为上层提供服务并依赖下层。常见有表现层、业务层、数据访问层和基础设施层。
优点:职责清晰、便于替换和维护、适合团队分工和安全隔离。
缺点:跨层调用链较长,可能影响性能;如果边界不清,会出现业务逻辑泄漏、层次穿透和“贫血”设计;严格分层不一定适合所有实时和高性能场景。
分层设计需要明确依赖方向、接口、事务边界和跨层数据模型。不能因为分了四个包就称为良好分层。
4. 客户端/服务器风格
客户端发起请求并负责部分交互,服务器集中提供数据和服务。两层和三层 C/S 架构适合集中管理和资源共享,但需要管理客户端版本、服务器容量和网络连接。浏览器/服务器架构降低了客户端部署成本,但服务器和网络成为关键依赖。
七、数据中心风格
数据中心风格以共享数据存储或数据管理系统为核心,多个计算组件通过统一数据中心交换信息。典型形式包括共享数据库、仓库、黑板系统和数据湖。
1. 共享数据库风格
多个应用通过统一数据库共享数据,优点是数据集中、一致性和查询方便;缺点是应用与数据结构紧耦合,数据库可能成为性能和可用性瓶颈,任何表结构变更都可能影响多个应用。
2. 黑板风格
多个知识源围绕一个共享黑板协作,知识源根据黑板状态读取和写入信息,控制组件决定下一步处理。适合复杂问题求解、专家系统和多源推理,但共享状态、调度和并发冲突较难管理。
3. 数据中心风格的选型
当多个业务需要共享权威数据、进行复杂关联和统一事务时,数据中心风格有优势;当服务需要独立演进、不同数据所有权和高弹性时,强共享数据库会增加耦合,应考虑服务自治、事件和数据复制。
八、事件驱动风格
事件驱动风格中,组件通过发布、传递和订阅事件进行协作。事件描述已经发生的事实,生产者不必直接知道所有消费者,消费者可以异步处理。
1. 发布-订阅
生产者发布事件到主题或代理,多个消费者订阅并独立处理。优点是解耦、异步、易扩展和便于新增消费者;缺点是流程可见性下降,事件顺序、重复、延迟和最终一致性需要治理。
2. 事件流处理
事件按时间或分区进入流处理组件,系统进行窗口、聚合、关联和告警。适合日志、物联网、交易风控和实时分析。架构要设计分区键、顺序、幂等、重试、死信、回溯和状态存储。
3. 事件驱动的风险
事件不是命令,消费者不能假设所有事件都按一次、按顺序到达。关键业务需要事件唯一 ID、版本、幂等处理和补偿;跨服务事务要明确最终一致性和业务可接受的中间状态。
九、面向服务和微服务风格
面向服务风格把业务能力封装成可发现、可调用和可组合的服务,通过标准接口协作,强调复用、松耦合和组织间集成。微服务进一步强调按业务边界拆分、独立部署、自治团队和自动化交付。
1. 适用条件
适合组织规模大、业务变化快、多个团队并行开发、部分能力需要独立扩展或多渠道复用的系统。
2. 主要代价
网络调用、服务治理、数据一致性、分布式事务、链路追踪、测试、发布和运维复杂度增加。微服务并不自动带来高性能和高可用,错误拆分可能比单体更难维护。
3. 设计原则
根据业务能力、数据所有权和变更边界拆分;服务接口以业务契约为核心;避免跨服务共享数据库;对关键链路设置超时、重试、熔断、限流和降级;引入统一观测和发布治理;保持服务粒度适中。
十、解释器、规则和插件风格
解释器风格将规则、脚本或领域语言作为输入,由解释器执行。它适合可配置流程、规则引擎、查询和策略系统,可以减少频繁修改核心代码。
插件或微内核风格把最小核心能力与可替换扩展分开。核心提供稳定接口,插件提供具体功能。适合 IDE、操作系统、设备能力和可扩展平台,但需要管理插件兼容性、权限、生命周期、版本和故障隔离。
规则与插件可以增强信息系统的灵活性,但灵活性不能突破安全和治理边界。规则冲突、脚本恶意行为和插件资源耗尽都需要检测、审批和回退。
十一、架构风格选择方法
1. 从业务场景出发
明确系统是事务处理、实时控制、数据分析、开放服务、复杂交互还是多方协同。不同场景对调用、数据、事件和时延的偏好不同。
2. 从质量属性出发
把性能、可用、可扩展、可维护、安全、数据一致性和演进要求转成场景。然后比较候选风格如何满足,以及需要付出什么代价。
3. 从组织和运维能力出发
微服务需要团队自治、自动化交付和可观测性;事件驱动需要消息治理和最终一致性经验;共享数据库需要严格数据和变更管理。组织没有相应能力时,复杂风格可能增加风险。
4. 从现有系统和迁移出发
既有数据库、接口、人员和供应商是现实约束。可以采用混合风格和渐进式演进,不必强行一次性换成目标风格。
5. 记录权衡和验证
记录选择原因、备选方案、风险、假设和验证方法。通过原型、性能测试、故障演练和用户试点验证风格是否适合。
十二、架构风格组合
真实系统通常采用组合风格:外部入口采用客户端/服务器和分层风格,内部服务采用面向服务和事件驱动,实时数据采用管道-过滤器,核心交易使用事务和共享数据库,分析使用数据中心或数据湖,插件机制支持领域扩展。
组合时要避免风格冲突。例如,事件驱动的异步流程与同步事务边界要明确;微服务独立数据与跨服务报表要采用数据复制或分析平台;实时控制与中心事件处理要区分安全闭环。架构图不仅要标识组件,还要说明不同风格在什么边界内生效。
十三、案例分析:电商平台架构风格选择
某电商企业有商品、购物车、订单、支付、库存、履约和推荐业务。促销高峰时订单量快速增长,推荐和搜索需要独立扩展,订单和支付要求正确,库存变化需要及时通知多个下游系统。团队计划“全部采用微服务和事件驱动”。
问题一:如何组合架构风格?
参考答案:用户入口和 API 采用客户端/服务器与分层风格;商品、订单、支付、库存和履约按业务能力进行服务化;订单和支付关键步骤采用同步调用与明确事务、幂等和状态机;订单创建、支付成功、库存扣减和发货等事实通过事件通知下游;搜索和推荐使用独立数据索引和分析数据;高频日志与行为数据使用流处理。不能所有流程都异步化,也不能所有服务共享订单数据库。
问题二:事件驱动需要解决哪些一致性问题?
参考答案:事件可能重复、乱序、延迟或丢失,需要唯一 ID、幂等消费、重试、死信和补偿;订单状态与支付状态可能短暂不一致,应定义状态机和用户可见状态;库存扣减要有并发控制和预占策略;关键事件需可靠发布和审计,最终一致不等于无条件接受错误状态。
问题三:为什么不能只写“微服务提高扩展性”?
参考答案:微服务把系统拆成分布式组件,虽然部分服务可独立扩展,但也引入网络、运维、数据一致性、测试和链路复杂度。是否采用要看团队、自动化交付、观测、故障治理和业务边界;要通过峰值压测、故障注入和发布演练证明收益。
十四、综合知识练习
题1
架构风格包含哪些基本内容?
参考答案:组件类型、连接器类型、组织约束、控制方式、数据组织方式和共同语义原则。风格通过这些内容规定系统允许的结构,并影响性能、维护和演进。
题2
什么时候适合采用管道-过滤器风格?
参考答案:数据需要经过多个相对独立的转换、清洗、分析或编译步骤,处理过程可串联、复用或并行时适合。交互式事务、复杂共享状态和需要整体回滚的场景不宜单独使用。
题3
事件驱动系统为什么必须考虑幂等和补偿?
参考答案:消息可能重复、延迟、乱序或部分失败,消费者如果重复执行会造成重复扣款、重复发货等问题;幂等避免重复副作用,补偿处理跨服务中间状态和失败,使最终业务结果可恢复。
题4
选择微服务风格时应评估哪些条件?
参考答案:业务边界和变化频率、团队规模与自治、独立扩展需求、自动化交付、可观测性、数据一致性、分布式事务、运维能力、成本和迁移风险。不能只看技术流行程度。
十五、论文写作素材
论文可以围绕“面向电商或企业平台的架构风格选择”展开。写作时先描述关键场景和质量属性,再说明为什么组合分层、调用/返回、事件驱动、数据中心和微服务,而不是笼统写“采用先进架构”。要写出风格带来的约束、代价、治理和验证。
可使用如下段落:
“本项目没有采用单一架构风格,而是根据不同业务闭环进行组合。外部访问和核心交易采用分层与调用/返回风格,保证接口契约、校验和事务状态清晰;订单事实通过发布-订阅向库存、履约和营销服务传播,降低直接依赖;搜索和推荐使用独立数据处理管道,避免分析负载影响交易数据库;服务按照业务能力和数据所有权拆分,并通过超时、幂等、重试、熔断、链路追踪和统一发布治理控制分布式代价。通过高峰压测、消息重复、服务故障和数据对账验证风格组合是否满足质量目标。”
十六、今日复盘
- 架构风格是对组件、连接器、约束和共同组织原则的抽象,不是具体产品或框架。
- 常见风格包括数据流、调用/返回、分层、数据中心、事件驱动、客户端/服务器和面向服务。
- 风格选择必须从业务场景、质量属性、组织能力、现有系统和迁移路线出发。
- 事件驱动要处理重复、乱序、延迟、最终一致和补偿;微服务要处理分布式运维和数据边界。
- 真实信息系统通常组合多种风格,并在不同边界内明确适用范围。
- 案例和论文要写“风格选择依据—收益—代价—治理—验证”,不能只罗列技术名词。
本节的核心结论是:架构风格不是装饰系统的标签,而是一组会影响结构、质量和演进的约束。优秀的架构师不是寻找唯一最先进的风格,而是根据业务和风险选择恰当的结构,并让团队能够长期遵守和验证这些约束。