读书笔记:软件架构实践

软件架构实践, Len Bass

第一部分 入门介绍

第1章 什么是软件架构 1

1.1 什么是软件架构,什么不是软件架构 2

1.架构是一组软件结构
架构结构可以分为三个有用的类别,
1)组件及连接器结构
2)模块结构
3)分配结构

架构结构的集合既不是固定的,也不是有限的。什么是架构取决于在系统上下文的推理中什么是有用的。

2.架构是一种抽象
架构关注的是公共部分;元素的私有部分(仅与内部实现有关的细节)与架构无关我们希望且需要的是,理解系统的架构要比理解系统的每个细节容易很多个数量级。
3.架构与设计
架构是设计,但并不是所有的设计都是架构。也就是说,许多设计决策不受架构的约束,
6.架构包括行为
架构师不必关注元素的所有行为。然而,当个元素 的行为影响 了整个系统的可接受性时,这个行为必须被认为是系统架构设计的一部分, 并被记录下来。

系统架构和企业架构
企业架构
企业架构是对组织的过程、信息流、人员、组织单元的结构和行为的描述。

1.2 架构结构与视图 5

架构结构本质上要有对应的东西。例如,神经科医生、骨科医生、血液科医生和皮肤
科医生对人体的不同结构都有不同的看法。

1.三种结构
1)组件及连接器( Component-and-Connector, C&C)结构:
2)模块结构: 模块结构中的模块之间的关系包括使用( use)、泛化“is-a”)和“是一部分”(is partof)。
3)分配结构:
每个软件元素在哪些处理器上执行?
在开发、测试和系统构建期间,每个元素存储在哪个目录或文件中?
每个软件元素分配给开发团队的任务是什么?

层结构。这种结构中的模块称为层。层是一个抽象的“虚拟机”。 层以可管理的方式使用其他层;在严格分层的系统中,一层只允许使用其他层中的一个。

3.一些有用的C&C结构
所有的C&C结构与基于模块的结构是正交的,

C&C结构中的关系都是依附( atachment),显示了组件和连接器是如何勾连在一起的。(连接器本身可以是“调用”这种常用的结构。)有用的C&C结构包括:

  • 服务结构。这里的单元是指通过服务协同机制(比如消息)进行互操作的服务。
  • 并发结构。

4.一些有用的分配结构
分配结构定了来自C&C或模块结构的元素如何映射到非软件——通常是硬件(可能是虚拟化的)、团队和文件系统。有用的分配结构包括:

  • 部署结构。部署结构显示了如何将软件分配给处理器和通信器件等硬件。
  • 实现结构。该结构显示软件元素 (通常是模块)如何映射到系统的开发、集成、测试或配置管理环境中的文件结构。
  • 工作分配结构。这种结构用于将实现和集成模块的任务分配给相关团队。例如,亚马逊的工作分配结构是为每项微服务配备一个团队。 在大型开发项目中,识别公共功能单元并将其分配给单个团队,而不是让每个需要它们的人来实现它们,这是很有用的。这种结构也将决定团队之间的主要沟通途径:定期的网络会议、wiki、 电子邮件列表等。

表1.1 有用的架构结构

软件结构 元素类型 关系 用于 影响的质量属性
模块结构 分解结构 模块 是...的子模块 资源分配以及项目构建和规划;封装 可修改性
使用结构 模块 使用(即请求正确存在..... ) 设计子集和扩展 可分解性、可扩展性
层结构 允许使用....服务;为..提供抽象 增量式开发;在“虚拟机” 上实现系统 可移植性、可修改性
类结构 类、对象 是....的实例;是对....的泛化 在面向对象的系统中,分解出共性:规划功能扩展性 可修改性、可扩展性
数据模型结构 数据实体 {1,多}对{1,多};泛化:具体化 为一致性和性能设计全局数据结构 可修改性、性能
C&C结构 服务结构 服务、服务注册 依附(通过消息传递) 调度分析;性能分析;鲁棒性分析 互操作性、可用性、可修改性
并发结构 进程、线程 依附(通过通信和同步机制) 确定存在资源争抢的位置,实现并行的时机 性能

1.3 什么是“好的”架构 19

我们把观察分成两组:过程建议和产品(或结构)建议。我们的过程建议如下:
1)软件(或系统)架构应该是单个架构师或技术领导带领的一小组架构师的产品。架构师和开发团队之间应该有很强的联系,以避免不切实际的“象牙塔”设计。
2)架构师(或架构团队)应该在持续的基础上,将架构建立在明确的质量属性需求的优先级列表上,这意味着要经常进行权衡。功能需求没那么重要。
3)应该使用视图来记录架构。
5)架构应该增量实现。一种方法是通过创建一个“骨架"系统,在这个“骨架”系统中,通信路径可用,但最初只有最小的功能。

1.4 总结 21
1.5 进一步阅读 21
1.6 问题讨论 22

第2章 软件架构的重要性 25

2.1 抑制或支持系统的质量属性 26

系统满足其期望的(或要求的)质量属性的能力实质上是由架构决定的。

  • 高性能。你需要关注管理元素基于时间的行为,它们对共享资源的使用以及元素间通信的频率和数量。
  • 可修改性。你需要关注将责任分配给元素,并限制这些元素的交互(耦合)。理想情况下,每个变更将只影响单个元素。
  • 高度防护。你需要管理和保护组件间的通信,并控制哪些组件可以访问哪些信息。授权机制来设置一个强大的“边界”以防止入侵。
  • 安全可靠,你需要保障措施和恢复机制。
  • 性能的可伸缩性。你需要将资源的使用本地化,以便引人更高容量资源来替换。
  • 交付系统增量子集,你必须管理组件间的使用。
  • 可重用。你需要限制元素间的耦合,这样当你提取一个元素时,它不会带出太多与当前环境相关的内容。

糟糕的下游设计或实现决策总是会破坏合理的架构设计。就像我们常说的那样(多半是开玩笑):架构给予什么,实现就拿走什么。软件生命周期的所有阶段(从架构设计到编码、实现和测试)的决策都会影响系统质量。因此,质量并不完全是架构设计的一个功能, 但它是起点。

2.2 关于变更的推理和管理 27

软件开发社区开始认识到这样一个事实:一个典型的软件系统大约80%的总成本发生在初始部署之后。

2.3 预测系统质量 28

2.4 利益相关者之间的沟通 28

