软件架构(software architecture)
学习笔记,内容来自网络,橙色为自己总结,如有错误还请指正。
目录
软件架构(software architecture)
一、架构的定义
二、软件架构定义
三、架构的种类
逻辑架构:软件系统中元件之间的关系,比如用户界面,数据库,外部系统接口、商业逻辑元件等
物理架构:软件元件是怎样放到硬件上的
系统架构:系统的非功能性特征,如可扩展性、强壮性、灵活性、可靠性、性能等
四、架构的表现形式----4+1视图
逻辑视图(Logic View)
处理视图(Process view)
物理视图(PhysicalView)
开发视图(DevelopmentView)
场景视图(用例视图)
五、软件架构设计的目标
六、软件架构的作用
七、五种常见软件架构
1.分层架构
2.事件驱动架构
3.微核架构
4.微服务架构
5.云架构
一、架构的定义
软件架构的定义大体分为“决策”论和“组成”论。
比较著名的“决策”论的定义是Booch,Rumbaugh和Jacobson于1999年提出的:架构就是一系列重要的决策,这些决策涉及软件系统的组织、组成系统的结构化元素及其接口的选择、元素之间协作时特定的行为、结构化元素和行为元素形成更大子系统的组合方式以及引导这一组织(也就是这些元素及其接口)、他们之间的协作以及组合(架构风格)。
“组成”论中最受推崇的是SEI(Software Engineering Institute)的Len Bass等人提出的定义:程序或计算系统的软件架构是系统的一个或多个结构,它包括软件元素、这些元素的外部可见属性以及它们之间的关系。
架构是规划、设计、构建的过程及最终成果。
参考资料里对架构下的定义为:架构是特定约束下决策的结果,并且这是一个循环递进的过程。
- 特定约束
任何行为、言语、结论都有一个context(上下文)为前提,某一个架构换一个场景可能并不适用。这个context就称为约束。但是必须是特定约束,不能是泛约束(约束必须具体,不能宽泛)。
- 决策
决策是一个过程,实际上就是选择。选择技术、结构、通信方式等内容,去符合特定约束。
- 结果
是决策的最终产物,可能是运行良好、满足需求的系统。也可能是一堆文档。如果这个结果是五视图(架构表现形式)、组件、接口、子系统、及其之间的关系,那么这个架构就是软件架构。
完善的需求(功能性、非功能性),实际就是架构的「特定约束」。而对上面这些问题的选择,就是「决策」。这些决策确定后,需要相关的设计图,这些图纸就是你决策的部分结果。最终交付给客户的才是你架构的最终成果。
架构和设计的关系:架构是顶层设计!
从操作层面做决策:用户从哪里进入、页面应该跳转到哪里、应该输入哪些信息.....这就是流程设计!
从代码层面决策,代码该怎么写:模块如何组织、包如何组织、类如何组织、方法如何组织......这就是代码设计!
从系统整体层面决策:子系统如何组织、组件如何组织、接口如何设计......这就是架构设计!
二、软件架构定义
参考资料:百度百科
软件架构(software architecture)是一系列相关的抽象模式,用于指导大型软件系统各个方面的设计。软件架构是一个系统的草图。软件架构描述的对象是直接构成系统的抽象组件。各个组件之间的连接则明确和相对细致地描述组件之间的通讯。在实现阶段,这些抽象组件被细化为实际的组件,比如具体某个类或者对象。在面向对象领域中,组件之间的连接通常用接口来实现
软件架构是指在一定的设计原则基础上,从不同角度对组成系统的各部分进行搭配和安排,形成系统的多个结构而组成架构,它包括该系统的各个组件,组件的外部可见属性及组件之间的相互关系。组件的外部可见属性是指其他组件对该组件所做的假设。
David GArlan和 Mary Shaw认为软件构架“在计算的算法和数据结构之外,设计并确定系统整体结构成为了新的问题。结构问题包括总体组织结构和全局控制结构;通信、同步和数据访问的协议;设计元素的功能分配;物理分布;设计元素的组成;定标与性能;备选设计的选择。”
但构架不仅是结构
IEEEWorking Group on Architecture 把其定义为“系统在其环境中的最高层概念”。构架还包括“符合”系统完整性、经济约束条件、审美需求和样式。
它并不仅注重对内部的考虑,而且还在系统的用户环境和开发环境中对系统进行整体考虑,即同时注重对外部的考虑。
一般而言,软件系统的架构(ArchitECture)有两个要素:
1.它是一个软件系统从整体到部分的最高层次的划分。
2.一个系统通常是由元件组成的,而这些元件如何形成、相互之间如何发生作用,则是关于这个系统本身结构的重要信息。
详细地说,就是要包括架构元件(Architecture Component)、联结器(Connector)、任务流(TASk-flow)。所谓架构元素,也就是组成系统的核心"砖瓦",而联结器则描述这些元件之间通讯的路径、通讯的机制、通讯的预期结果,任务流则描述系统如何使用这些元件和联结器完成某一项需求。
总结:软件架构是一系列相关的抽象模式,用于指导大型软件系统各个方面的设计,包括架构元件(构成系统的各种组件)、联结器(组件之间通信的路径和机制)、任务流(系统如何使用元件和联结器完成需求)。不仅注重对系统内部(功能因素)的考虑,同时注重对系统外部(非功能因素)的考虑
三、架构的种类
根据关注的角度不同,可以将架构分成三种
逻辑架构:软件系统中元件之间的关系,比如用户界面,数据库,外部系统接口、商业逻辑元件等
从上面这张图中可以看出,此系统被划分成三个逻辑层次,即表象层次,商业层次和数据持久层次。每一个层次都含有多个逻辑元件
物理架构:软件元件是怎样放到硬件上的
比如下面这张物理架构图,图中所有的元件都是物理设备,包括网络分流器、代理服务器、WEB服务器、应用服务器、报表服务器、整合服务器、存储服务器、主机等等
系统架构:系统的非功能性特征,如可扩展性、强壮性、灵活性、可靠性、性能等
首先,一个软件系统中的元件首先是逻辑元件。这些逻辑元件如何放到硬件上,以及这些元件如何为整个系统的可扩展性、可靠性、强壮性、灵活性、性能等做出贡献,是非常重要的信息。
其次,进行软件设计需要做出的决定中,必然会包括逻辑结构、物理结构,以及它们如何影响到系统的所有非功能性特征。这些决定中会有很多是一旦作出,就很难更改的。
四、架构的表现形式----4+1视图
以多种构架视图来表示软件构架。每种构架视图针对于开发流程中的涉众(例如最终用户、设计人员、管理人员、系统工程师、维护人员等)所关注的特定方面。一个架构视图是对于从某一视角或某一点上看到的系统所做的简化描述,描述中涵盖了系统的某一特定方面,而省略了于此方面无关的实体。
也就是说,架构要涵盖的内容和决策太多了,超过了人脑"一蹴而就"的能力范围,因此采用"分而治之"的办法从不同视角分别设计;同时,也为软件架构的理解、交流和归档提供了方便。
逻辑视图(Logic View)
逻辑视图用来描述系统的功能需求,即在为用户提供服务方面系统所应该提供的功能。在逻辑视图中,系统分解成一系列的功能抽象、功能分解与功能分析,这些主要来自问题领域(ProblemDefinition)。在面向对象技术中,表现为对象或对象类的形式,采用抽象、封装和继承的原理。用对象模型来代表逻辑视图,可以用类图(Class Diagram)来描述逻辑视图。借助于类图和类模板的手段 ,类图用来显示一个类的集合和它们的逻辑关系:关联、使用、组合、继承等。相似的类可以划分成类集合。类模板关注于单个类,它们强调主要的类操作,并且识别关键的对象特征。
逻辑视图的表示法:
构件(Components):类、类服务、参数化类、类层次
连接件(Connectors):关联、包含聚集、使用、继承、实例化
逻辑视图的风格采用面向对象的风格,其主要的设计准则是试图在整个系统中保持单一的、一致的对象模型,避免就每个场合或过程产生草率的类和机制的技术说明。
处理视图(Process view)
又称“进程视图”,又称“处理视图”。
过程架构考虑一些非功能性的需求,如性能和可用性。它解决并发性、分布性、系统完整性、容错性的问题,以及逻辑视图的主要抽象如何与进程结构相配合在一起,即定义逻辑视图中的各个类的具体操作是在哪一个线程(Thread)中被执行。过程视图侧重系统的运行特性。服务于系统集成人员,方便后续性能测试
Ø 构件:进程、简化进程、循环进程
Ø 连接件:消息、远程过程调用(RPC)、双向消息、事件广播 。
过程视图:关注进程、线程、对象等运行时概念,以及相关的并发、同步和通信等问题。
进程架构可以在几种层次的抽象上进行描述,每个层次针对不同的问题。在最高的层次上,进程架构可以视为一组独立执行的通信程序(叫作"processes")的逻辑网络,它们分布在整个一组硬件资源上,这些资源通过 LAN 或者 WAN 连接起来。多个逻辑网络可能同时并存,共享相同的物理资源。
接着,我们可以区别主要任务、次要任务。主要任务是可以唯一处理的架构元素;次要任务是由于实施原因而引入的局部附加任务(周期性活动、缓冲、暂停等等)。主要任务的通讯途径是良好定义的交互任务通信机制:基于消息的同步或异步通信服务、远程过程调用、事件广播等。次要任务则以会见或共享内存来通信。在同一过程或处理节点上,主要任务不应对它们的分配做出任何假定。
物理视图(PhysicalView)
主要描述硬件配置。服务于系统工程人员,解决系统的拓扑结构、系统安装、通信等问题。主要考虑如何把软件映射到硬件上,也要考虑系统性能、规模、可靠性等。可以与进程视图一起映射。物理架构主要关注系统非功能性的需求,如可用性、可靠性(容错性),性能(吞吐量)和可伸缩性。
软件在计算机网络或处理节点上运行,被识别的各种元素(网络、过程、任务和对象),需要被映射至不同的节点;我们希望使用不同的物理配置:一些用于开发和测试,另外一些则用于不同地点和不同客户的部署。因此软件至节点的映射需要高度的灵活性及对源代码产生最小的影响。
物理视图的表示法
Ø 构件:处理器、计算机、其它设备
Ø 连接件:通信协议等
物理视图和处理视图的关系:处理视图特别关注目标程序的动态执行情况,而物理视图重视目标程序的静态位置问题;
开发视图(DevelopmentView)
描述了在开发环境中软件的静态组织结构,即关注软件开发环境下实际模块的组织,服务于软件编程人员。将软件打包成小的程序块(程序库或子系统),它们可以由一位或几位开发人员来开发。子系统可以组织成分层结构,每个层为上一层提供良好定义的接口。
系统的开发架构用模块和子系统图来表达,显示了"输出"和"输入"关系。完整的开发架构只有当所有软件元素被识别后才能加以描述。但是,可以列出控制开发架构的规则:分块、分组和可见性。
开发视图的风格通常是层次结构,每个层为上一层提供良好定义的接口,层次越低,通用性越好。
开发视图的表示方法:
Ø 构件:模块、子系统、层
Ø 连接件:参照相关性、模块/过程调用
大部分情况下,开发架构考虑的内部需求与以下几项因素有关:开发难度、软件管理、重用性和通用性及由工具集、编程语言所带来的限制。开发架构视图是各种活动的基础,如:需求分配、团队工作的分配(或团队机构)、成本评估和计划、项目进度的监控、软件重用性、移植性和安全性。它是建立产品线的基础。
场景视图(用例视图)
它综合所有的视图。用于刻画构件之间的相互关系,将四个视图有机地联系起来。可以描述一个特定的视图内的构件关系,也可以描述不同视图间的构件关系。
四种视图的元素通过一组重要场景(更常见的是用例)进行无缝协同工作,我们为场景描述相应的脚本(对象之间和过程之间的交互序列)。在某种意义上场景是最重要的需求抽象,它们的设计使用对象场景图和对象交互图来表示。
场景视图是其他视图的冗余(因此"+1"),但它起到了两个作用:
- 作为一项驱动因素来发现架构设计过程中的架构元素。
- 作为架构设计结束后的一项验证和说明功能,既以视图的角度来说明,又作为架构原型测试的出发点。
五、软件架构设计的目标
1.可靠性(Reliable)。软件系统对于用户的商业经营和管理来说极为重要,因此软件系统必须非常可靠。
2.安全性(Secure)。软件系统所承担的交易的商业价值极高,系统的安全性非常重要。
3.可扩展性(SCAlable)。软件必须能够在用户的使用率、用户的数目增加很快的情况下,保持合理的性能。只有这样,才能适应用户的市场扩展得可能性。
4.可定制化(CuSTomizable)。同样的一套软件,可以根据客户群的不同和市场需求的变化进行调整。
5.可扩展性(Extensible)。在新技术出现的时候,一个软件系统应当允许导入新技术,从而对现有系统进行功能和性能的扩展。
6.可维护性(MAIntainable)。软件系统的维护包括两方面,一是排除现有的错误,二是将新的软件需求反映到现有系统中去。一个易于维护系统可以有效地降低技术支持的花费。
7.客户体验(Customer Experience)。软件系统必须易于使用。
8.市场时机(Time to Market)。软件用户要面临同业竞争,软件提供商也要面临同业竞争。以最快的速度争夺市场先机非常重要。
六、软件架构的作用
1、开发新产品过程中软件架构所具备的作用分析
所谓的软件架构则是属于在现实的世界与计算机领域所搭建起来的一座沟通的桥梁
第一点就是进行业务目标的上乘。从本质上来看,软件架构往往存在着出于将业务目标完成而必须开展相应的大局规划的责任
第二点所指的就是进行技术决策的下接。凭借着把面向业务的相关需求往面向技术方向转向的软件架构设计方案,这可以将行之有效的限制与指导提供给后续的技术开发工作
第三点就是有效的将新产品的质量提升;第四点所指的就是进相应的新产品开发过程的组织;第五点所指的就是借助于相应的迭代实施相应新产品开展与增量的交付;第六点则是说控制所具备的复杂性,立足于相应的分而治之的思想,
2、 开发软件产品过程中系统架构所具备的作用分析
第一就是将所具备的相应的核心知识予以固话;第二就是可以提供相应的可重用资产;第三就是将产品推出的周期进行有效的缩短;第四就是使得产品开发与维护的总成本得以最大限度的降低;第五就是将产品的质量有效的提升;第六就是为批量控制提供有效的支持。
3、 软件产品线架构所具备的特点分析
第一个作用就是应该将一系列的明确许可的变化进行考虑;第二个作用所指的就是必须做到文档化;第三个作用就是说应该可以存在着相应的产品创建者指南,将实例化架构的整个过程进行描述。
4、维护软件过程中软件架构的作用分析
从本质上来看,相应的软件维护工作主要的来源是Bug与需求变更。往往修复一个Bug与增加一个新的功能,那么通常都会涉及到架构环节的一条模块协作链,针对这样的情况,软件架构比有利于维护工作的开展;反之,如果对于架构并不能了解,相应的进行程序的盲目修改,这也就会存在着可能性对架构设计的思路造成未必,从而导致整个系统所存在的架构逐步显得比较混乱,这也就会存在着可能性导致出现不可思议的Bug与问题。
5、软件升级过程中软件架构的作用分析
相应的软件架构则是通过对软件系统实施持续性的修改,还应该必须做好重构,往往对其实施重构主要是两种状况:第一种状况就是特别混乱的架构,从而导致实施一个比较小的改动就会出现牵动全身;第二种状况所指的就是即将实施的升级软件存在着比较大的力度,之前的软件架构与新的需求根本就不能适应。相应的软件架构予以重构则是属于再工程的一种情况,往往必须实施的步骤为逆向工程、重新规划、正向工程这样的三个步骤
七、五种常见软件架构
1.分层架构(layered architecture)
分层架构(layered architecture)是最常见的软件架构,也是事实上的标准架构。如果你不知道要用什么架构,那就用它。
这种架构将软件分成若干个水平层,每一层都有清晰的角色和分工,不需要知道其他层的细节。层与层之间通过接口通信。
虽然没有明确约定,软件一定要分成多少层,但是四层的结构最常见
- 表现层(presentation):用户界面,负责视觉和用户互动
- 业务层(business):实现业务逻辑
- 持久层(persistence):提供数据,SQL 语句就放在这一层
- 数据库(database) :保存数据
有的软件在逻辑层和持久层之间,加了一个服务层(service),提供不同业务逻辑需要的一些通用接口。
用户的请求将依次通过这四层的处理,不能跳过其中任何一层。
优点
- 结构简单,容易理解和开发
- 不同技能的程序员可以分工,负责不同的层,天然适合大多数软件公司的组织架构
- 每一层都可以独立测试,其他层的接口通过模拟解决
缺点
- 一旦环境变化,需要代码调整或增加功能时,通常比较麻烦和费时
- 部署比较麻烦,即使只修改一个小地方,往往需要整个软件重新部署,不容易做持续发布
- 软件升级时,可能需要整个服务暂停
- 扩展性差。用户请求大量增加时,必须依次扩展每一层,由于每一层内部是耦合的,扩展会很困难
2.事件驱动架构(event-driven architecture)
事件(event)是状态发生变化时,软件发出的通知。
事件驱动架构就是通过事件进行通信的软件架构。它分成四个部分。
- 事件队列(event queue):接收事件的入口
- 分发器(event mediator):将不同的事件分发到不同的业务逻辑单元
- 事件通道(event channel):分发器与处理器之间的联系渠道
- 事件处理器(event processor):实现业务逻辑,处理完成后会发出事件,触发下一步操作
对于简单的项目,事件队列、分发器和事件通道,可以合为一体,整个软件就分成事件代理和事件处理器两部分。
优点
- 分布式的异步架构,事件处理器之间高度解耦,软件的扩展性好
- 适用性广,各种类型的项目都可以用
- 性能较好,因为事件的异步本质,软件不易产生堵塞
- 事件处理器可以独立地加载和卸载,容易部署
缺点
- 涉及异步编程(要考虑远程通信、失去响应等情况),开发相对复杂
- 难以支持原子性操作,因为事件通过会涉及多个处理器,很难回滚
- 分布式和异步特性导致这个架构较难测试
3.微核架构(microkernel architecture)
微核架构又称为"插件架构"(plug-in architecture),指的是软件的内核相对较小,主要功能和业务逻辑都通过插件实现。
内核(core)通常只包含系统运行的最小功能。插件则是互相独立的,插件之间的通信,应该减少到最低,避免出现互相依赖的问题。
优点
- 良好的功能延伸性(extensibility),需要什么功能,开发一个插件即可
- 功能之间是隔离的,插件可以独立的加载和卸载,使得它比较容易部署,
- 可定制性高,适应不同的开发需要
- 可以渐进式地开发,逐步增加功能
缺点
- 扩展性(scalability)差,内核通常是一个独立单元,不容易做成分布式
- 开发难度相对较高,因为涉及到插件与内核的通信,以及内部的插件登记机制
4.微服务架构(microservices architecture)
微服务架构是服务导向架构(service-oriented architecture,缩写 SOA)的升级。
每一个服务就是一个独立的部署单元(separately deployed unit)。这些单元都是分布式的,互相解耦,通过远程通信协议(比如REST、SOAP)联系。
微服务架构分成三种实现模式。
- RESTful API 模式:服务通过 API 提供,云服务就属于这一类
- RESTful 应用模式:服务通过传统的网络协议或者应用协议提供,背后通常是一个多功能的应用程序,常见于企业内部
- 集中消息模式:采用消息代理(message broker),可以实现消息队列、负载均衡、统一日志和异常处理,缺点是会出现单点失败,消息代理可能要做成集群
优点
- 扩展性好,各个服务之间低耦合
- 容易部署,软件从单一可部署单元,被拆成了多个服务,每个服务都是可部署单元
- 容易开发,每个组件都可以进行持续集成式的开发,可以做到实时部署,不间断地升级
- 易于测试,可以单独测试每一个服务
缺点
- 由于强调互相独立和低耦合,服务可能会拆分得很细。这导致系统依赖大量的微服务,变得很凌乱和笨重,性能也会不佳。
- 一旦服务之间需要通信(即一个服务要用到另一个服务),整个架构就会变得复杂。典型的例子就是一些通用的 Utility 类,一种解决方案是把它们拷贝到每一个服务中去,用冗余换取架构的简单性。
- 分布式的本质使得这种架构很难实现原子性操作,交易回滚会比较困难。
5.云架构(cloud architecture)
云结构主要解决扩展性和并发的问题,是最容易扩展的架构。
它的高扩展性,主要原因是没使用中央数据库,而是把数据都复制到内存中,变成可复制的内存数据单元。然后,业务处理能力封装成一个个处理单元(prcessing unit)。访问量增加,就新建处理单元;访问量减少,就关闭处理单元。由于没有中央数据库,所以扩展性的最大瓶颈消失了。由于每个处理单元的数据都在内存里,最好要进行数据持久化。
这个模式主要分成两部分:处理单元(processing unit)和虚拟中间件(virtualized middleware)。
- 处理单元:实现业务逻辑
- 虚拟中间件:负责通信、保持sessions、数据复制、分布式处理、处理单元的部署。
虚拟中间件又包含四个组件。
- 消息中间件(Messaging Grid):管理用户请求和session,当一个请求进来以后,决定分配给哪一个处理单元。
- 数据中间件(Data Grid):将数据复制到每一个处理单元,即数据同步。保证某个处理单元都得到同样的数据。
- 处理中间件(Processing Grid):可选,如果一个请求涉及不同类型的处理单元,该中间件负责协调处理单元
- 部署中间件(Deployment Manager):负责处理单元的启动和关闭,监控负载和响应时间,当负载增加,就新启动处理单元,负载减少,就关闭处理单元。
优点
- 高负载,高扩展性
- 动态部署
缺点
- 实现复杂,成本较高
- 主要适合网站类应用,不合适大量数据吞吐的大型数据库应用
- 较难测试