森.林木

架构设计:架构风格及其应用分析

数据流风格(Data Flow)

面向数据的架构风格,有简单的批处理风格和管道-过滤器风格等

批处理风格(Batch Sequential)

线性处理,典型例子是:Unix批处理指令

批处理风格

优点:

  • 高内聚、低耦合
  • 简单:维护、扩展、拼接
  • 重用

缺点:

  • 不适合实时系统
  • 过滤器都增加导致系统性能下降

变化:

  • 过滤器可以是同一进程内的处理模块,也可以是跨进程、跨地域的不同服务
  • 过滤器可以是一个过程、一个类、一个组件、一个模块、甚至一个系统(可以和面向过程、面向对象、面向组件、面向服务等不同的风格组合)

    管道-过滤器风格(Pipe-Filter)

多路处理,典型例子是编译器

管道-过滤器风格

优点:

  • 高内聚、低耦合
  • 简单:维护、扩展、拼接
  • 重用
  • 并行:多过滤器同时执行

缺点:

  • 退化成批处理的结构
  • 不适合实时系统
  • 过滤器都增加导致系统性能下降

变化:

  • 过滤器可以是同一进程内的处理模块,也可以是跨进程、跨地域的不同服务
  • 过滤器可以是一个过程、一个类、一个组件、一个模块、甚至一个系统(可以和面向过程、面向对象、面向组件、面向服务等不同的风格组合)

数据中心风格(Data-Centered)

仓库风格
数据中心风格的体系结构由两种构件组成:

  • 中央数据结构——表示当前状态
  • 独立构件的集合——对中央数据结构进行操作。

根据事务发起的主动方不同,可分为2种风格

  • 仓库风格:由构件发起事务,选择进行何种处理,并把执行结果作为当前状态存储到中央数据结构中
  • 黑板风格:由中央数据结构的当前状态决定进行何种处理

仓库风格(Repository)

由客户端或构件发起事务,典型的例子是数据库系统

仓库风格

优点:

  • 支持数据集成、备份和恢复
  • 组件可扩展、可重用
  • 独立

缺点:

  • 数据完整性不好保证
  • 数据结构依赖
  • 数据中心扩展性弱

变化:

  • 数据中心的扩展性需要额外设计,如采用分布式数据中心
  • 数据的完整性可以通过锁机制实现,但是影响系统性能

黑板风格(Blackboard)

(1)知识源:知识源中包含独立的、与应用程序相关的知识,知识源之间不直接进行通讯,它们之间的交互只通过黑板来完成。

(2)黑板数据结构:黑板数据是按照与应用程序相关的层次来组织的解决问题的数据,知识源通过不断地改变黑板数据来解决问题。

(3)控制:控制完全由黑板的状态驱动,黑板状态的改变决定使用的特定知识。

黑板系统的传统应用是信号处理领域,如语音和模式识别

黑板风格

优点:

  • 可扩展性
  • 并发
  • 复用

缺点:

  • 数据结构强依赖
  • 可测试性差

变化:

  • 黑板风格并不是舞台风格,两者完全不同

分层架构(layered architecture)

这种架构将软件分成若干个水平层,每一层都有清晰的角色和分工,不需要知道其他层的细节。层与层之间通过接口通信。虽然没有明确约定,软件一定要分成多少层,但是四层的结构最常见:

  • 表现层(presentation):用户界面,负责视觉和用户互动
  • 业务层(business):实现业务逻辑
  • 持久层(persistence):提供数据,SQL 语句就放在这一层
  • 数据库(database) :保存数据

有的软件在逻辑层和持久层之间,加了一个服务层(service),提供不同业务逻辑需要的一些通用接口。
用户的请求将依次通过这四层的处理,不能跳过其中任何一层。

分层架构

分层架构

优点:

  • 结构简单,容易理解和开发
    • 不同技能的程序员可以分工,负责不同的层,天然适合大多数软件公司的组织架构
  • 每一层都可以独立测试,其他层的接口通过模拟解决

