什么是软件架构
系统的软件架构包括软件元素、这些元素的外观,以及它们之间的关系。
- 架构是涉众之间进行交流的手段
- 是早期设计决策的体现
- 是可传递、可重用的系统抽象
结构和视图
- 结构是元素本身的集合,因为它们存在于软件或硬件中。
- 视图是由系统涉众编写和读取的一组一致的体系结构元素的表示。
常用的结构
Module structure
体现了关于如何将系统构建为一组代码或数据单元的决策
Decomposition structure(分解结构)
User structure -> layer pattern
Class structure
- 模块中的关系为继承或实例
Data model
- 描述静态数据结构与它们之间的关系
Component and connector structures(C&C)
体现了关于如何将系统作为一组具有运行时行为(组件)和交互(连接器)的元素进行结构化的决策。元素是运行时组件,如服务、对等点、客户端、服务器或许多其他类型的运行时元素。连接器是组件之间的通信工具,例如调用返回、进程同步操作符、管道或其他
Service structure
单元之间通过服务协调机制(如SOAP)互相交互
SOAP(Simple Object Access Protocol)——简单对象访问协议,用来描述传递信息的格式
Concurrency structure
用于确定并行的可能与可能发生资源争用的位置
Allocation structures
显示了软件元素和一个或多个外部环境中的元素之间的关系,软件就是在这些外部环境中创建和执行的。
Deployment structure
- 说明软件在硬件上怎么分配与交互的元素
Implementation structure
说明软件元素(通常是模块)是怎么映射到系统部署的文件结构的
Work assignment structure
- 说明模块集成实现的职责分配
架构模式
体系结构模式表示用于解决特定问题的元素类型及其交互形式。
Module type pattern
Layered pattern
用来构建可以分解为子任务组的程序,每个子任务都处于特定的抽象层次。每层仅为下一个更高层提供服务
- 问题:减少发展的不同组织之间的相互作用,并支持可移植性、可修改性、和重用
- 解决方案:分层模式将软件划分为层。每一层都是一组模块,它们提供了一组内聚的服务。每个层通过公共接口公开。用法必须是单向的。
Component and connector pattern
Broker pattern 代理模式
代理模式定义了一个运行时组件,称为代理,它代理多个客户机和服务器之间的通信
- 背景:许多系统服务发布在多台服务器
- 问题;我们如何构造分布式软件,使服务使用者不需要知道服务提供者的性质和位置?
- 解决方案:代理模式通过插入中介(称为代理)将客户机与提供者服务器分开,当客户机需要服务时,它通过服务接口查询代理。然后,代理将客户机的服务请求转发给服务器,该服务器处理请求
Model-View-Controller pattern
- 背景:用户界面软件是交互式应用程序中最经常修改的部分
- 问题:如何将用户界面功能与应用程序功能分开,但仍响应用户输入,还是对底层应用程序的数据进行响应?当底层应用程序数据发生变化时,如何创建、维护和协调用户界面的多个视图?
- 解决方案:模型-视图-控制器模式将应用程序功能划分为三种组件:一个模型,其中包含应用程序的数据;视图,显示底层数据的一部分并与用户交互;一个控制器,它在模型和视图之间进行中介,管理状态变化的通知
Pipe-and-Filter pattern 管道-过滤器模式
- 背景:流数据处理
- 问题:如何加速数据处理
- 解决方案:数据到达过滤器的输入端口,进行转换,然后通过其输出端口通过管道传递到下一个过滤器。单个筛选器可以将数据从一个或多个端口消耗或生成数据
Shared data(repository) pattern 共享数据模式
- 背景:各种计算组件需要共享和操作大量数据。这些数据不完全属于这些组件中的任何一个
- 问题:系统如何存储和操作由多个独立组件访问的持久数据?
解决方案:在共享数据模式。相互作用是由多个数据访问和至少一个共享数据存储之间的数据交流为主的持续性。交流可以通过访问器或数据存储器启动。连接器类型是数据读写。之间的数据访问的通信是通过共享数据存储介质。数据由数据存储器持久化。
Client and server pattern
这种模式由两方组成:一个服务器和多个客户端。服务器组件将向多个客户端组件提供服务。客户端向服务器请求服务,服务器向这些客户端提供相关服务。此外服务器继续侦听客户端请求
- 背景:大量分布式客户机希望访问共享资源和服务,我们希望控制访问或服务质量
- 问题:通过集中控制这些资源和服务来提高可伸缩性和可用性
- 解决方案:客户端通过请求服务器的服务进行交互。一些组件可以同时充当客户端和服务器。可能有一个中央服务器或多个分布式服务器
Peer to peer pattern(点对点模式)
在这种模式中,单个组件被称为同级。同事可能即作为客户端又作为服务器,并且可以随着时间动态地改变其角色
- 背景:分布式计算实体需要合作和协作以向分布式用户社区提供服务
- 问题:一组“相同”的分布式计算实体如何通过一个公共协议互相连接,这样它们就可以组织并共享其高可用性和可伸缩性的服务?
- 解决方案:在点对点模式中,组件直接作为对等体交互。所有的peers都是平等的。对等通信是一个典型的没有不对称的CS模式请求/响应交互
Service-Oriented Architecture pattern SOA模式
- 背景:服务消费者需要了解和使用服务,而不需要了解服务的实现
- 问题:我们如何支持在不同平台上运行的分布式组件的互操作性,以及由不同组织提供的不同实现语言编写,并在Internet分发?
- 解决方案:面向服务的体系结构模式描述了提供 和/或 服务的分布式组件的集合
元素:
组件:
服务提供者,它通过发布的接口提供一个或多个服务
服务消费者,直接或通过中介调用服务。
企业服务总线(ESB)是一个中间元素,它可以在服务提供者和使用者之间路由和转换消息。
服务注册中心,提供者可以使用它来注册服务,使用者可以使用它来在运行时发现服务。
连接器:
SOAP连接器,它使用SOAP协议在web服务之间进行同步通信,通常是通过HTTP。
REST连接器,它依赖于HTTP协议的基本请求/应答操作。
异步消息传递连接器,它使用消息传递系统来提供点对点或发布-订阅异步消息交换。
约束:服务使用者连接到服务提供者,但是可以使用中介组件(例如ESB、注册中心)。
Publish-Subscribe pattern 发布订阅模式
- 背景:数据生产者和消费者的确切数量和性质不是预先确定的或固定的
- 问题:在生产者和消费者之间传递信息,使他们不知道对方的身份,甚至他们的存在?
- 解决方案:提供时间、空间和同步的解耦
Allocation type pattern
Multi-tier pattern 多级模式
描述如何在不同的硬件和软件子集中分配和分配系统的组件,这些子集由某些通信媒介连接。
Competence center pattern
- 这个模式声明了软件系统的职责分配结构
Platform pattern
Map-Reduce pattern
好的结构的一些经验法则
- 体系结构应该是单个架构师的产品,或者是一个确定的技术领导者的一个架构师小组的产品。
- 架构师(或体系结构团队)应该将体系结构建立在良好指定的质量属性需求的优先列表之上。
- 应该使用视图记录体系结构
- 应该评估体系结构交付系统重要质量属性的能力
- 体系结构应该适合增量实现
- 体系结构应该以定义良好的模块为特征
- 体系结构不应该依赖于商业产品或工具的特定版本
- 产生数据的模块应该与消耗数据的模块分开
- 不要期望模块和组件是一一对应的
- 应该编写每个进程以便能够轻松地更改对特定处理器地分配 ,甚至在运行时也可以这样做
- 体系结构应该提供少量的组件交互方式
为什么要用架构
- 体系结构将抑制或者促进系统的驱动质量属性
- 体系结构可以让你在软件升级的时候控制变更
- 对体系结构的分析可以对系统的质量进行早期预测
- 文档化体系结构增强了涉众之间的沟通
- 体系结构是最早、最基本、最难改变设计决策的载体
- 体系结构在随后的实现中定义了一组约束
- 体系结构决定了一个组织的结构,反之亦然
- 体系结构可以为演化原型提供基础
- 体系结构允许架构师和项目经理判断成本和进度
- 体系结构可以创建为可转移的、可重用的模型,形成产品线的核心
- 基于体系结构的开发关注的是组件的组装,而不是简单地创建它们
- 通过限制设计方案,体系结构可以拓宽开发人员的创造力,减少设计和系统复杂性
- 架构可以是培训新团队成员的基础
- 一个系统是否能够展示它的所需质量属性大体上取决于它的架构
软件体系结构的多种背景
- Technical:软件体系结构在系统中扮演什么样的技术角色
- Project life cycle:软件体系结构如何与软件开发生命周期的其他阶段相关联
- Business:软件体系结构的存在如何影响组织的业务环境
- Professional:软件架构师在组织或开发项目中的作用是什么
质量属性
系统需求可以分为:
- 功能需求
- 质量属性需求
- 描述系统运行时的属性:availability、performance、usability、security
- 描述系统开发时的属性:modifiability、testability
- 约束
为了表达质量属性的需求我们使用了一个质量属性场景
- Stimulus source
- Stimulus
- Environment
- Artifact
- Response
Response measure
质量属性场景分类
- 一般的质量属性场景是与系统无关的
- 具体的质量属性场景是特定于所考虑的特定系统的
Tactics
一个原始设计技术的集合,架构师可以用它来实现质量属性响应
Tactics VS Architecture pattern
- A tatic 是针对单个质量属性的设计决策
- A tatic 不考虑质量属性的权衡
- Architecture pattern 可以看为一个考虑了权衡的Tatics的集合
我们需要隔离、分类和描述战术。我们为什么要这么做?
- 设计模式是复杂的,而且通常很难应用,架构师需要修改和调整它们
- 如果没有模式来实现架构师的设计目标,策略允许架构师从“第一原理”构建一个设计片段
- 通过编目策略,我们可以选择多种策略来改进特定的质量属性。选择哪种策略取决于实施成本等因素
七种质量设计的决策:
- 职责分配
- 协调模型
- 数据模型
- 资源管理
- 构建元素之间的映射
- 结合时间的决定
- 技术的选择
可用性
可用性泛指系统在故障发生时可用的能力
提高可用性的策略分为:
检测错误
- ping/回声
- 监控
- 心跳
- 时间戳、状态监视、投票、异常检测、自检
从错误当中恢复
- 活动冗余(热备用)
- 备用(冷备用)
- 降级:在组件失败的情况下维护最关键的系统功能,减少不重要的功能
- 重构: 重新分配职责,离开故障的资源,同时保持尽可能多的功能
预防故障
- 删除服务:暂时将系统组件置于服务状态之外,以减轻潜在的系统故障
- 事务:捆绑状态更新,以便在分布式组件之间交换的异步消息具有原子性、一致性、隔离性和持久性
- 预测模型:在检测到可能出现的未来故障的情况下,采取纠正措施
- 异常预防:通过智能指针、抽象数据类型、包装器防止系统异常发生
- 增加权限集:设计一个组件来处理更多的故障,作为其正常运行的一部分
互操作性
互操作性是指两个或多个系统能够通过特定上下文中的接口有效地交换有意义的信息的程度
- 语法互操作性是交换数据的能力
- 语义互操作性是对正在交换的数据进行解释的能力
SOAP VS REST
SOAP 与一组协议一起在 SOA 系统中使用
- 服务描述 & 发现: WSDL,UDDI
- 服务集成: BPEL
SOAP是用来传输结构化数据的复杂方法,而REST是简单的传输少量信息的方法
互操作性的两个目标
了解彼此,这是定位战术的目标
Flood/Broadcast request
- Efficient and less resource consuming for the searcher
- Low resource consuming for the searched
- But disturbing and resource consuming for the environment
Successive request(一次请求一个实体并匹配,如果不匹配则继续寻找下一个)
- Less efficient and high resource consuming for the searcher
- But less disturbing and less resource consuming for the environment
Continuous/periodical advertisement
- Efficient but high resource consuming for the searched
- Low resource demanding for the searcher
- Disturbing and resource consuming for the environment
Advertisement upon arrival of new entity (新实体到达时广播)
需要检测新实体到达的机制
- Less resource consuming for the searched
- Low resource demanding for the searcher
- Less disturbing and resource consuming for the environment
Introduction of the “middlemen”, registry (中间人)
- The searched entity registers to a registry
The searcher can address to the registry to get information and find the searched entity
在语义上有意义的方法交换信息。这是管理接口战术的目标,交换信息的两个方面是:
- 按正确的顺序提供服务
- Orchestrate:使用控制机制来协调、管理和排序服务的调用。当系统必须以复杂的交互方式完成复杂的任务时,就会使用Orchestrate
- 将一个参与者生成的信息修改为另一个参与者可接收的形式
- Tailor Interface:添加或移除接口的功能,比如翻译,缓冲或者数据平滑
- 按正确的顺序提供服务
可修改性
可修改性是关于变更的,我们对它的兴趣在于改变的成本和风险
可修改性战术的目标
- 控制变更的复杂度
- 控制变更的时间和花费
战术
Reduce Size of a Module
- Split Module
Increase Cohesion
- Increase Semantic Coherence
Reducing Coupling
Encapsulate:封装为模块引入了显式接口。这个接口包括一个API及其相关的职责
Use an Intermediary:给定职责A和职责B之间的依赖关系(例如,首先执行A需要执行B),可以通过使用中介打破依赖关系。
Restrict Dependencies:限制给定模块与之交互或依赖的模块
Abstract Common Services:如果两个模块提供了近似的方法,那更有效率的做法是实现一个更加一般化的服务
Publish/Subscribe System
动机:
- 传统C/S通信模型
- 同步、紧耦合的请求调用
- 对分布式应用程序,特别是广域网和局域网,有很大的限制
- 当节点/链接失败时,系统收到影响。必须内置容错功能来支持这一点
- 需要提供异步机制的更灵活的解耦合通信样式
- 传统C/S通信模型
解决方案:
- 发布/订阅系统是一种通信范式,它允许在(分布式)系统中通过通信实体在时间、空间和同步方面的解耦实现自由。
- Publishers:发布者生成事件数据并发布它们
- Subscribers:订阅者提交他们的订阅并处理接收到的事件
P/S service:中介/代理过滤并将事件从发布者路由到感兴趣的订阅者
分类:
Centralized Broker model(集中代理模型)
- 由多个发布者、多个订阅者和一个集中的代理/代理(一个相互交互的覆盖网络)组成。
Peer-to-Peer model
- 每个节点都可以作为发布者、订阅者或代理
- 订阅者直接订阅发布者,发布者直接通知订阅者。所以他们必须保持对彼此的了解
代理中间件的关键方法
事件过滤
- 选出对产生的事件感兴趣的订阅者集合
- 订阅者们被存储在内存中并且在发布者发布一个新的事件时被搜索
事件路由
- 将产生的事件路由到所有感兴趣的订阅者的过程
Topic based VS Content based
Topic based
通常也称为基于主题、基于组或基于通道的事件过滤。
每个事件由其发布者发布到这些通道之一。
订阅者订阅特定的通道,并将接收发布到订阅通道的所有事件
Content based
通过允许对事件内容的任意/自定义查询中的更多表达式,为订阅者提供了更大的灵活性和更强大的功能
事件通过键/值属性对发布,而订阅使用显式订阅语言指定筛选器
优缺点:
优点
- Robust:发布者或者订阅者错误不会影响整个系统
- Scalability:适合构建包含大量实体的分布式应用程序
- Adaptability:可以适应不同的环境(移动,网络游戏,嵌入式系统等)
缺点
- Reliability:它默认所有对应的订阅者会接收到发布者发布的事件
- 当发布者和订阅者使中间代理超载时,可能出现瓶颈
性能
性能是关于时间和软件系统满足时序要求的能力
List Scheduling Method
第一步:排序任务
第二步:选择处理器
战术
控制资源需求
- 控制采样率
- 事件优先级
- 减少开销
- 限制执行时间
- 提高资源效率:提高算法
管理资源
- 提高资源
- 提高并发度
任务调度问题
单处理器任务包
多处理器任务包
DAGs调度在多处理器上
Job Shop Problem(JSP)
- 约束:每个任务要在每个处理器执行一次
安全性
安全性是衡量系统保护数据和信息免受未经授权访问的能力的一种度量方法,同时还提供对被授权的人和系统的访问
什么是安全性
- 保密性——保护数据或服务不受未经授权的访问的属性
- 完整性——数据或服务不受未经授权的操作的属性
- 可用性——系统可以合法使用的属性
- 身份验证——验证事务各方的身份,并检查他们是否真的如他们所声称的那样
- 授权——授予用户执行的权力
- 不可抵赖性
战术
检测攻击
检测入侵
检查服务否认:将进入系统的网络流量的模式或签名与已知拒绝服务(DoS)攻击的历史概括进行比较
检查消息的完整性:如校验和
检测消息延迟
抵抗攻击
标识参与者:标识系统的任何外部输入的来源。
验证参与者身份:确保用户或远程计算机实际上是它所声明的人或内容。
限制访问
限制暴露:通过尽可能少的访问点来最小化系统的攻击面。
应对攻击
撤销访问
锁定计算机
告知参与者
可测试性
软件可测试性指的是软件可以通过测试来演示其故障的容易程度
战术
控制并观察系统状态
专门的接口:set或get函数等
记录/回放:捕获跨接口的信息并将其用作进一步测试的输入。
本地化状态存储:要以测试的任意状态启动系统,最方便的方法是将该状态存储在单个位置。
沙盒:将系统与现实世界隔离以支持实验
可执行断言:断言是手工编码的,并放置在需要的位置,以指示程序何时以及何处处于错误状态
控制复杂度
限制结构复杂性:避免或解决组件之间的循环依赖关系,减少组件之间的依赖关系
限制非决定论:找出所有非决定论的来源,如无约束并行论,并尽可能地清除它们。
易用性
用于描述用户使用软件完成任务的难易度
战术
支持用户主动
取消:系统必须监听取消请求
暂停/恢复:暂时释放资源,以便重新分配给其他任务。
恢复:维护关于系统状态的足够数量的信息,以便可以恢复较早的状态
聚合:能够将较低级别的对象聚合到一个组中,这样就可以将用户操作应用到组中,从而将用户从重复操作中解放出来。
维护任务模型:确定上下文,以便系统能够了解用户正在尝试什么并提供帮助
维护系统模型:系统维护自己的显式模型。这用于确定预期的系统行为,以便向用户提供适当的反馈
其他质量属性
可移植性
用于描述在一个平台运行的软件移植到另一不同平台运行的难易程度
开发可分布性
开发可分布性是设计支持分布式软件开发的软件的质量。
可拓展性
水平可伸缩性(向外扩展)指向逻辑单元添加更多资源,比如向集群添加另一台服务器。
垂直可伸缩性(向上扩展)是指向物理单元添加更多的资源,比如向计算机添加更多的内存
可部署性
可部署性涉及可执行文件如何到达主机平台以及如何调用它。
机动性(Mobility)
机动性处理平台的移动和可承受性问题,如电池管理、断开与重新连接、蜂窝网络中的传递
可监测性
可监测性处理操作人员在系统执行时监视系统的能力。
架构与需求
- ASR = Architecturally Significant Requirement = 重要的架构需求
- 来自需求文档
- 采访干系人
- 组织质量属性研讨会 Quality Attribute Workshop(QAW)
- QAW演示和介绍:QAW主持人描述了QAW的动机,并解释了QAW的每个步骤
- 业务/任务介绍
- 架构计划展示
- 确定架构驱动程序
- 质量属性场景头脑风暴
- 整合质量属性场景
- 给质量属性场景分优先级
- 对质量属性场景进行细化
- 组织质量属性研讨会 Quality Attribute Workshop(QAW)
- 通过理解业务目标
- 在效用树
设计一个架构
设计一个架构: ADD = The Attribute-Driven Design Method = 属性驱动设计方法
一种迭代的方法。ADD并不能导致完整的设计。在每次迭代:
- 选择系统的一部分进行设计
- 组织该部分的所有架构上的重要需求
生成并测试该部分的设计
<!— - 有责任的容器集
容器间的交互和信息流
不为容器生成api —>
输入:需求, 上下文描述
输出:架构元素及其关系
step of ADD
- 选择系统的元素进行设计
- 确定所选元素的ASRs
- 为所选元素生成设计解决方案
- 统计剩余需求,并为下一次迭代选择输入
- 重复1-4直到ASRs满足
架构实现与测试
4种保持代码与架构一致性的技巧
- 将设计嵌入代码中:实现者知道他们正在实现什么样的架构。他们可以将代码中的体系结构文档作为注释记录。然后任何人拿起代码都会知道一些约束条件。有的工具可以自动关联代码和体系结构
- 框架方法。框架是围绕特定主体组织起来的可重用的库或类集。程序员使用框架提供的服务
- 代码模板方法。代码模板是代码集合,程序员在其中提供特定于应用程序的部分
- 保持代码和体系结构的一致性(即避免体系结构的侵蚀)。
- 实现可能会偏离文档体系结构
- 实施者可能做出与其他实施者和架构都不一致的决定
- 架构可能没有预见,提出所有可能性
- 使用工具强制架构约束。可以添加被强制执行的架构规则
- 在创建代码模板时,给剩下部分更多的信任/自由
- 计划文档/代码同步时间
两种级别的测试
单元测试:测试软件的特定片段
- 功能正确性的职责
- 综合负荷下的性能
- 故障注入后的可用性
- 可修改性的需求也可以通过将变更分配给测试团队来测试
集成测试:
- 测试功能、性能、可用性和安全性
- 通过测试执行各种攻击场景,可以对安全性进行测试
- 如果资源未释放或配置错误,系统运行很长时间后可能会降级
架构评价
架构评价的三种形式
- 设计者在设计过程中评价。每次设计者做出关键的设计决策时,所选择的方案都要进行评估
- 同行在设计过程中评价。同行评审可以在设计过程的任何地方进行,只要存在候选体系结构,或者至少是体系结构的一个连贯的可评审部分
- 设计完成后交给局外人评价,“外”是相对的,可能意味着
- 在开发项目之外
- 在项目所在的业务单元之外,但在同一家公司
- 公司以外
ATAM = Architecture Tradeoff Analysis Method = 架构权衡分析方法
ATAM是一个全面的评价软件架构的方法
- 介绍ATAM
- 现在的业务驱动程序
- 呈现架构
- 确定架构方法
- 生成Utility Tree
- 分析架构方法
- 头脑风暴和优先考虑情景
- 分析架构方法
- 展示结果
Lightweight Architecture Evaluation 是基于 ATAM 的,提供了一种低成本的评估软件架构的方法
云架构
云计算是一种信息技术(IT)范式,它支持无处不在地访问共享的系统资源池和更高级别的服务,这些资源和服务可以用最少的管理工作(通常是通过Internet)快速提供。
基本属性
随需应变。资源使用者可以根据需要单方面获得计算服务
资源池。云提供商的计算资源被合并。
无处不在的网络访问。云服务和资源可以通过异构网络访问
位置独立性。资源的位置不必与资源的使用者有关。
快速的弹性。能力可以迅速而灵活地提供。
现收现付制。服务的消费者仅根据他们使用的内容付费
多租户。应用程序和资源可以在不了解彼此的多个使用者之间共享。
基本的服务模型
Software as a Service (SaaS).
在这种情况下,消费者是最终用户。
消费者使用在云上运行的应用程序。
E.g. e-mail services
Platform as a Service (PaaS).
这里的消费者是开发人员
为用户提供在云上开发和部署应用程序的编程语言和工具
Infrastructure as a Service (IaaS).
本例中的使用者是开发人员或系统管理员。
提供处理、存储、网络和其他基础计算资源
使用者可以部署和运行任意软件,包括操作系统和应用程序
部署模式
Public cloud.云基础设施向公众开放,并由出售云服务的组织拥有。
Private cloud.云基础设施仅由单个组织拥有,且仅为该组织拥有的应用程序运行。
Community cloud.云基础设施由多个组织共享,并支持共享关注点的特定社区
Hybrid cloud.云基础设施是两个或多个云(私有、社区或公共)的组合