软件系统的每一个利益相关者(客户、用户、项目经理、编码人员、测试人员等)都与受架构影响的不同系统特征有关。例如:

  • 用户关心系统是否快速、可靠且在需要时可用。
  • 客户(为系统付费的人)关心架构可以按计划和预算实施。
  • 管理者关心架构(除了成本和进度方面之外)是否最大限度允许团队独立工作,以有纪律和受控的方式进行交互。
  • 架构师关心实现所有这些目标的策略。

2.5 早期设计决策 31
2.6 实现约束 31
2.7 对组织结构的影响 32
2.8 赋能增量开发 33
2.9 成本和进度估算 33
2.10 可转移、可重用模型 34
2.11 架构允许合并独立开发的元素 34
2.12 限制设计方案的术语 35
2.13 培训的基础 36
2.14 总结 36
2.15 进一步阅读 37
2.16 问题讨论 37

第二部分 质量属性

第3章 理解质量属性 39

3.1 功能性 40
3.2 质量属性注意事项 41

3.3 明确质量属性需求:质量属性场景 42

质量属性场景由六个部分组成:

  • 刺激。我们使用术语“刺激”来描述到达系统或项目的事件。刺激可以是性能社区的事件、易用性社区的用户操作或防护性社区的攻击,等等。
  • 来源。刺激必须有源头,它必须来自某个地方。
  • 响应。响应是刺激到达后发生的活动,是架构师承诺要满足的内容。
  • 响应度。当响应发生时。它应该是可度量的。
  • 环境。环境是场景发生时所处的状况,通常是指系统运行时状态。
  • 制品。刺激到达的某个目标。这通常是指系统或项目本身,但如果可能的话,更精确一些是有帮助的。

3.4 通过架构模式和战术实现质量属性 45
3.5 用战术设计 46
3.6 分析质量属性的设计决策:基于战术的调查问卷 48
3.7 总结 49

3.8 进一步阅读 49

在Frank Buschmann等人的五卷集《面向模式的软件体系结构》(Pattern-Oriented Sofware Architecture)中可以找到内容充实的架构模式目录。

3.9 问题讨论 50

第4章 可用性 51

系统与其规格之间的偏差称为失效,这种偏差在外部是可见的,而且有明确的外部观察者。
失效的原因叫作故障。

系统的可用性可以通过在指定的时间间隔内提供服务的概率来街量。一个众所周知的用来推导稳态可用性(来自硬件领域)的表达式为:
$$MTBF/(MTBF+MTTR)$$
其中,MTBF ( Mean Time Between Failures)指系统平均失效间隔,MTTR ( Mean Time To Repair)指平均修复时间。
依据公式,我们可以计算概率,并做出类似“系统表现出99.999%的可用性”或“系统无法正常操作的概率为0.001%”这样的声明。在计算可用性时,不应考虑计划停机时间(提前安排好的停机),因为那时系统被认为“无须运行”;当然,这取决于系统的特定需求,这些需求通常约定在服务水平协议( Service Level Agreement, SLA)中。

4.1 可用性通用场景 53

4.2 可用性战术 55

可用性战术的目标是使系统能够防止或忍受系统故障,从而使系统交付的服务仍然符合其规格。
因此作为架构师,你的工作可能是选择和评估(而不是实现)正确的可用性战术和战术的正确组合。

1.故障检测
在任何系统对故障采取行动之前,必须检测到故障的存在或预测到故障的存在。

  • pingeho在这种战术中,节点之间交换异步请求/响应消息对,用于确定通过相关网络路径的可达性和往返延迟。
  • 心跳。这种故障检测机制在系统监视器和被监视的进程之间进行周期性的消息交换。心跳和ping/echo之间的区别在于谁负责启动检查——是监视器还是组件本身。
  • 异常检测。参数围栏战术使用一个已知的数据样本(例如0xDEADBEEF),将该样本放置在对象任何可变长参数之后,用于在运行时检测访问是否覆盖了对象可变长参数分配的内存。

2.故障恢复

  • 冗余备份。这种战术指的是一种配置, 在这种配置中,如果主组件发生故障,一个或多个备份组件可以介人并接管工作。这种战术是热备、温备和冷备模式的核心,它们的主要区别在于接管时备份组件的更新程度。
  • 回滚
  • 重试。常被用于网络和服务器集群中。
  • 事务。事务战术最常见的实现是“两阶段提交(two-Phase Commit, 2PC)协议这种战术可以防止两个进程同时更新相同数据导致的竞争情况。

4.3 基于战术的可用性调查问卷 62

4.4 可用性模式 66

  • 活动冗余(热备)。因为冗余备份组件拥有与活动组件相同的状态,所以它可以在大约几毫秒的时间内接管故障组件。
  • 备份(冷备)。在冷备的配置中,冗余备份在故障转移发生之前一直处于停止服务状态,此时,在冗余备份投人服务之前,需要启动开机复位过程。

4.5 进一步阅读 68
4.6 问题讨论 69

第5章 可部署性 71

5.1 持续部署 72
5.2 可部署性 75
5.3 可部署性通用场景 76

5.4 可部署性战术 78

2.完全替代服务的模式
基于规模递增部署战术。
1)蓝/绿部署。
2)滚动升级。实践中,一次可以替换多个实例, 但每步只能替换一小部分。
3.部分替代服务的模式
(1)金丝雀测试
(2) A/B测试
在金丝雀测试中,DNS 服务器和服务发现配置被设置为向不同的版本发送客户端请求。在A/B测试中, 要对不同的版本进行监视, 以便从业务角度选出哪 个版本提供了最佳响应。

5.5 基于战术的可部署性调查问卷 80
5.6 可部署性模式 81
5.7 进一步阅读 87
5.8 问题讨论 87

第6章 能源效率 89

6.1 能源效率通用场景 90
6.2 能源效率战术 92
6.3 基于战术的能源效率调查问卷 95
6.4 模式 97
6.5 进一步阅读 98
6.6 问题讨论 99

第7章 可集成性 101

7.1 评估架构的可集成性 102
7.2 可集成性通用场景 104

7.3 可集成性战术 105

  1. 限制依赖关系
    1. 封装
    2. 使用中介
    3. 限定通信路径
    4. 遵守标准
    5. 抽象公共服务
  2. 适配
    1. 发现
    2. 裁剪接口
    3. 配置行为
  3. 协调
    1. 编排
    2. 管理资源