缺点:

  • 一旦环境变化,需要代码调整或增加功能时,通常比较麻烦和费时
  • 部署比较麻烦,即使只修改一个小地方,往往需要整个软件重新部署,不容易做持续发布
  • 软件升级时,可能需要整个服务暂停
  • 扩展性差。用户请求大量增加时,必须依次扩展每一层,由于每一层内部是耦合的,扩展会很困难

客户端/服务器

Client/Server

C/S架构是第一种比较早的软件架构,主要用于局域网内。也叫 客户机/服务器模式。它可以分为客户机和服务器两层:第一层是在客户机系统上结合了界面显示与业务逻辑,第二层是通过网络结合了数据库服务器。

C/S 可以看做是胖客户端架构。因为客户端需要实现绝大多数的业务逻辑和界面展示。作为客户端的部分需要承受很大的压力,因为显示逻辑和事务处理都包含在其中,通过与数据库的交互(通常是SQL或存储过程的实现)来达到持久化数据,以此满足实际项目的需要。

C/S架构

优点:

  • 强交互性
  • 安全性
  • 性能好

缺点:

  • 部署升级难
  • 推广难
  • 兼容性差

Browse/Server

B/S架构的全称为Browser/Server,即浏览器/服务器结构。Browser指的是Web浏览器,极少数事务逻辑在前端实现,但主要事务逻辑在服务器端实现。B/S架构的系统无须特别安装,只有Web浏览器即可。

B/S架构有三层,分别为:

  • 表现层:主要完成用户和后台的交互及最终查询结果的输出功能。
  • 逻辑层:主要是利用服务器完成客户端的应用逻辑功能。
  • 数据层:主要是接受客户端请求后独立进行各种运算。

B/S架构的几种形式

第一种:客户端-服务器-数据库

B/S架构

这个应该是我们平时比较常用的一种模式:
1、客户端向服务器发起Http请求
2、服务器中的web服务层能够处理Http请求
3、服务器中的应用层部分调用业务逻辑,调用业务逻辑上的方法
4、如果有必要,服务器会和数据库进行数据交换. 然后将模版+数据渲染成最终的Html, 返送给客户端

第二种:客户端-web服务器-应用服务器-数据库

B/S架构

类似于第一种方法,只是将web服务和应用服务解耦

1、客户端向web服务器发起Http请求
2、web服务能够处理Http请求,并且调用应用服务器暴露在外的RESTFUL接口
3、应用服务器的RESTFUL接口被调用,会执行对应的暴露方法.如果有必要和数据库进行数据交互,应用服务器会和数据库进行交互后,将json数据返回给web服务器
4、web服务器将模版+数据组合渲染成html返回给客户端

第三种方法:客户端-负载均衡器(Nginx)-中间服务器(Node)-应用服务器-数据库

这种模式一般用在有大量的用户,高并发的应用中。

B/S架构

1、整正暴露在外的不是真正web服务器的地址,而是负载均衡器器的地址
2、客户向负载均衡器发起Http请求
3、负载均衡器能够将客户端的Http请求均匀的转发给Node服务器集群
4、Node服务器接收到Http请求之后,能够对其进行解析,并且能够调用应用服务器暴露在外的RESTFUL接口
5、应用服务器的RESTFUL接口被调用,会执行对应的暴露方法.如果有必要和数据库进行数据交互,应用服务器会和数据库进行交互后,将json数据返回给Node
6、Node层将模版+数据组合渲染成html返回反向代理服务器
7、反向代理服务器将对应html返回给客户端

优点:

  • 客户端无需安装,有Web浏览器即可。
  • BS架构可以直接放在广域网上,通过一定的权限控制实现多客户访问的目的,交互性较强。
  • BS架构无需升级多个客户端,升级服务器即可。可以随时更新版本,而无需用户重新下载啊什么的。

