本系列文章通过逐章回答《Fundamentals of Software Architecture》(下文简称 FOSA)一书中的课后思考题,来深入理解书中的核心概念和理论,从而提升我们的软件架构设计能力。本篇为第五章内容。

本章的课后题是:

  1. Give a reason why it is a good practice to limit the number of characteristics (“-ilities”) an architecture should support.

    举一个例子来说明为什么限制系统中支持的架构特性的数量的有必要的。

  2. True or false: most architecture characteristics come from business requirements and user stories.

    大多数的架构特性都来自于业务需求和用户故事,这对吗?

  3. If a business stakeholder states that time-to-market (i.e., getting new features and bug fixes pushed out to users as fast as possible) is the most important business concern, which architecture characteristics would the architecture need to support?

    如果一个业务利益相关者将上市时间(比如以最快的速度实现新功能和修复 BUG)视为最重要的需求点,这个时候需要支持什么样的架构特性?

  4. What is the difference between scalability and elasticity?

    可伸缩性(scalability) 和弹性(elasticity)的区别是什么?

  5. You find out that your company is about to undergo several major acquisitions to significantly increase its customer base. Which architectural characteristics should you be worried about?

    如果你发现了你的公司进行了几次重大收购以大幅增加其客户群,这个时候你应该考虑什么架构特性?


架构特性不是越多越好

  • 增加系统设计的复杂性:每增加一个架构特性,都会使整个系统设计变得更加复杂。支持过多的架构特性会导致在架构师和开发人员开始解决核心业务问题之前,系统就变得越来越复杂。
  • 分散对核心问题的关注:架构特性定义了系统的成功标准,通常与系统的功能性正交,关注的是“如何”实现需求以及“为什么”做出某些选择。然而,如果过度追求特性数量,可能会导致偏离原始的业务问题,即开发软件的最初动机。
  • 每个特性都涉及权衡:软件架构中的每一个方面都存在权衡,有优点也有缺点。例如,在拍卖系统中,选择使用主题(topic)进行通信可能带来架构可扩展性的优势和服务的解耦,但会引入数据访问和数据安全方面的潜在问题,并且不支持异构契约。而使用队列(queue)则允许每个消费者拥有自己的契约,但不具备可扩展性,并且会增加服务间的耦合。架构师需要分析这些权衡,并根据业务驱动因素和环境选择最重要的特性。
  • 过度规范的危害:架构师过度规范架构特性是常见的陷阱,其破坏性不亚于规范不足,因为它会使系统设计过于复杂。历史案例“瓦萨号”战舰的失败就是一个例证,它是因为过度追求建造最宏伟的战舰(即过度规范架构特性)而最终导致沉没。
  • 陷入“意外复杂性”陷阱:架构师有时会为解决方案、图表和文档添加不必要的复杂性。正如一位作者所言,“开发者被复杂性吸引,就像飞蛾扑火一样——结果往往相同”。这种“意外复杂性”是由于人为地使问题复杂化,而不是问题本身固有的复杂性。通过识别子领域类型并根据其业务逻辑的复杂性选择合适的实现模式(例如,事务脚本和活动记录适用于简单业务逻辑,而领域模型和事件溯源领域模型适用于复杂的核心子领域),可以避免引入不必要的复杂性。
  • 设计应由业务驱动:领域驱动设计(DDD)的核心思想在于让业务领域驱动软件设计决策。这意味着设计决策应该基于业务领域的需求和战略,而非盲目地堆砌所有可能的架构特性。

因此,与领域利益相关者合作时,架构师应努力使最终的架构特性列表尽可能短,因为每个特性都会增加总体系统设计的复杂性。

如何识别架构特性

  1. 从领域焦点中识别架构特性
  2. 从业务需求中识别架构特性

这里面的一大难点就是:业务方与开发方使用的不是同一种"语言"。双方对同一件事情的关注点是不一样的,所以表述出来的述求,也是不同的。

所以在识别架构特性的时候,架构师的职责就是需要将业务领域的关注点和架构特性进行对应。比如:

Domain Concern Architecture characteristics
Mergers and acquisitions 合并与收购 互操作性 interoperability
可扩展性 scalability
适配性 adaptability
可扩展性 extensibility
Time to market 上市时间 灵活性 agility
可测试性 testability
可部署性 deployability
User satisfaction 用户满意度 性能 performance
可用性 availability
容错性 fault tolerance
可测试性 testability
可部署性 deployability
灵活性 agility
安全性 security
Competitive advantage 竞争优势 灵活性 agility
可测试性 testability
可部署性 deployability
可扩展性 scalability
可用性 availability
容错性 fault tolerance
Time and budget 时间和预算 简单性 simplicity
可行性 feasibility

另外, 随着业务的发展,关注点也是在不断发生变化的,这个时候,架构所侧重的架构特性也是随之改变的。

可扩展性 vs 弹性

  • 可伸缩性(Scalability)指的是系统在用户或请求数量增加时,仍然能够维持性能和运行的能力。它衡量的是系统在负载线性增加时,性能是否能够保持相应的线性增长。例如,如果一个系统在用户增加一倍时,其性能也能线性提升,那么它就是可伸缩的。这通常通过增加资源(如服务器实例)来实现,以应对持续增长的用户数量。
  • 弹性(Elasticity)指的是系统处理请求突发性增长的能力。它关注的是系统如何有效地应对不可预测和可变的用户流量高峰。例如,音乐会售票系统在门票开售时会经历用户流量的突然飙升,这需要高弹性的支持。一个具有弹性的系统能够在流量高峰时动态地启动新的处理单元(Processing Units),并在负载降低时关闭它们

简而言之,可伸缩性是关于处理增加的负载并保持性能,而弹性是关于处理突发性、不可预测的负载波动。