7.4 基于战术的可集成性调查问卷 110

7.5 可集成性模式 112

  • 包装器。包装器是一种封装形式。

1.面向服务的架构模式
服务之间的通信通常使用如Web服务描述语言( Web Services Description Language, WSDL)或简单对象访问协议( Simple Object Access Protocol, SOAP) 等Web服务协议来执行。

2.动态发现
动态发现的注册和注销必须是自动化的,因此要开发相应的工具。

7.6 进一步阅读 114
7.7 问题讨论 115

第8章 可修改性 117

一个简化的变更机制判断公式是:
N × 不采用该机制的变更成本≤ 创建机制的成本+ (N × 使用机制进行变更的成本)
这里,N是使用可修改性机制进行修改的预期数量——但它也是一个预测。 如果出现的变更比预期的少,可能不会引入昂贵的修改机制。此外,创建可修改性机制的成本可以
应用到其他地方(机会成本)——添加新功能, 改进性能,甚至是非软件投资,如招聘或培训。

特定的可修改性赋予了特殊的名称:

  • 可扩展性用于容纳更多内容。水平可扩展性(向外扩展)指的是向逻辑单元添加更多资源,例如向服务器集群添加新服务器。垂直可扩展性(向上扩展)是指向物理单元添加更多资源,例如向单个计算机添加更多内存。
  • 可变性是指系统及其支撑制品(如代码、需求、测试计划和文档)以预先计划的方式生成一组彼此不同的变体的能力。软件产品线中的可变性目标是在一段时间内让构建和维护系列产品变得容易。
  • 可移植性是指在一个平台上运行的软件可以改为在另一个平台上运行的难易程度。

8.1 可修改性通用场景 120

8.2 可修改性战术 121

可修改性战术的控制目标是控制变更的复杂性以及进行变更的时间和成本。
我们可以通过测量一个模块的变更传播到另一个模块的概率来量化这种重叠。这种关系称为耦合。
内聚用于度量-一个模块的职责之间的关系有多紧密。内聚性越高,给定变更影响多个模块的可能性就越低。

可修改性战术:

  • 增加内聚性
    • 拆分模块
    • 重新分配职责
  • 减少耦合性
    • 封装
    • 使用中介
    • 抽象公共服务
    • 限制依赖关系
  • 延迟绑定
    • 组件替换(例如,在构建脚本或makefile中)
    • 编译参数
    • 方面
    • 配置时绑定
    • 资源文件
    • 发现
    • 解释参数
    • 共享库
    • 多态性

8.3 基于战术的可修改性调查问卷 125

8.4 模式 126

1.客户机-服务器模式
以大观明型性(特别是机密性)并保持完整性。
2.插件(微核)模式
插件模式包含两种类型的元素——提供核心功能集的元素和通过一组固定接口添加功能的专门变体(称为插件)。
4.发布-订阅模式
发布者不知道订阅者,订阅者只知道消息类型。使用发布-订阅模式的系统依赖于隐式调用,也就是说,发布消息的组件不会直接调用任何其他组件。

8.5 进一步阅读 130

在《软件系统体系结构:使用视点和视角与利益相关者合作》( Software Systems Architecture: Working With Stakcholders Using Viewpoints and Perspectives) 中给出了更多的可修改性模式。

8.6 问题讨论 131

第9章 性能 133

9.1 性能通用场景 134

性能场景从事件到达系统开始。正确响应事件需要消耗资源(包括时间)。需要注意这种场景下,系统可能同时为其他事件提供服务。

9.2 性能战术 137

  • 控制资源需求
    • 管理工作请求
    • 限制事件响应
    • 事件优先级
    • 减少计算开销
    • 限定执行时间
    • 提高资源利用率
  • 管理资源
    • 增加资源
    • 引人并发
    • 保持多个计算副本
    • 保持多个数据副本
    • 限定队列大小
    • 调度资源

调度策略
调度策略在概念上有两部分:优先级分配和分派。
常见的调度策略如下:

  • 先进先出。
  • 固定优先级调度。
  • 动态优先级调度。
    • 轮询。
    • 最早截止优先。
    • 最少空闲优先。

9.3 基于战术的性能调查问卷 145

9.4 性能模式 146

  1. 服务网格。网格模式已在微服务架构中采用。网格的主要特征是sidecar——一种伴随每个微服务的代理,用于处理与应用功能无关的大量公共功能,如服务间通信、监视和防护性。
  2. map-reduce。

map-reduce模式由三部分组成:

  • map函数以一个键和一个数据集作为输人。它使用该键将数据散列到一组bucket中。假设我们的数据集由扑克牌组成,那么键值就可能是花色。
  • 所有繁重的分析都在reduce函数中进行。reduce实例的数量对应于map函数输出的bucket的数量。reduce 阶段执行一些程序员指定的分析,然后发出分析的结果。例如,我们可以计算梅花、方块、红桃和黑桃的数量。

9.5 进一步阅读 149

  • Foundations of software and system performance engineering: process, performance modeling, requirements, testing, scalability, and practice ISBN: 9780321833822这本书提供了性能工程的全面概述,从技术实践到组织实践。
  • Software Performance and Scalability : A Quantitative Approach。这本书涵盖了面向企业应用程序的性能,重点介绍了队列理论和度量。
  • 《软件性能工程》(Peformance Solutions : A Pracical Guide to Creating Reponsive,Scalable Software)) 。这本书涵盖了性能设计,重点是构建实用的预测性能模型(并使用真实数据)。

9.6 问题讨论 150

第10章 安全性 151

10.1 安全性通用场景 154
10.2 安全性战术 156
10.3 基于战术的安全性调查问卷 160
10.4 安全性模式 163
10.5 进一步阅读 165
10.6 问题讨论 166

第11章 防护性 169

描述防护性最简单的方法集中于CIA (CIA-Cofientiality, Integrity, Availability) 特征上,即机密性、完整性和可用性:

  • 机密性是指保护数据或服务不受未经授权访问的属性。例如,防止黑客在政府系统上访问你的纳税申报表。
  • 完整性是指保护数据或服务不受未经授权篡改的属性。例如,你的成绩在老师判定后是不能被篡改的。
  • 可用性是指系统被合法使用的属性。例如,拒绝服务攻击不会阻止你从在线书店订购这本书。