缺点:

  • 在跨浏览器上,BS架构不尽如人意。
  • 表现要达到CS程序的程度需要花费不少精力。
  • 在速度和安全性上需要花费巨大的设计成本,这是BS架构的最大问题。
  • 客户端服务器端的交互是请求-响应模式,通常需要刷新页面,这并不是客户乐意看到的。(在Ajax风行后此问题得到了一定程度的缓解)

面向对象架构

抽象数据类型概念对软件系统有着重要作用,目前软件界已普遍转向使用面向对象系统。这种风格建立在数据抽象和面向对象的基础上,数据的表示方法和它们的相应操作封装在一个抽象数据类型或对象中。这种风格的构件是对象,或者说是抽象数据类型的实例。对象是一种被称作管理者的构件,因为它负责保持资源的完整性。对象是通过函数和过程的调用来交互的。

面向对象

优点:

  • 因为对象对其它对象隐藏它的表示,所以可以改变一个对象的表示,而不影响其它的对象。
  • 设计者可将一些数据存取操作的问题分解成一些交互的代理程序的集合。

缺点:

  • 为了使一个对象和另一个对象通过过程调用等进行交互,必须知道对象的标识。只要一个对象的标识改变了,就必须修改所有其他明确调用它的对象。
  • 必须修改所有显式调用它的其它对象,并消除由此带来的一些副作用。例如,如果A使用了对象B,C也使用了对象B,那么,C对B的使用所造成的对A的影响可能是料想不到的。

变化:

  • 对象的概念再扩大化,即是组件、模块,演化成基于组件的架构

面向服务架构

微服务架构

微服务架构(microservices architecture)是服务导向架构(service-oriented architecture,缩写 SOA)的升级。每一个服务就是一个独立的部署单元(separately deployed unit)。这些单元都是分布式的,互相解耦,通过远程通信协议(比如REST、SOAP)联系。

微服务架构分成三种实现模式:

  • RESTful API 模式:服务通过 API 提供,云服务就属于这一类
  • RESTful 应用模式:服务通过传统的网络协议或者应用协议提供,背后通常是一个多功能的应用程序,常见于企业内部
  • 集中消息模式:采用消息代理(message broker),可以实现消息队列、负载均衡、统一日志和异常处理,缺点是会出现单点失败,消息代理可能要做成集群

微服务架构

优点:

  • 扩展性好,各个服务之间低耦合
  • 容易部署,软件从单一可部署单元,被拆成了多个服务,每个服务都是可部署单元
  • 容易开发,每个组件都可以进行持续集成式的开发,可以做到实时部署,不间断地升级
  • 易于测试,可以单独测试每一个服务

缺点:

  • 由于强调互相独立和低耦合,服务可能会拆分得很细。这导致系统依赖大量的微服务,变得很凌乱和笨重,性能也会不佳。
  • 一旦服务之间需要通信(即一个服务要用到另一个服务),整个架构就会变得复杂。典型的例子就是一些通用的 Utility 类,一种解决方案是把它们拷贝到每一个服务中去,用冗余换取架构的简单性。
  • 分布式的本质使得这种架构很难实现原子性操作,交易回滚会比较困难。

Restful架构

Restful架构本质上是一种资源定位风格,属于接口风格。RESTful架构:

  • 每一个URI代表一种资源;
  • 客户端和服务器之间,传递这种资源的某种表现层;
  • 客户端通过四个HTTP动词,对服务器端资源进行操作,实现”表现层状态转化”。

理解REST风格的架构所具有的6个的主要特征:

  • 面向资源(Resource Oriented)
  • 可寻址(Addressability)
  • 连通性(Connectedness)
  • 无状态(Statelessness)
  • 统一接口(Uniform Interface)
  • 超文本驱动(Hypertext Driven)

从架构风格的抽象高度来看,常见的分布式应用架构风格有三种:

分布式对象(Distributed Objects,简称DO)
架构实例有CORBA/RMI/EJB/DCOM/.NET Remoting等等

远程过程调用(Remote Procedure Call,简称RPC)
架构实例有SOAP/XML-RPC/Hessian/Flash AMF/DWR等等