11.1 防护性通用场景 170

11.2 防护性战术 172

  • 检测攻击
    • 检测人侵
    • 检测拒绝服务
    • 验证消息完整性
    • 检测消息传递异常
  • 抵抗攻击
    • 标识参与者
    • 验证参与者。密码、一次性密码、数字证书。另一个例子是CAPTCHA (Completely Automated Public Turing test to tell Computers and Humans Apart,区分计算机和人类的完全自动化公共图灵测试)。
    • 授权参与者
    • 限制访问
    • 限制暴露
    • 加密数据
    • 隔离实体
    • 验证输人。数据验证是防范SQL注人(恶意代码被插人SQL语句中)和跨站脚本(XSS)等攻击的主要形式,XSS是指来自服务器的恶意代码在客户机上运行。
    • 更改凭证设置
  • 应对攻击
    • 撒销访问
    • 限制登录
    • 通知参与者
  • 从攻击中恢复
    • 审计。我们审计系统(即保存用户和系统的活动及其影响的记录)以帮助跟踪攻击者的行为并识别攻击者。
    • 不可抵赖性。这种战术保证了消息的发送者以后不能否认发送过消息,而接收者也不能否认收到过消息。

11.3 基于战术的防护性调查问卷 176
11.4 防护性模式 179
11.5 进一步阅读 180
11.6 问题讨论 180

第12章 可测试性 183

12.1 可测试性通用场景 186

12.2 可测试性战术 187

  • 控制和观察系统状态
    • 专用接口
    • 记录/回放。造成故障的状态通常很难重现。记录是指捕获通过接口的信息,回放是指使用它作为进一步测试的输人。
    • 本地化状态存储
    • 抽象数据源
    • 沙箱。“沙箱化”指的是将系统实例从现实世界中隔离出来。特别是如果在现实世界中的进行模拟,在一且失败可能导致严重后果的测试情况下,常常使用沙箱战术。
    • 可执行断言
  • 限制复杂性
    • 限制结构复杂性
    • 限制不确定性

12.3 基于战术的可测试性调查问卷 192
12.4 可测试性模式 192
12.5 进一步阅读 194
12.6 问题讨论 195

第13章 易用性 197

13.1 易用性通用场景 198
13.2 易用性战术 200
13.3 基于战术的易用性调查问卷 202

13.4 易用性模式 203

1.模型-视图-控制器
用户交互(按下按键、点击按钮、移动鼠标等)被传送到控制器,控制器将它们解释为对模型的操作,然后将这些操作发送给模型,模型会相应地改变状态。反向路径也是原始MVC模式的部分。也就是说,模型被更改,控制器向视图发送更新。

13.5 进一步阅读 205
13.6 问题讨论 205

第14章 使用其他质量属性 207

14.1 其他质量属性 207
14.2 是否使用标准质量属性清单 209
14.3 处理“X能力”:引入新的QA 212
14.4 进一步阅读 215
14.5 问题讨论 215

第三部分 架构解决方案

第15章 软件接口 217

元素的参与者(actor) 是指与其交互的其他元素、用户或系统。与元素交互的参与者集合称为元素的环境( environment)。所谓“交互”,我们指的是一个元素所做的任何可能影响另一个元素处理的事情。
这些提供与元素直接交互的点的结构,称为资源( resource)。

15.1 接口的概念 218

15.2 设计一个接口 222

2.交互方式
两个最广泛使用的交互方式: RPC和REST。

  • 表现层状态转移( Representational State Transfer, REST)。REST是用于Web服务的协议。

最常见的独立于编程语言的数据表示样式可以分为文本(如XML或JSON)和二进制如协议缓区如(protocol buffer)两类。

3.交换数据的表示和结构

15.3 接口文档编制 228

“Hyrum定律" (www.hyrumslaw.com):“如果一个接口有足够多的用户,那么你在契约中承诺什么就不重要了:你的系统所有可观察的行为都将被某人所依赖。”

15.4 总结 230

15.5 进一步阅读 230

要了解采用XML、JSON和Protocol Buffers 表示邮政地址的区别,分别见https://schema.org/PostalAddress和https:/github.com/mgravell/protobuf-net/blob/master/src/protogen.site/wwwroot/protoc/googletype/postal_address.proto。
你可以在https://grpc.io上阅读更多关于gRPC的信息。
REST是由Roy Fielding在他的博士论文( ics.uci.edu/ ~ fielding/pubs/dissertation/top.htm)中定义的。

15.6 问题讨论 231

第16章 虚拟化 233

计算界因多个独立应用程序无法共享一台物理机资源(如内存、磁盘、I/O通道和用户输入设备)而感到沮丧。无法共享资源意味着一次只能运行一个应用程序。

16.1 共享资源 234

处理器共享是通过线程调度机制实现的。

随着应用程序的增长,将所有的代码和数据都装人物理内存是不可能的。面对这一挑战,虚拟内存技术应运而生。内存管理硬件将进程的地址空间划分为页,并根据需要在物理内存和辅助存储之间交换页。物理内存中的页可以立即访问,而其他页则存储在辅助内存中,直到需要它们的时候。硬件能支持个地址空间 与另一个地址空间的隔离。

磁盘的共享和隔离使用几种机制来实现。首先,只能通过磁盘控制器访问物理磁盘,该控制器确保每个线程的读写数据流按顺序传输。此外,操作系统可以使用诸如用户ID和组之类的信息来标记执行线程和磁盘内容(如文件和且录)。

网络隔离是通过识别消息来实现的。每个虚拟机( Virtual Machine, VM) 或容器都有一个Internet协议( Internet Protocol, IP)地址,用于标识虚拟机或容器收发的消息。本质上,IP地址用于将消息路由到正确的VM或容器。另一种发送和接收消息的网络机制依赖于端口号的使用。每个请求服务的消息除了指定一个 IP地址,同时还要指定一个端口号。

16.2 虚拟机 235

虚拟机监控程序( hypervisor),它是虚拟机的操作系统。直接在物理计算机硬件上运行的hypervisor 通常称为裸金属或一型hypervisor。

宿主机
hypervisor
VM1
VM2
裸金属或一型hypervisor

托管hypervisor或二型hypervisor。在这种情况下,hypervisor 作为主机操作系统上的服务运行,而hypervisor又控制一个或多个VM。

宿主机
操作系统
托管hypervisor
VM1
VM2
托管hypervisor