表述性状态转移(Representational State Transfer,简称REST)
架构实例有HTTP/WebDAV

DO和RPC这两种架构风格在企业应用中非常普遍,而REST则是Web应用的架构风格,它们之间有非常大的差别。

REST与DO的差别在于:

REST支持抽象(即建模)的工具是资源,DO支持抽象的工具是对象。在不同的编程语言中,对象的定义有很大差别,所以DO风格的架构通常都是与某种编程语言绑定的。跨语言交互即使能实现,实现起来也会非常复杂。而REST中的资源,则完全中立于开发平台和编程语言,可以使用任何编程语言来实现。
DO中没有统一接口的概念。不同的API,接口设计风格可以完全不同。DO也不支持操作语义对于中间组件的可见性。
DO中没有使用超文本,响应的内容中只包含对象本身。REST使用了超文本,可以实现更大粒度的交互,交互的效率比DO更高。
REST支持数据流和管道,DO不支持数据流和管道。
DO风格通常会带来客户端与服务器端的紧耦合。在三种架构风格之中,DO风格的耦合度是最大的,而REST的风格耦合度是最小的。REST松耦合的源泉来自于统一接口+超文本驱动。

REST与RPC的差别在于:

REST支持抽象的工具是资源,RPC支持抽象的工具是过程。REST风格的架构建模是以名词为核心的,RPC风格的架构建模是以动词为核心的。简单类比一下,REST是面向对象编程,RPC则是面向过程编程。
RPC中没有统一接口的概念。不同的API,接口设计风格可以完全不同。RPC也不支持操作语义对于中间组件的可见性。
RPC中没有使用超文本,响应的内容中只包含消息本身。REST使用了超文本,可以实现更大粒度的交互,交互的效率比RPC更高。
REST支持数据流和管道,RPC不支持数据流和管道。
因为使用了平台中立的消息,RPC风格的耦合度比DO风格要小一些,但是RPC风格也常常会带来客户端与服务器端的紧耦合。支持统一接口+超文本驱动的REST风格,可以达到最小的耦合度。

比较了三种架构风格之间的差别之后,从面向实用的角度来看,REST架构风格可以为Web开发者带来三方面的利益:

简单性
采用REST架构风格,对于开发、测试、运维人员来说,都会更简单。可以充分利用大量HTTP服务器端和客户端开发库、Web功能测试/性能测试工具、HTTP缓存、HTTP代理服务器、防火墙。这些开发库和基础设施早已成为了日常用品,不需要什么火箭科技(例如神奇昂贵的应用服务器、中间件)就能解决大多数可伸缩性方面的问题。

可伸缩性
充分利用好通信链各个位置的HTTP缓存组件,可以带来更好的可伸缩性。其实很多时候,在Web前端做性能优化,产生的效果不亚于仅仅在服务器端做性能优化,但是HTTP协议层面的缓存常常被一些资深的架构师完全忽略掉。

松耦合
统一接口+超文本驱动,带来了最大限度的松耦合。允许服务器端和客户端程序在很大范围内,相对独立地进化。对于设计面向企业内网的API来说,松耦合并不是一个很重要的设计关注点。但是对于设计面向互联网的API来说,松耦合变成了一个必选项,不仅在设计时应该关注,而且应该放在最优先位置。

消息总线

消息总线

消息总线

消息总线

多层消息总线

基于事件架构

基于事件的架构是消息总线架构的一种特殊情况。常用于UI系统。事件(event)是状态发生变化时,软件发出的通知。事件驱动架构(event-driven architecture)就是通过事件进行通信的软件架构。它分成四个部分:

    • 事件队列(event queue):接收事件的入口
  • 分发器(event mediator):将不同的事件分发到不同的业务逻辑单元
  • 事件通道(event channel):分发器与处理器之间的联系渠道
  • 事件处理器(event processor):实现业务逻辑,处理完成后会发出事件,触发下一步操作

基于事件架构

对于简单的项目,事件队列、分发器和事件通道,可以合为一体,整个软件就分成事件代理和事件处理器两部分。