hypervisor要求其客户VM使用与底层物理CPU相同的指令集——hypervisor不转换或模拟指令执行。例如,如果你有一个用于使用ARM处理器的移动或嵌人式设备VM,那么你就不能在使用x86处理器的hypervisor上运行该虚拟机。另一种与hypervisor类似的技术支持跨处理器执行。它被称为仿真器(emulator)。例如,开源QEMU仿真器可以模拟一个完整的PC系统,包括BIOS、x86 处理器和内存、声卡、显卡,甚至软盘驱动器。

16.3 虚拟机映像 238

我们把启动VM时调用的磁盘存储中的内容称作VM镜像。
有三种方法可以用于创建新的VM镜像:

  1. 你可以找到一台已运行相关软件的机器,然后对该机器的内存进行快照。
  2. 你可以从已有镜像开始并添加其他软件。
  3. 你可以从头开始创建镜像。首先获取所选操作系统的安装介质,之后从安装介质启动新机器,它会格式化机器的磁盘驱动器,将操作系统复制到驱动器上,并将boot loader添加到预定位置。

16.4 容器 239
16.5 容器和虚拟机 241

16.6 容器可移植性 242

容器运行引擎和容器之间的接口已经由Open Container Initiative标准化,允许某个供应商(比如Docker)创建的容器在另一个供应商(比如containerd)提供的容器运行引擎上执行。

16.7 Pod 242

同一Pod中的容器共享IP地址和端口空间,以接收来自其他服务的请求,它们可以使用进程间通信(IPC)机制(比如信号量或共享内存)彼此通信,它们还可以共享Pod生命周期内的临时存储容量,它们具有相同的生命周期——Pod 中的容器一起被分配和释放。Pod的目的是减少紧密相关容器之间的通信成本。如果容器1和容器2频繁通信,将它们部署为一个Pod并分配到同个VM上,实际上是一种比消息传递更快的通信机制。

16.8 无服务器架构 243
16.9 总结 244
16.10 进一步阅读 245
16.11 问题讨论 245
第17章 云和分布式计算 247
17.1 云基础 248
17.2 云中失效 251
17.3 使用多个实例提高性能和可用性 253
17.4 总结 261
17.5 进一步阅读 262
17.6 问题讨论 262

第18章 移动系统 263

重点介绍其中的五个特性:

  • 能源
  • 网络连接
  • 传感器和执行器
  • 资源
  • 生命周期

18.1 能源 264

18.2 网络连通性 266

无线网络是根据传输距离来分类的。

  • 在4cm以内。近场通信(Near Feild Commnication,NFC)用于门卡和非接触式支付系统。GSM联盟正在制定这方面的标准。
  • 10m以内。IEEE 802.15标准系列涵盖了这距离。蓝牙和Zigbee是这类协议中的常见协议。
  • 100 m以内。在此距离内使用IEEE 802.11标准系列(Wi-Fi)。
  • 几公里之内。IEEE 802.16 标准涵盖了这一距离。 WiMAX是IEEE 802.16标准的商业名称。
  • 几公里以上。这是通过蜂窝或卫星通信实现的。

架构师关注点
通信和网络连接的设计需要架构师权衡大量的关注点,包括:

  • 需要支持的通信接口数量。移动系统的设计目标恰恰相反:只应该包含严格要求的网络接口,以优化功耗、发热和空间分配。
  • 从一个协议切换到另一个协议。移动系统可能会从支持一个协议 的环境移动到支持另一个协议的环境。例如,视频可能通过Wi-Fi进行流传输,但随后系统可能会移动到没有Wi-Fi的环境中并通过蜂窝网络传输。这种切换对用户来说应该是无缝衔接的。

18.3 传感器和执行器 267
18.4 资源 268
18.5 生命周期 270
18.6 总结 273
18.7 进一步阅读 274
18.8 问题讨论 275

第四部分 可扩展架构实践

第19章 架构上的重要需求 277

架构重要性需求( Architecturally Significant Requirement, ASR) 是一种对架构有深远影响的需求,也就是说,如果没有这种需求,架构可能会有很大的不同。

19.1 从需求文档中收集ASR 278

19.2 通过访谈利益相关者收集ASR 279

  • 业务/使命陈述。代表系统背后的业务关注点的利益相关者(通常是管理者或管理者代表)花费大约一个小时来解释系统的业务背景、广泛的功能需求、约束和已知的QA需求。
  • 架构计划陈述。虽然详细的系统或软件架构可能不存在,但可能已经创建了广泛的系统描述、上下文示意图或其他制品来描述系统的一些技术细节。
  • 识别架构驱动因素。
  • 场景头脑风暴。通过指定明确的刺激和响应,确保每个场景都解决了一个QA问题。
  • 场景整合。要求利益相关者识别内容非常相似的场景。
  • 场景优先级。利益相关者可以将任意数量的选票投给任何场景或场景组合。
  • 场景细化。

我不知道需求应该是什么

在这种情况下,引出这个“东西”要比简单地自己编造需求好得多。例如,你可能会问,“系统应该以多快的速度响应这个事务请求?”如果答案是“我
不知道”,我的建议是装糊涂。你可以说,“那么...24h可以吗?”
通过装糊涂,你通常可以让人们至少给你一个可接受的值范围,即使他们不确切地如道需求应该是什么。

19.3 通过理解业务目标收集ASR 282

PALM的核心由以下步骤组成:

  • 业务目标的引出。详细闸述业务目标并将其表示为业务目标场景
  • 从业务目标中识别潜在的QA。让参与者描述有助于实现目标的QA和响应度值(如果需要架构实现)。

19.4 在工具树中捕获ASR 284

效用树以单词“效用”作为根节点开始。效用是系统整体“好处”的一种表达。
一旦ASR被记录为场景并放在树的叶节点上,你就可以根据两个标准来评估这些场景:候选场景的业务价值和实现它的技术风险。你可以使用任何你喜欢的量表,但我们发现一个简单的“H"(高)、“M"(中)和“L”(低)评分系统足以满足每个标准。对于业务价值,“高”表示必须具备的需求,“中” 表示重要但不会导致项目失败的需求,而“低”表示需要满足但不值得付出太多努力的良好需求。对于技术风险,“高"表示风险会让你夜不能寐,“中”表示满足此ASR会让你担心,但不会带来高风险,“低”表示你有信心有能力
满足该ASR。

19.5 发生了变化 286
19.6 总结 286

19.7 进一步阅读 287

可在https://www.opengroup.org/togaf/10thedition上获得Open Group Architecture Framework,它提供的完整模板,用于记录包含大量有用信息的业务场景。

19.8 问题讨论 287

第20章 设计架构 289

属性驱动设计( Atribute-Driven Desig, ADD),它允许以系统的、可重复的、经济高效的方式来设计架构。

20.1 属性驱动的设计 289

20.2 ADD步骤 292

1.步骤1:复检输入
设计过程的输人;

  • 本轮设计的目标
  • 主要功能需求
  • 主要质量属性(QA)场景
  • 任何约束
  • 任何关注点

2.步骤2:通过选择驱动因素建立迭代目标
每次设计迭代都聚焦实现一个特定的目标。

3步骤3:选择-一个或多个系统元素进行细化
更满足驱动因素,你就要做出架构设计决策,然后在一- 个或多个架构结构中表现出来。

4.步骤4:选择-一个或多个符合所选驱动因素的设计概念
选择设计概念可能是你在设计过程中面临的最困难的决策,因为它要求你识别各种可能用于实现迭代目标的设计概念,然后从这些备选方案中进行选择。

5.步骤5:实例化架构元素,分配职责,定义接口
如何从你选择的设计概念出发实例化元素。例如,如果你选择层模式作为设计概念,就必须决定使用多少层,以及它们允许的关系,因为模式本身并没有规定这些关系。

6.步骤6:素描视图并记录设计决策
如果你在一一个会议室执行步骤5, 你可你白板上完成一系列图表。捕获视图可能就像给白板拍张照片一样简单。

7.步骤7:执行当前设计的分析,检查迭代目标和设计目标的实现情况

8.必要时进行迭代
由于时间或资源的限制,这种重复通常是不可能的,因为这些限制迫使你停止设计活动并转向实现。
是否需要更多的设计迭代,判断的标准是什么?让风险成为你的向导。

20.3 ADD步骤4的进一步说明:选择一个或多个设计概念 295

1.识别设计概念
更槽糕的是,这些设计概念分散在许多不同的来源:几十种博客和网站、研究文献和书籍。

设计候选方案:

  • 利用现有的最佳实践。
  • 利用自己的知识和经验。缺点是,你可能最终会重复使用相同的思想,即使它们不是最适合你所面临的设计问题。俗话说:如果你只有一把锤子,那么整个世界看起来就像一颗钉子。

2.设计概念的选择
SWOT (优势、劣势、机会、威胁)分析等方法可以帮助你做出决策。

3.创建原型
创建原型还是不创建原型
一个团队可以进行一系列的实验(比如构建原型),以减少选择的不确定性。问题在于实验可能会带来巨大的成本,而得出的结论可能仍然不确定。

20.4 ADD步骤5的进一步说明:生成结构 298
20.5 ADD步骤6的进一步说明:在设计过程中创建初步文档 301

20.6 ADD步骤7的进一步说明:对当前设计进行分析并审查迭代目标和设计目的实现情况 304

评估你是否完成了足够的设计工作:

  • 你需要做多少设计?
  • 到目前为止,你做了多少设计?
  • 你完成了吗?

1.架构backlog的使用
架构backlog是架构设计过程中仍然需要执行的未决活动的待办事项列表。

2.使用设计看板
一个可以用来跟踪设计过程的工具是看板。 看板建立了三类backlog项:“未解决“部分解决”和“完全解决”。

20.7 总结 306
20.8 进一步阅读 306
20.9 问题讨论 307

第21章 架构评估 309

架构评估是确定架构符合其预期目标程度的过程。

21.1 评估作为一项降低风险的活动 309

21.2 关键的评估活动是什么 310

价每次评估都应包括(至少)以下步骤:
1)评审人员单独确保自己了解架构的当前状态。
2)评审人员确定指导评审的若干驱动因素。
3)对于每个场景,每个评审人员应确定该场景是否已满足。
4)评审人员捕获在上一步骤中暴露的潜在问题。

21.3 谁能执行评估 311
21.4 环境因素 312

21.5 架构权衡分析方法 313

架构权衡分析方法( Architecture Tradeoff Analysis Method, ATAM)是正式定义的执行架构评估的过程。ATAM的设计使评估者不需要事先熟悉架构或其业务目标,也不需要等到系统构建完成。

1.ATAM的参与者

  • 评估团队。这个团队位于要进行架构评估的项目的外部。在任何情况下,他们都需要被认为是有能力的、无偏见的局外人,没有隐含的议程或意图。
  • 项目决策者。这些人被授权为开发项目说话,或者有权对其进行变更。通常包括项目经理,如果能找到一个客户为开发买单,那么该客户的代表也可能会在里面。架构师总是被包括在内——架构评估的一个基本规则是架构师必须欣然参与。
  • 架构利益相关者。利益相关者对所宣称的架构具有既得利益。利益相关者包括开发人员、测试人员、集成商、维护人员、性能工程师、用户,以及与系统交互的系统构建者。
角色 职责
团队领导 建立评估:与客户协调,确保客户需求得到满足:创建评估合同:组建评估小组:确保生成并交付最终报告
评估领导 执行评估:推动场景获取;管理场景优先级排序过程;推动根据架构评估场景
场景描述者 在场景获取过程中以共享的、公开的形式编写场景:捕获每个场景的一致描述, 暂停讨论,直到获得准确的描述
电子抄写员 以电子形式捕获过程中的产出一原始场景、 激发每个场景的问题(通常在场景本身描述中找不到)和每个场景的分析结果;生成已采用方案的列表,分发给所有参与者
提问者 基于质量属性提出问题
表 ATAM 评估团队角色

2.ATAM的输出
1)架构简明介绍。
3 )以质量属性场景表示的优先质量属性需求。
4)一组风险点和无风险点。
6)将架构决策映射到质量需求。
7)一组识别出的敏感点和权衡点。敏感点是对质量属性响应有显著影响的架构决策。权衡点是当两个或多个质量属性响应对相同的架构决策敏感,但其中一个改善而另一个恶化时,就会出现矛盾,因此需要权衡。

3.ATAM的各个阶段