基于事件架构

优点:

  • 分布式的异步架构,事件处理器之间高度解耦,软件的扩展性好
  • 适用性广,各种类型的项目都可以用
  • 性能较好,因为事件的异步本质,软件不易产生堵塞
  • 事件处理器可以独立地加载和卸载,容易部署

缺点:

  • 涉及异步编程(要考虑远程通信、失去响应等情况),开发相对复杂
  • 难以支持原子性操作,因为事件通过会涉及多个处理器,很难回滚
  • 分布式和异步特性导致这个架构较难测试

微内核(插件)(Microkernel / plug-in)

微核架构又称为”插件架构”,指的是软件的内核相对较小,主要功能和业务逻辑都通过插件实现。内核(core)通常只包含系统运行的最小功能。插件则是互相独立的,插件之间的通信,应该减少到最低,避免出现互相依赖的问题。

典型例子,Eclipse

微内核

优点:

  • 良好的功能延伸性(extensibility),需要什么功能,开发一个插件即可
  • 功能之间是隔离的,插件可以独立的加载和卸载,使得它比较容易部署,
  • 可定制性高,适应不同的开发需要
  • 可以渐进式地开发,逐步增加功能

缺点:

  • 扩展性(scalability)差,内核通常是一个独立单元,不容易做成分布式
  • 开发难度相对较高,因为涉及到插件与内核的通信,以及内部的插件登记机制

变化:

  • 插件往往以组件的形式存在,并遵行一定的接口契约
  • 其于舞台风格有一定相似之处

舞台

舞台风格,指的是:在固定的舞台上,能够支持多种对象的展现、动作、变换等,一般适用于UI系统,如各种动画编辑软件。

这个风格,首先就采用面向对象的设计风格,并基于契约定义各对象的基础行为,对象可以通过插件化的方式支持扩展,从而将对象与舞台进行解耦。

舞台风格(图不准确)

云架构

云结构(cloud architecture)主要解决扩展性和并发的问题,是最容易扩展的架构。
它的高扩展性,主要原因是没使用中央数据库,而是把数据都复制到内存中,变成可复制的内存数据单元。然后,业务处理能力封装成一个个处理单元(prcessing unit)。访问量增加,就新建处理单元;访问量减少,就关闭处理单元。由于没有中央数据库,所以扩展性的最大瓶颈消失了。由于每个处理单元的数据都在内存里,最好要进行数据持久化。
这个模式主要分成两部分:处理单元(processing unit)和虚拟中间件(virtualized middleware)。

  • 处理单元:实现业务逻辑
  • 虚拟中间件:负责通信、保持sessions、数据复制、分布式处理、处理单元的部署。

enter description here

虚拟中间件又包含四个组件。

  • 消息中间件(Messaging Grid):管理用户请求和session,当一个请求进来以后,决定分配给哪一个处理单元。
  • 数据中间件(Data Grid):将数据复制到每一个处理单元,即数据同步。保证某个处理单元都得到同样的数据。
  • 处理中间件(Processing Grid):可选,如果一个请求涉及不同类型的处理单元,该中间件负责协调处理单元
  • 部署中间件(Deployment Manager):负责处理单元的启动和关闭,监控负载和响应时间,当负载增加,就新启动处理单元,负载减少,就关闭处理单元。
  • 优点:
  • 高负载,高扩展性
  • 动态部署

缺点:

  • 实现复杂,成本较高
  • 主要适合网站类应用,不合适大量数据吞吐的大型数据库应用
  • 较难测试

综合对比

enter description here

enter description here

参考资料

http://www.ruanyifeng.com/blog/2016/09/software-architecture.html
http://www.jianshu.com/p/2d3cd75ef209
http://www.cnblogs.com/wintersun/p/4869344.html
http://www.cnblogs.com/xianyulaodi/p/5986748.html
https://forums.ni.com/t5/Example-Program-Drafts/Message-Bus-Architecture-An-Intro/ta-p/3512280