阶段 活动 参与者 典型累积时间
0 伙伴关系和准备 评估团队领导和关键项目决策者 按要求非正式地进行,可能需要几个星期
1 评估 评估团队和项目决策者 1~2天
2 评估(继续) 评估团队、项目决策者和利益相关者 2天
3 跟进 评估团队和评估客户 1星期
表 ATAM阶段及其特征

4.评估阶段的步骤
ATAM分析阶段(第1和第2阶段)包括九个步骤。
1)步骤1:讲解ATAM
2)步骤2::讲解业务目标
3)步骤3:讲解架构
4)步骤4:识别架构设计方法
5)步骤5:生成质量属性效用树
6)步骤6:分析架构设计方法
7)第2阶段的间歇和开始
8)步骤7:头脑风暴并确定场景优先级
9)步骤8:分析架构设计方法
10)步骤9:讲解结果

21.6 轻量级架构评估 324
21.7 总结 326

21.8 进一步阅读 327

有多个采用ATAM方法的案例研究。可以通过访问https://insights.sei.cmu.edu/library/并搜索“ ATAM case study"找到它们。

21.9 问题讨论 327

第22章 记录一个架构 329

22.1 架构文档的用途和受众 330
22.2 符号 331
22.3 视图 332
22.4 合并视图 339

22.5 记录的行为 340

有两种类型的表示法可用于记录行为:面向轨迹的和综合的。
轨迹描述了系统结系之间的一系列活动或交互。这里我们介绍记录轨迹的四种表示法:用例、序列图、通信图和活动图。

  • 序列图。对象(即元素实例)有一条生命线,沿时间轴以垂直虚线绘制。这个序列通常由最左边的角色开始。实例通过发送消息进行交互,消息显示为水平箭头。消息可以是通过网络发送的消息、函数调用或通过队列发送的事件。消息通常映射到接收方实例接口中的资源(操作)。图中的实线实心箭头表示同步消息,而实线开放箭头表示异步消息,虚线箭头是返回消息。沿着生命线的执行条表示实例正在处理或被阻止等待返回。

综合表示法显示结构元素的完整行为。
状态机是许多综合表示法使用的一种形式。
UML状态机允许你跟踪系统的行为。这样的图表使用方框表示状态,使用箭头表示状态之间的转换。

22.6 不只是视图 345

除了视图和行为,关于架构的全面信息还包括以下内容:

  • 视图之间的映射。因为一个架构的所有视图都描述同一个系统,所以任何两个视图都有很多共同之处。

22.7 记录基本原理 346

22.8 架构利益相关者 347

架构的主要利益相关者包括:

  • 项目经理关心进度计划、 资源分配。

对以下视图感兴趣:

  1. 模块视图。分解视图、使用视图和分层视图。
  2. 分配视图。部署视图和工作分配视图。
  3. 其他。显示系统交互、系统概述和用途的顶层上下文关系图。
  • 开发团队的成员
  • 测试人员和集成人员
  • 最终用户不需要看到架构
  • 分析人员对设计是否满足系统的质量目标感兴趣。架构作为架构评估方法的素材

22.9 实际问题 350
22.10 总结 353

22.11 进一步阅读 353

AADL (addl.info) 是一种架构描述语言, 已成为SAE记录架构的标准。SAE是航空航天、汽车和商用车辆行业工程专业人士的组织。

22.12 问题讨论 354

第23章 管理架构债 355

随着时间的推移,设计将变得难以维护和发展。我们将这种形式的熵称为“架构债”。
一旦确定了架构债,并且足够糟糕,就应该通过重构来消除它。如果没有回报的定量证据,通常很难让项目利益相关者同意这一点。
债务分析模型可以确定架构中出现异常高的错误率和代码扰动率(churn)(根据提交的代码行)的区域,并尝试将这些症状与设计缺陷联系起来。

23.1 确定是否存在架构债问题 356

在管理架构债的过程中,我们将聚焦架构元素的物理表现形式,即存储源代码的文件。我们如何确定一组文件在架构上是相关联的呢? 一种方法是根据项目文件之间的静态依赖关系,例如,一文件中的方法调用另文件中的方法。第二种方法是捕获文件之间的进化依赖关系。 当两个文件需要-起变更时, 即称之存在进化依赖关系。
我们可以使用一种称为设计结构矩阵( Design Structure Matrix, DSM)的特殊邻接矩
阵来表示文件依赖关系。
二T定进化(取历文)低积。
重复一下: DSM中的每一行表示一个文件。一 行中的条目表示该文件对系统中其他文件的依赖关系。如果系统耦合度低,则DSM矩阵是稀疏的;也就是说,任何给定的文件都依赖较少的其他文件。此外,你应希望DSM是下对角线的:也就是说,所有条目都出现在对角线下方。这意味着文件仅依赖于较低级别的文件,而不依赖于较高级别的文件,并且你的系统中没有循环依赖项。

23.2 发现热点 358

如果你怀疑你的代码库有架构债(也许错误率在上升而特性发布速度在下降),
常见反模式:

  • 不稳定的接口
  • 违反模块化
  • 不健康的继承
  • 循环依赖或派系依赖
  • 包循环

23.3 示例 362

2.量化架构债
架构师可以很容易地根据热点中的反模式估计每个重构所需的人月数。

23.4 自动化 363
23.5 总结 364
23.6 进一步阅读 364
23.7 问题讨论 365

第五部分 架构和组织

第24章 架构师在项目中的角色 367

24.1 架构师和项目经理 367

项目经理负责项目的整体绩效——通常是保证项目在预算内、按计划进行,并配备正确的人员做正确的工作。
项目经理应该知道,并向高层管理者反映项目中的进展和风险,而软件架构师应该知道,并向开发人员反映外部利益相关者的关注点。

架构师在支持项目管理知识领域中的角色

项目管理知识体系领域 描述 架构师角色
项目集成管理 确保项目中各个元素彼此协作 创建设计团队,围绕设计组织团队;管理依赖关系。获取度量指标。协调变更请求
项目范围管理 确保项目包括所有必需的工作,并且只包括必需的工作 获取、协商和审查运行时需求,并生成开发需求。估算与满足需求相关的成本、进度和风险
项目时间管理 确保项目按时完成 帮助定义工作分解结构。定义跟踪措施。提出给软件开发团队分配资源的建议
项目成本管理 确保项目在所需预算内完成 从各个团队收集成本数据;就构建/购买和资源分配提出建议
项目质量管理 确保项目满足其承担的需求
针对质量进行设计,并根据设计跟踪系统。定义质量指标
项目人力资源管理 确保项目最有效地利用人力资源 定义所需的技能集。指导开发人员职业道路。推荐培训。面试候选人
项目沟通管理 确保及时、适当地生成、收集、传播、存储和处置项目信息
确保开发人员之间的沟通和协作。征求有关进展、问题和风险的反馈。监督文档
项目风险管理 识别、分析和应对项目风险 识别和量化风险;调整架构和流程以降低风险
项目采购管理 从组织外部获取商品和服务 确定技术要求;推荐技术、培训和工具

24.2 增量架构和利益相关者 369

24.3 架构和敏捷开发 370

敏捷原则和以架构为中心的观点

敏捷原则 以架构为中心
我们的首要任务是通过尽早、持续地交付有价值的软件来满足客户 对极了
欢迎不断变化的需求,即使是在开发后期。敏捷流程利用变化实现客户的竞争优势 对极了,这一原则要求提供高度可修改性和可部署性的架构
围绕有工作动力的个人建立项目。给他们环境和他们需要的支持,并相信他们能完成工作 虽然我们原则上同意,但许多开发人员缺乏经验。因此,请确保包括一名技术熟练、 经验丰富、积极主动的架构师来帮助指导这些人
在开发团队中传递信息的最有效方法是面
对面交谈
对于重要系统来说,这是胡说八道。人类发明写作是因为我们大脑不能记住需要记住的一切。接口、协议、架构等都需要写下来,重复指令的低效和无效,以及由于误解而产生的错误,都不符合这一原则。根据这一观点,任何人都不应该制作用户手册,而应该公开开发者的电话号码,并邀请他们随时通话。对于任何有维护阶段(几乎所有系统都有维护阶段)的系统来说,这也是毫无意义的,因为在维护阶段,根本找不到原始团队。
最好的架构、需求和设计来自自组织团队 不,他们没有。正如我们在第20章中所描述的,最好的架构是由熟练、有才华、训练有素和经验丰富的架构师有意识设计的

24.4 架构和分布式开发 373

大多数实质性项目都是由分布式团队开发的。
分布式开发既有好处也有挑战:

  • 成本。劳动力成本因地而异,然而,在低成本的开发人员具备足够的领域专业知识之前,在克服分布式开发的困难之前,必须进行大量的返工,从而让整个工作得不偿失。
  • 技能和劳动力。组织可能无法在一个地点雇用开发人员: 以分布式方式开发系统允许工作移动到员工所在的位置,而不是强迫员工移动到工作地点,尽管这是以额外的通信和协作为代价的。
  • 本地市场知识。开发者对合适的功能和可能出现的文化问题更有发言权。

协作方法包括下列选项:

  • 非正式接触。只有团队同地协作时,才能进行非正式接触,如在咖啡间或走廊里开会。
  • 文档。
  • 会议。
  • 异步电子通信。各种形式的异步电子通信可以用作协作机制,如电子邮件、新闻组、博客和wiki。

这对架构和架构师意味着什么?这意味着在分布式开发中,架构师将责任分配给团队比在同地协作(指所有开发人员都在一个办公室内,或者至少在很近的距离内开发)中更为重要,这还意味着,与其他质量属性(如可修改性和性能)相比,架构师给了模块依赖关系更多的关注。

24.5 总结 376

24.6 进一步阅读 376

Dan Paulish写了一本介绍如何在以架构为中心的环境中进行管理的好书——《软件项日管理实用指南——以体系结构为中心( Architecture-centric Software Project Management: A Pactical Guide)。
架构师在组织中占有独特的地位。他们被期望熟练地掌握系统生命周期的所有阶段。在项目的所有成员中,他们对项目和系统的所有利益相关者的需求最为敏感。他们之所以被选为架构师,部分原因是他们的沟通能力高于平均水平。The Software Architect Elevator : Redefining the Architect's Role in the Digital Enterprise 描述了架构师与组织内外各级人员互动的独特能力。

24.7 问题讨论 377

第25章 架构能力 379

25.1 个人能力:架构师的职责、技能和知识 379

3.知识

通用知识领域 特定知识领域 示例
计算机科学知识 架构概念知识 了解架构框架,架构模式、战术、结构和视图、参考架构、与系统和企业架构的关系、新兴技术、架构评估模型和方法以及质量属性
软件工程知识 软件开发领域的知识,包括需求、设计、开发、维护、配置管理、工程管理和软件工程过程。系统工程知识
设计知识 熟悉工具、设计和分析技术。了解如何设计复杂的多产品系统。熟悉面向对象的分析和设计,以及UML和SysML图表
编程知识 熟悉编程语言和编程语言模型。具备安全性、实时、防护性等专业编程技术知识
技术和平台知识 特定技术和平台 熟悉硬件/软件接口、基于Web的应用程序和互联网技术。具备特定软件/操作系统的知识
对技术和平台的通用知识 了解IT行业的未来发展方向以及基础设施对应用程序的影响方式
组织环境和管理的知识 领域知识 了解最相关的领城和特定领域的技术
行业知识 了解行业最佳实践和行业标准。了解如何在国内1海外团队环境中工作

25.2 软件架构组织的能力 386
25.3 成为更好的架构师 387
25.4 总结 388

25.5 进一步阅读 388

信息技术架构知识体系( Information Technology Architecture Body of Knowledge,ITABoK)是一个“免费的IT架构最佳实践、技能和知识公共档案库,基于全球最大的IT架构专业组织lasa中的个人和公司成员的经验开发而成”( https://itabok.iasaglobal.org/itabok/)。
Joseph Ingeno在Software Architect's Handbook中专门用了一章来介绍“软件架构师的软技能”。

25.6 问题讨论 389
第六部分 结论
第26章 展望未来:量子计算 391
26.1 单量子位 392
26.2 量子隐形传态 394
26.3 量子计算和加密 394
26.4 其他算法 395
26.5 潜在应用 396
26.6 最后的想法 397
26.7 进一步阅读 398
参考资料 399

posted @   liqinglucky  阅读(7)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· 清华大学推出第四讲使用 DeepSeek + DeepResearch 让科研像聊天一样简单!
· 实操Deepseek接入个人知识库
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库
历史上的今天:
2021-02-14 nginx反向代理
点击右上角即可分享
微信分享提示