【软考-系统架构设计师】知识要点-15

44 软件架构风格

软件架构设计的一个核心问题是能否使用重复的软件架构模式,即能否达到架构级别的软件重用;也就是说,能否在不同的软件系统中,使用同一架构;基于这个目的,学者们开始研究和实践软件架构的风格和类型问题。

软件架构风格是描述某一特定应用领域中系统组织方式的惯用模式(Idiomatic Paradigm)。架构风格定义了一个系统家族,即一个架构定义一个词汇表和一组约束,词汇表中包含一些构件和连接件类型,而这组约束指出系统是如何将这些构件和连接件组合起来的;架构风格反映了领域中众多系统所共有的结构和语义特性,并指导如何将各个模块和子系统有效地组织成一个完整的系统。

架构风格不变的部分使不同的系统可以共享同一个实现代码,只要系统是使用常用的、规范的方法来组织,就可使别的设计者很容易地理解系统的架构;例如,如果某人把系统描述为客户/服务器模式,则不必给出设计细节,我们立刻就会明白系统是如何组织和工作的。

软件架构风格为大粒度的软件重用提供了可能;然而,对于应用架构风格来说,由于视点的不同,系统设计师有很大的选择余地,要为系统选择或设计某一个架构风格,必须根据特定项目的具体特点,进行分析比较后再确定,架构风格的使用几乎完全是特定的。

44.1 软件架构风格分类

讨论架构风格时要回答的问题是:

  • 设计词汇表是什么?
  • 构件和连接件的类型是什么?
  • 可容许的结构模式是什么?
  • 基本的计算模型是什么?
  • 风格的基本不变性是什么?
  • 其使用的常见例子是什么?
  • 使用此风格的优缺点是什么?
  • 其常见的特例是什么?

这些问题的回答包括了架构风格最关键的四要素,即提供一个词汇表、定义一套配置规则、定义一套语义解释原则和定义对基于这种风格的系统所进行的分析

根据此框架得出了通用架构风格的分类:

  • 数据流风格:批处理序列;管道/过滤器;
  • 调用/返回风格:主程序/子程序;面向对象风格;层次结构;
  • 独立构件风格:进程通信;事件系统;
  • 虚拟机风格:解释器;基于规则的系统;
  • 仓库风格:数据库系统;超文本系统;黑板系统。

44.2 数据流风格

数据流风格的软件架构是一种最常见,结构最为简单的软件架构;这样的架构下,所有的数据按照流的形式在执行过程中前进,不存在结构的反复和重构,就像工厂中的汽车流水线一样,数据就像汽车零部件一样在流水线的各个节点上被加工,最终输出所需要的结果(一部完整的汽车)。在流动过程中,数据经过序列间的数据处理组件进行处理,然后将处理结果向后传送,最后进行输出

数据流风格架构主要包括两种具体的架构风格:批处理序列和管道-过滤器。

44.2.1 批处理序列

批处理风格的每一步处理都是独立的,并且每一步是顺序执行的;只有当前一步处理完,后一步处理才能开始;数据传送在步与步之间作为一个整体。

组件为一系列固定顺序的计算单元,组件间只通过数据传递交互;每个处理步骤是一个独立的程序,每一步必须在前一步结束后才能开始,数据必须是完整的,以整体的方式传递。

批处理的典型应用:

  • 经典数据处理;
  • 程序开发;
  • Windows下的BAT程序就是这种应用的典型实例。

44.2.2 管道和过滤器

在管道/过滤器风格的软件架构中,每个构件都有一组输入和输出,构件读输入的数据流,经过内部处理,然后产生输出数据流;这个过程通常通过对输入流的变换及增量计算来完成,在输入被完全消费之前,输出便产生了。因此,这里的构件被称为过滤器,这种风格的连接件就像是数据流传输的管道,将一个过滤器的输出传到另一过滤器的输入。

此风格特别重要的过滤器必须是独立的实体,它不能与其他的过滤器共享数据,而且一个过滤器不知道它上游和下游的标识;一个管道/过滤器网络输出的正确性并不依赖于过滤器进行增量计算过程的顺序。

管道/过滤器风格的软件架构具有许多很好的特点:

  • 使得软件具有良好的隐蔽性和高内聚、低耦合的特点;
  • 允许设计者将整个系统的输入/输出行为看成是多个过滤器的行为的简单合成;
  • 支持软件重用:只要提供适合在两个过滤器之间传送的数据,任何两个过滤器都可被连接起来;
  • 系统维护和增强系统性能简单:新的过滤器可以添加到现有系统中来;旧的可以被改进的过滤器替换掉;
  • 允许对一些如吞吐量、死锁等属性的分析;
  • 支持并行执行:每个过滤器是作为一个单独的任务完成,因此可与其他任务并行执行。

但是,这样的系统也存在着若干不利因素:

  • 通常导致进程成为批处理的结构:这是因为虽然过滤器可增量式地处理数据,但它们是独立的,所以设计者必须将每个过滤器看成一个完整的从输入到输出的转换;
  • 不适合处理交互的应用:当需要增量地显示改变时,这个问题尤为严重;
  • 因为在数据传输上没有通用的标准,每个过滤器都增加了解析和合成数据的工作,这样就导致了系统性能下降,并增加了编写过滤器的复杂性。

44.2.3 批处理序列风格与管道过滤器风格对比

把批处理序列风格与管道过滤器风格比较:

  • 共同点:把任务分成一系列固定顺序的计算单元(组件),组件间只通过数据传递交互;
  • 区别:批处理是全部的、高潜伏性的,输入时可随机存取,无合作性、无交互性;而管道过滤器是递增的,数据结果延迟小,输入时处理局部化,有反馈、可交互;批处理强调数据传送在步与步之间作为一个整体,而管理过滤器无此要求。

44.3 调用/返回风格

调用返回风格顾名思义,就是指在系统中采用了调用与返回机制。利用调用-返回实际上是一种分而治之的策略,其主要思想是将一个复杂的大系统分解为一些子系统,以便降低复杂度,并且增加可修改性。程序从其执行起点开始执行该构件的代码,程序执行结束,将控制返回给程序调用构件。

调用/返回风格架构主要包括三种具体的架构风格:主程序/子程序;面向对象风格;层次结构。

44.3.1 主程序/子程序

主程序/子程序风格是结构化开发时期的经典架构风格,这种风格一般采用单线程控制,把问题划分为若干处理步骤,构件即为主程序和子程序,子程序通常可合成为模块,过程调用作为交互机制,即充当连接件;调用关系具有层次性,其语义逻辑表现为子程序的正确性,取决于它调用的子程序的正确性。

44.3.2 面向对象风格

这种风格建立在数据抽象和面向对象的基础上,数据的表示方法和它们的相应操作封装在一个抽象数据类型或对象中这种风格的构件是对象,或者说是抽象数据类型的实例;对象是一种被称作管理者的构件,因为它负责保持资源的完整性;对象是通过函数和过程的调用来交互的。

这种风格的两个重要特征为:

  • 对象负责维护其表示的完整性;
  • 对象的表示对其他对象而言是隐蔽的:因为一个对象对它的客户隐藏了自己的表示,所以这些对象可以不影响它的客户就能改变其实现方法。

面向对象的系统有许多优点,并早已为人所知:

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

但是,面向对象的系统也存在着某些问题:

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

44.4 层次结构风格

层次系统组织成一个层次结构,每一层为上层服务,并作为下层客户。

在一些层次系统中,除了一些精心挑选的输出函数外,内部的层只对相邻的层可见;连接件通过决定层间如何交互的协议来定义,拓扑约束包括对相邻层间交互的约束

这种风格支持基于可增加抽象层的设计,这样,允许将一个复杂问题分解成一个增量步骤序列的实现;由于每一层最多只影响两层,同时只要给相邻层提供相同的接口,允许每层用不同的方法实现,同样为软件重用提供了强大的支持。

层次系统最广泛的应用是分层通信协议,在这一应用领域中,每一层提供一个抽象的功能,作为上层通信的基础;较低的层次定义低层的交互,最低层通常只定义硬件物理连接。

层次系统有许多可取的属性:

  • 支持基于抽象程度递增的系统设计,使设计者可以把一个复杂系统按递增的步骤进行分解;
  • 支持功能增强,因为每一层至多和相邻的上下层交互,因此功能的改变最多影响相邻的上下层;
  • 支持重用:只要提供的服务接口定义不变,同一层的不同实现可以交换使用;这样,就可以定义一组标准的接口,而允许各种不同的实现方法。

但是,层次系统也有其不足之处:

  • 并不是每个系统都可以很容易地划分为分层的模式,甚至即使一个系统的逻辑结构是层次化的,出于对系统性能的考虑,系统设计师不得不把一些低级或高级的功能综合起来;
  • 很难找到一个合适的、正确的层次抽象方法。

44.5 独立构件风格

独立构件风格主要强调系统中的每个构件都是相对独立的个体,它们之间不直接通信,以降低耦合度,提升灵活性

独立构件风格主要包括:进程通讯和事件系统子风格。

44.5.1 进程通信架构风格

进程通信架构风格:构件是独立的过程,连接件是消息传递。这种风格的特点是构件通常是命名过程,消息传递的方式可以是点到点、异步和同步方式及远过程调用

44.5.2 事件系统风格

事件系统风格基于事件的隐式调用,风格的思想是构件不直接调用一个过程,而是触发或广播一个或多个事件系统中的其他构件中的过程在一个或多个事件中注册,当一个事件被触发,系统自动调用在这个事件中注册的所有过程,这样,一个事件的触发就导致了另一模块中的过程的调用。

从架构上说,这种风格的构件是一些模块,这些模块既可以是一些过程,又可以是一些事件的集合;过程可以用通用的方式调用,也可以在系统事件中注册一些过程,当发生这些事件时,过程被调用。

基于事件的隐式调用风格的主要特点是事件的触发者并不知道哪些构件会被这些事件影响;这样不能假定构件的处理顺序,甚至不知道哪些过程会被调用,因此,许多隐式调用的系统也包含显式调用作为构件交互的补充形式。

隐隐式调用系统的主要优点有:

  • 为软件重用提供了强大的支持:当需要将一个构件加入现存系统中时,只需将它注册到系统的事件中;
  • 为改进系统带来了方便:当用一个构件代替另一个构件时,不会影响到其他构件的接口。

隐式调用系统的主要缺点有:

  • 构件放弃了对系统计算的控制:一个构件触发一个事件时,不能确定其他构件是否会响应它;而且即使它知道事件注册了哪些构件的过程,它也不能保证这些过程被调用的顺序;
  • 数据交换的问题:有时数据可被一个事件传递,但另一些情况下,基于事件的系统必须依靠一个共享的仓库进行交互,在这些情况下,全局性能和资源管理便成了问题;
  • 既然过程的语义必须依赖于被触发事件的上下文约束,关于正确性的推理存在问题。

44.6 虚拟机风格

虚拟机风格的基本思想是人为构建一个运行环境,在这个环境之上,可以解析与运行自定义的一些语言,这样来增加架构的灵活性。

虚拟机风格主要包括解释器和规则为中心两种架构风格。

44.6.1 解释器

一个解释器通常包括完成解释工作的解释引擎,一个包含将被解释的代码的存储区,一个记录解释引擎当前工作状态的数据结构,以及一个记录源代码被解释执行进度的数据结构。

具有解释器风格的软件中含有一个虚拟机,可以仿真硬件的执行过程和一些关键应用。

解释器通常被用来建立一种虚拟机以弥合程序语义与硬件语义之间的差异,其缺点是执行效率较低。

44.6.2 规则为中心

基于规则的系统包括规则集、规则解释器、规则/数据选择器及工作内存。

44.7 仓库(Repository)风格

在仓库风格中,有两种不同的构件:中央数据结构说明当前状态,独立构件在中央数据存储上执行,仓库与外构件间的相互作用在系统中会有大的变化。

仓库风格包括的子风格有:

  • 数据库系统:数据库架构是库风格最常见的形式;构件主要有两大类,一个是中央共享数据源,保存当前系统的数据状态;另一个是多个独立处理元素,处理元素对数据元素进行操作。
  • 超文本系统:超文本系统的典型代表,就是早期的静态网页。
  • 黑板风格

黑板系统是在抽象与总结语言理解系统HEARSAY-11的基础上产生的,适合于解决复杂的非结构化的问题,能在求解过程中综合运用多种不同知识源,使得问题的表达、组织和求解变得比较容易。

黑板系统是一种问题求解模型,是组织推理步骤、控制状态数据和问题求解之领域知识的概念框架;它将问题的解空间组织成一个或多个应用相关的分级结构;

分级结构的每一层信息由一个唯一的词汇来描述,它代表了问题的部分解。领域相关的知识被分成独立的知识模块,它将某一层次中的信息转换成同层或相邻层的信息;各种应用通过不同知识表达方法、推理框架和控制机制的组合来实现。

影响黑板系统设计的最大因素是应用问题本身的特性,但是支撑应用程序的黑板体系结构有许多相似的特征和构件;对于特定应用问题,黑板系统可通过选取各种黑板、知识源和控制模块的构件来设计;也可以利用预先定制的黑板体系结构的编程环境。

黑板系统的传统应用是信号处理领域,如语音和模式识别;另一应用是松耦合代理数据共享存取。

黑板系统主要由三部分组成:

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

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

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


45 层次系统架构风格

45.1 二层及三层C/S架构风格

C/S架构是基于资源不对等,且为实现共享而提出来的,是20世纪90年代成熟起来的技术,C/S结构将应用一分为二,服务器(后台)负责数据管理,客户机(前台)完成与用户的交互任务。

C/S软件架构具有强大的数据操作和事务处理能力,模型思想简单,易于人们理解和接受。但随着企业规模的日益扩大,软件的复杂程度不断提高,传统的二层C/S结构存在以下几个局限:

  • 二层C/S结构为单一服务器且以局域网为中心,所以难以扩展至大型企业广域网或Internet;
  • 软、硬件的组合及集成能力有限;
  • 服务器的负荷太重,难以管理大量的客户机,系统的性能容易变坏;
  • 数据安全性不好:因为客户端程序可以直接访问数据库服务器,那么,在客户端计算机上的其他程序也可想办法访问数据库服务器,从而使数据库的安全性受到威胁。

正是因为二层C/S有这么多缺点,因此,三层C/S结构应运而生;三层C/S结构是将应用功能分成表示层、功能层和数据层三个部分

  • 表示层是应用的用户接口部分,它担负着用户与应用间的对话功能;它用于检查用户从键盘等输入的数据,并显示应用输出的数据,在变更用户接口时,只需改写显示控制和数据检查程序,而不影响其他两层;检查的内容也只限于数据的形式和取值的范围,不包括有关业务本身的处理逻辑;
  • 功能层相当于应用的本体,它是将具体的业务处理逻辑编入程序中;而处理所需的数据则要从表示层或数据层取得;表示层和功能层之间的数据交往要尽可能简洁;
  • 数据层就是数据库管理系统,负责管理对数据库数据的读写;数据库管理系统必须能迅速执行大量数据的更新和检索,因此,一般从功能层传送到数据层的要求大都使用SQL语言。

三层C/S的解决方案是:对这三层进行明确分割,并在逻辑上使其独立,原来的数据层作为数据库管理系统已经独立出来,所以,关键是要将表示层和功能层分离成各自独立的程序,并且还要使这两层间的接口简洁明了。

一般情况是只将表示层配置在客户机中,如果将功能层也放在客户机中,与二层C/S结构相比,其程序的可维护性要好得多,但是其他问题并未得到解决。客户机的负荷太重,其业务处理所需的数据要从服务器传给客户机,所以系统的性能容易变差;如果将功能层和数据层分别放在不同的服务器中,则服务器和服务器之间也要进行数据传送;但是,由于在这种形态中三层是分别放在各自不同的硬件系统上的,所以灵活性很高,能够适应客户机数目的增加和处理负荷的变动,例如,在追加新业务处理时,可以相应增加装载功能层的服务器,因此,系统规模越大这种形态的优点就越显着

45.2 B/S架构风格

浏览器/服务器(Browser/Server,简称B/S)风格就是上述三层应用结构的一种实现方式,其具体结构为:浏览器/Web服务器/数据库服务器;采用B/S结构的计算机应用系统的基本框架如图所示。

在B/S结构中,除了数据库服务器外,应用程序以网页形式存放于Web服务器上,用户运行某个应用程序时只需在客户端上的浏览器中键入相应的网址,调用Web服务器上的应用程序并对数据库进行操作完成相应的数据处理工作,最后将结果通过浏览器显示给用户。

可以说,在B/S模式的计算机应用系统中,应用(程序)在一定程度上具有集中特征;基于B/S架构的软件,系统安装、修改和维护全在服务器端解决,用户在使用系统时,仅需要一个浏览器就可运行全部的模块,真正达到了“零客户端”的功能,很容易在运行时自动升级。另外,B/S结构的计算机应用系统与Internet的结合也使新近提出的一些新的企业计算机应用(如电子商务,客户关系管理)的实现成为可能。

与C/S架构相比,B/S架构也有许多不足之处,例如:

  • B/S架构缺乏对动态页面的支持能力,没有集成有效的数据库处理功能;
  • 采用B/S架构的应用系统,在数据查询等响应速度上,要远远地低于C/S架构;
  • B/S架构的数据提交一般以页面为单位,数据的动态交互性不强,不利于在线事务处理(Online Transaction Processing,简称OLTP)应用。

45.3 MVC架构风格

MVC全名是Model View Controller,是模型(Model)-视图(View)-控制器(Controller)的缩写,它是分层架构风格的一种。

MVC提出的基本思想是进行关注点分离,一个典型的人机交互应用具有三个主要的关注点:数据在可视化界面上的呈现、UI处理逻辑和业务逻辑;如果按传统的自治视图模式(即将与UI相关的逻辑都定义在针对视图的相关元素的事件上),将三者混合在一起,势必会带来一系列问题:

  • 业务逻辑是与UI无关的,应该最大限度地被重用;由于业务逻辑定义在自治视图中,相当于完全与视图本身绑定在一定,如果我们能够将UI的行为抽象出来,基于抽象化UI的处理逻辑也是可以被共享的;
  • 业务逻辑具有最强的稳定性,UI处理逻辑次之,而可视化界面上的呈现最差(比如我们经常会为了更好地呈现效果来调整HTML),如果将具有不同稳定性的元素融为一体,那么具有最差稳定性的元素决定了整体的稳定性
  • 任何涉及UI的组件都不易测试;UI是呈现给人看的,并且用于人机交互,用机器来模拟活生生的人来对组件实施自动化测试不是一件容易的事,自治视图严重损害了组件的可测试性。

正是为了解决以上的问题,所以我们需要采用关注点分离的方针来将可视化界面呈现、UI处理逻辑和业务逻辑三者分离出来,并且采用合理的交互方式将它们之间的依赖降到最低。

MVC中各个部分的分工与协作是这样的:

  • Model是对应用状态和业务功能的封装,我们可以将它理解为同时包含数据和行为的领域模型;Model接受Controller的请求并完成相应的业务处理,在状态改变的时候向View发出相应的通知;
  • View实现可视化界面的呈现并捕捉最终用户的交互操作(例如鼠标和键盘的操作);
  • View捕获到用户交互操作后会直接转发给Controller,后者完成相应的UI逻辑;如果需要涉及业务功能的调用,Controller会直接调用Model,在完成UI处理后,Controller会根据需要控制原View或者创建新的View对用户交互操作予以响应。

45.4 MVP架构风格

MVP的全称为Model-View-Presenter,Model提供数据,View负责显示,Controller/Presenter负责逻辑的处理。

MVP是从经典的模式MVC演变而来,它们的基本思想有相通的地方:Controller/Presenter负责逻辑的处理,Model提供数据,View负责显示。

MVP与MVC也有一些显着的区别,MVC模式中元素之间“混乱”的交互主要体现在允许View和Model直接进行“交流”,这在MVP模式中是不允许的;在MVP中View并不直接使用Model,它们之间的通信是通过Presenter(MVC中的Controller)来进行的,所有的交互都发生在Presenter内部,而在MVC 中View会直接从Model中读取数据而不是通过Controller。

MVP不仅仅避免了View和Model之间的耦合,还进一步降低了Presenter对View的依赖;Presenter依赖的是一个抽象化的View,即View实现的接口IView,这带来的最直接的好处,就是使定义在Presenter中的UI处理逻辑变得易于测试。由于Presenter对View的依赖行为定义在接口IView中,我们只需要一个实现了这个接口的View就能对Presenter进行测试。

  • 模型与视图完全分离,我们可以修改视图而不影响模型;
  • 可以更高效地使用模型,因为所有的交互都发生在Presenter内部;
  • 我们可以将一个Presenter用于多个视图,而不需要改变Presenter的逻辑,这个特性非常的有用,因为视图的变化总是比模型的变化频繁;
  • 如果我们把逻辑放在Presenter中,那么我们就可以脱离用户接口来测试这些逻辑(单元测试)。

MVP的缺点包括:由于对视图的渲染放在了Presenter中,所以视图和 Presenter的交互会过于频繁;还有一点需要明白,如果Presenter过多地渲染了视图,往往会使得它与特定的视图的联系过于紧密,一旦视图需要变更,那么Presenter也需要变更了;比如说,原本用来呈现HTML的Presenter现在也需要用于呈现PDF了,那么视图很有可能也需要变更。


46 面向服务的架构(Service-Oriented Architecture, SOA)

较为典型的定义有以下三个:

  • W3C的定义:SOA是一种应用程序架构,在这种架构中,所有功能都定义为独立的服务,这些服务带有定义明确的可调用接口,能够以定义好的顺序调用这些服务来形成业务流程。
  • http://Service-architecture.com的定义:服务是精确定义、封装完善、独立于其他服务所处环境和状态的函数;SOA本质上是服务的集合,服务之间彼此通信,这种通信可能是简单的数据传送,也可能是两个或更多的服务协调进行某些活动,服务之间需要某些方法进行连接。
  • Gartner的定义:SOA是一种C/S架构的软件设计方法,应用由服务和服务使用者组成,SOA与大多数通用的C/S架构模型不同之处,在于它着重强调构件的松散耦合,并使用独立的标准接口。

46.1 SOA概述

SOA是一种在计算环境中设计、开发、部署和管理离散逻辑单元(服务)模型的方法;虽然基于SOA的系统并不排除使用OOD来构建单个服务,但是其整体设计却是面向服务的;由于SOA考虑到了系统内的对象,所以虽然SOA是基于对象的,但是作为一个整体,它却不是面向对象的。

SOA系统原型的一个典型例子是CORBA,它已经出现很长时间,其定义的概念与SOA相似。SOA建立在XML等新技术的基础上,通过使用基于XML的语言来描述接口,服务已经转到更动态且更灵活的接口系统中。

在SOA模型中,所有的功能都定义成了独立的服务,服务之间通过交互和协调完成业务的整体逻辑;所有的服务通过服务总线或流程管理器来连接,这种松散耦合的架构使得各服务在交互过程中无需考虑双方的内部实现细节,以及部署在什么平台上。

46.1.1 服务的基本结构

服务模型的表示层从逻辑层分离出来,中间增加了服务对外的接口层;通过服务接口的标准化描述,使得服务可以提供给在任何异构平台和任何用户接口使用;这允许并支持基于服务的系统成为松散耦合、面向构件和跨技术实现,服务请求者很可能根本不知道服务在哪里运行、是由哪种语言编写的,以及消息的传输路径,而是只需要提出服务请求,然后就会得到答案。

46.1.2 SOA设计原则

关于服务,一些常见的设计原则如下:

  • 明确定义的接口:服务请求者依赖于服务规约来调用服务,因此,服务定义必须长时间稳定,一旦公布,不能随意更改;服务的定义应尽可能明确,减少请求者的不适当使用;不要让请求者看到服务内部的私有数据。
  • 自包含和模块化:服务封装了那些在业务上稳定、重复出现的活动和构件,实现服务的功能实体是完全独立自主的,独立进行部署、版本控制、自我管理和恢复。
  • 粗粒度:服务数量不应该太多,依靠消息交互而不是远程过程调用,通常消息量比较大,但是服务之间的交互频度较低。
  • 松耦合:服务请求者可见的是服务的接口,其位置、实现技术、当前状态和私有数据等,对服务请求者而言是不可见的。
  • 互操作性、兼容和策略声明

46.1.3 服务构件与传统构件

服务构件架构(Service Component Architecture,SCA)是基于SOA的思想描述服务之间组合和协作的规范,它描述用于使用SOA构建应用程序和系统的模型,它可简化使用SOA进行的应用程序开发和实现工作。

SCA服务构件与传统构件的主要区别在于,服务构件往往是粗粒度的,而传统构件以细粒度居多;服务构件的接口是标准的,主要是服务描述语言接口,而传统构件常以具体API形式出现;服务构件的实现与语言是无关的,而传统构件常绑定某种特定的语言;服务构件可以通过构件容器提供QoS(Quality of Service,服务质量)的服务,而传统构件完全由程序代码直接控制。

46.2 SOA的关键技术

46.2.1 UDDI

UDDI(Universal Description Discovery and Integration,统一描述、发现和集成)提供了一种服务发布、查找和定位的方法,是服务的信息注册规范,以便被需要该服务的用户发现和使用它。

UDDI规范描述了服务的概念,同时也定义了一种编程接口,通过UDDI提供的标准接口,企业可以发布自己的服务供其他企业查询和调用,也可以查询特定服务的描述信息,并动态绑定到该服务上。

在UDDI技术规范中,主要包含以下三个部分的内容:

  • 数据模型:是一个用于描述业务组织和服务的XML Schema;
  • API:是一组用于查找或发布UDDI据的方法,UDDI API基于SOAP;
  • 注册服务:是SOA中的一种基础设施,对应着服务注册中心的角色。

46.2.2 WSDL

WSDL(Web Service Description Language,Web服务描述语言)是对服务进行描述的语言,它有一套基于XML的语法定义。

WSDL描述的重点是服务,它包含服务实现定义和服务接口定义。

采用抽象接口定义对于提高系统的扩展性很有帮助。

服务接口定义就是一种抽象的、可重用的定义,行业标准组织可以使用这种抽象的定义来规定一些标准的服务类型,服务实现者可以根据这些标准定义来实现具体的服务;服务实现定义描述了给定服务提供者如何实现特定的服务接口。

服务实现定义中包含服务和端口描述。一个服务往往会包含多个服务访问入口,而每个访问入口都会使用一个端口元素来描述,端口描述的是一个服务访问入口的部署细节,例如,通过哪个地址来访问,应当使用怎样的消息调用模式来访问等。

46.2.3 SOAP

SOAP(Simple Object Access Protocol,简单对象访问协议)定义了服务请求者和服务提供者之间的消息传输规范。

SOAP用XML来格式化消息,用HTTP来承载消息;通过SOAP,应用程序可以在网络中进行数据交换和远程过程调用(Remote Procedure Call, RPC)。

SOAP主要包括以下四个部分:

  • 封装:定义了一个整体框架,用来表示消息中包含什么内容,谁来处理这些内容,以及这些内容是可选的还是必需的;
  • 编码规则:定义了一种序列化的机制,用于交换系统所定义的数据类型的实例;
  • RPC表示:定义了一个用来表示远程过程调用和应答的协议;
  • 绑定:定义了一个使用底层传输协议来完成在节点之间交换SOAP 封装的约定。

SOAP消息基本上是从发送端到接收端的单向传输,但它们常常结合起来执行类似于请求/应答的模式;所有的SOAP消息都使用XML进行编码;SOAP 消息包括以下三个部分:

  • 封装(信封):元素名是Envelope,在表示消息的XML文档中,封装是顶层元素,在SOAP消息中必须出现;
  • SOAP头:元素名是Header,提供了向SOAP消息中添加关于这条SOAP消息的某些要素的机制;
  • SOAP体:元素名是Body,是包含消息的最终接收者想要的信息的容器;
  • REST(Representational State Transfer,表述性状态转移):是一种只使用HTTP和XML进行基于Web通信的技术,可以降低开发的复杂性,提高系统的可伸缩性;

46.3 SOA的实现方法

从本质上来看,SOA是用本地计算模型来实现一个分布式的计算应用,也有人称这种方法为“本地化设计,分布式工作”模型,CORBA、DCOM和EJB等都属于这种解决方式,也就是说,SOA最终可以基于这些标准来实现。

从逻辑上和高层抽象来看,目前,实现SOA的方法也比较多,其中主流方式有Web Service、企业服务总线和服务注册表。

46.3.1 Web Service

在Web Service(Web服务)的解决方案中,一共有三种工作角色,其中服务提供者和服务请求者是必需的,服务注册中心是一个可选的角色;它们之间的交互和操作构成了SOA的一种实现架构,如图所示。

  • 服务提供者:是服务的所有者,该角色负责定义并实现服务,使用 WSDL对服务进行详细、准确、规范地描述,并将该描述发布到服务注册中心,供服务请求者查找并绑定使用;
  • 服务请求者:是服务的使用者,虽然服务面向的是程序,但程序的最终使用者仍然是用户;从架构的角度看,服务请求者是查找、绑定并调用服务,或与服务进行交互的应用程序;服务请求者角色可以由浏览器来担当,由人或程序(例如,另外一个服务)来控制;
  • 服务注册中心:是连接服务提供者和服务请求者的纽带,服务提供者在此发布他们的服务描述,而服务请求者在服务注册中心查找他们需要的服务;不过,在某些情况下,服务注册中心是整个模型中的可选角色,例如,如果使用静态绑定的服务,服务提供者则可以把描述直接发送给服务请求者。

Web Service模型中的操作包括发布、查找和绑定,这些操作可以单次或反复出现:

  • 发布:为了使用户能够访问服务,服务提供者需要发布服务描述,以便服务请求者可以查找它;
  • 查找:在查找操作中,服务请求者直接检索服务描述或在服务注册中心查询所要求的服务类型;对服务请求者而言,可能会在生命周期的两个不同阶段中涉及查找操作,首先是在设计阶段,为了程序开发而查找服务的接口描述;其次是在运行阶段,为了调用而查找服务的位置描述;
  • 绑定:在绑定操作中,服务请求者使用服务描述中的绑定细节来定位、联系并调用服务,从而在运行时与服务进行交互;绑定可以分为动态绑定和静态绑定:在动态绑定中,服务请求者通过服务注册中心查找服务描述,并动态地与服务交互;在静态绑定中,服务请求者已经与服务提供者达成默契,通过本地文件或其他方式直接与服务进行绑定。

在采用Web Service作为SOA的实现技术时,应用系统大致可以分为六个层次,分别是底层传输层、服务通信协议层、服务描述层、服务层、业务流程层和服务注册层:

  • 底层传输层:底层传输层主要负责消息的传输机制,HTTP、JMS(Java Messaging Service,Java消息服务)和SMTP都可以作为服务的消息传输协议,其中HTTP使用最广;
  • 服务通信协议层:主要功能是描述并定义服务之间进行消息传递所需的技术标准,常用的标准是SOAP和REST协议;
  • 服务描述层:主要以一种统一的方式描述服务的接口与消息交换方式,相关的标准是WSDL;
  • 服务层:主要功能是将遗留系统进行包装,并通过发布的WSDL接口描述被定位和调用;
  • 业务流程层:主要功能是支持服务发现,服务调用和点到点的服务调用,并将业务流程从服务的底层调用抽象出来;
  • 服务注册层:主要功能是使服务提供者能够通过WSDL发布服务定义,并支持服务请求者查找所需的服务信息;相关的标准是UDDI。

46.3.2 服务注册表(Service Registry)

它提供一个策略执行点(Policy Enforcement Point,PEP),在这个点上,服务可以在SOA中注册,从而可以被发现和使用。

服务注册表可以包括有关服务和相关构件的配置、依从性和约束文件。从理论上来说,任何帮助服务注册、发现和查找服务合约、元数据和策略的信息库、数据库、目录或其他节点都可以被认为是一个注册表。

大多数商用服务注册产品支持服务注册、服务位置和服务绑定功能:

  • 服务注册:指服务提供者向服务注册表发布服务的功能(服务合约),包括服务身份、位置、方法、绑定、配置、方案和策略等描述性属性;使用服务注册表实现SOA时,要限制哪些新服务可以向注册表发布、由谁发布以及谁批准和根据什么条件批准等,以便使服务能够有序的注册;
  • 服务位置:指服务使用者,帮助它们查询已注册的服务,寻找符合自身要求的服务;这种查找主要是通过检索服务合约来实现的,在使用服务注册表实现SOA时,需要规定哪些用户可以访问服务注册表,以及哪些服务属性可以通过服务注册表进行暴露等,以便服务能得到有效的、经过授权的使用;
  • 服务绑定:服务使用者利用查找到的服务合约来开发代码,开发的代码将与注册的服务进行绑定,调用注册的服务,以及与它们实现互动;可以利用集成的开发环境自动将新开发的服务与不同的新协议、方案和程序间通信所需的其他接口绑定在一起。

46.3.3 企业服务总线(ESB)

ESB的概念是从SOA发展而来的,它是一种为进行连接服务提供的标准化的通信基础结构,基于开放的标准,为应用提供了一个可靠的、可度量的和高度安全的环境,并可帮助企业对业务流程进行设计和模拟,对每个业务流程实施控制和跟踪、分析并改进流程和性能。

ESB提供了一种基础设施,消除了服务请求者与服务提供者之间的直接连接,使得服务请求者与服务提供者之间进一步解耦

ESB是由中间件技术实现并支持SOA的一组基础架构,是传统中间件技术与XML、Web Service等技术结合的产物,是在整个企业集成架构下的面向服务的企业应用集成机制。

具体来说,ESB具有以下功能:

  • 支持异构环境中的服务、消息和基于事件的交互,并且具有适当的服务级别和可管理性;
  • 通过使用ESB,可以在几乎不更改代码的情况下,以一种无缝的非侵入方式使现有系统具有全新的服务接口,并能够在部署环境中支持任何标准
  • 充当缓冲器的ESB(负责在诸多服务之间转换业务逻辑和数据格式)与服务逻辑相分离,从而使不同的系统可以同时使用同一个服务,不用在系统或数据发生变化时,改动服务代码;
  • 在更高的层次,ESB还提供诸如服务代理和协议转换等功能,允许在多种形式下通过像HTTP、SOAP和JMS总线的多种传输方式,主要是以网络服务的形式,为发表、注册、发现和使用企业服务或界面提供基础设施;
  • 提供可配置的消息转换翻译机制和基于消息内容的消息路由服务,传输消息到不同的目的地;
  • 提供安全和拥有者机制,以保证消息和服务使用的认证、授权和完整性。

在企业应用集成方面,与现存的、专有的集成解决方案相比,ESB具有以下优势:

  • 扩展的、基于标准的连接:ESB形成一个基于标准的信息骨架,使得在系统内部和整个价值链中可以容易地进行异步或同步数据交换;ESB通过使用XML、SOAP和其他标准,提供了更强大的系统连接性;
  • 灵活的、服务导向的应用组合:基于SOA,ESB使复杂的分布式系统(包括跨多个应用、系统和防火墙的集成方案)能够由以前开发测试过的服务组合而成,使系统具有高度可扩展性;
  • 提高复用率,降低成本:按照SOA方法构建应用,提高了复用率,简化了维护工作,进而减少了系统总体成本;
  • 减少市场反应时间,提高生产率:ESB通过构件和服务复用,按照SOA的思想简化应用组合,基于标准的通信、转换和连接来实现这些优点。

46.4 微服务

通俗一点来说,微服务类似于古代著名的发明,活字印刷术,每个服务都是一个组件,通过编排组合的方式来使用,从而真正做到了独立、解耦、组件化、易维护、可复用、可替换、高可用、最终达到提高交付质量、缩短交付周期的效果。

从专业的角度来看,微服务架构是一种架构模式,它提倡将单一应用程序划分成一组小的服务,服务之间互相协调、互相配合,为用户提供最终价值。

每个服务运行在其独立的进程中,服务与服务间采用轻量级的通信机制互相沟通(通常是基于HTTP协议的RESTful API)每个服务都围绕着具体业务进行构建,并且能够被独立的部署到生产环境、类生产环境等。

另外,应当尽量避免统一的、集中式的服务管理机制,对具体的一个服务而言,应根据业务上下文,选择合适的语言、工具对其进行构建。

所以总结起来,微服务的核心特点为:小,且专注于做⼀件事情、轻量级的通信机制、松耦合、独立部署。

46.4.1 微服务的优势

  • 技术异构性:在微服务架构中,每个服务都是一个相对独立的个体,每个服务都可以选择适合于自身的技术来实现;
  • 弹性:弹性主要讲的是系统中一部分出现故障会引起多大问题;微服务架构中,每个服务可以内置可用性的解决方案与功能降级方案,所以比单块系统强;
  • 扩展:在微服务架构中,可以针对单个服务进行扩展;
  • 简化部署:微服务架构中,每个服务的部署都是独立的,这样就可以更快地对特定部分的代码进行部署;
  • 与组织结构相匹配:可以将架构与组织结构相匹配,避免出现过大的代码库,从而获得理想的团队大小及生产力;服务的所有权也可以在团队之间迁移,从而避免异地团队的出现;
  • 可组合性:在微服务架构中,系统会开放很多接口供外部使用,当情况发生改变时,可以使用不同的方式构建应用,而整体化应用程序只能提供一个非常粗粒度的接口供外部使用;
  • 对可替代性的优化。

46.4.2 微服务面临的挑战

  • 分布式系统的复杂度:性能方面微服务是拆分成多个服务进行部署,服务间的通信都是通过网络,此时的性能会受影响;同时可靠性也会受影响,数据一致性也需要严格控制,其成本也比单块系统高;
  • 运维成本:在微服务架构下,随着服务数量的增多,每个服务都需要独立的配置、部署、监控、日志收集等,因此成本呈指数级增长;
  • 部署自动化:如何有效地构建自动化部署流水线,降低部署成本、提高部署频率,是微服务架构下需要面临的一个挑战;
  • DevOps与组织结构:微服务不仅表现出一种架构模型,同样也表现出一种组织模型,这种新型的组织模型意味着开发人员和运维的角色发生了变化,开发者将承担起服务整个生命周期的责任,包括部署和监控,而运维也越来越多地表现出一种顾问式的角色,尽早考虑服务如何部署;因此,如何在微服务的实施中,按需调整组织架构,构建全功能的团队,是一个不小的挑战;
  • 服务间依赖测试:由于微服务架构是把系统拆分为若干个可独立部署的服务,所以需要进行服务间的依赖测试;在服务数量较多的情况下,如何有效地保证服务之间能有效按照接口的约定正常工作,成为微服务实施过程中必须面临的巨大挑战;
  • 服务间依赖管理:在将系统功能拆分成相互协作的独立服务之后,随着微服务个数的增多,如何清晰有效地展示服务之间的依赖关系,成为了一个挑战。

46.4.3 微服务与SOA

微服务可以讲是SOA的一种,但仔细分析与推敲,我们又能发现他们的一些差异。这种差异表现在多个方面,具体如下表所示。

微服务SOA
能拆分就拆分能放一起就放一起,是一个整体
纵向业务拆分水平划分
单一组织负责按层级划分不同部门组织负责
细粒度粗粒度
一两句话可解释清楚SOA的目录就有几百字
独立的子公司类似大公司中的业务单元(Business Unit, BU),也就是独立完成一件事情的小组或部门
小组件较复杂组件
业务逻辑存在于每一个服务中业务逻辑横跨多个业务领域
使用轻量级通信方式,如HTTP企业服务总线(ESB),充当服务之间的通信角色

这些差异自然影响到其实现,在实现方面的主要差异如下表所示。

微服务实现SOA实现
团队级,自底向上开展企业级,自顶向下开展
一个系统被拆分成多个服务,细粒度服务由多个子系统组成,粗粒度
松散的服务架构企业服务总线,集中式服务架构
集成方式简单(HTTP、REST、JSON)集成方式复杂(ESB、WS、SOAP)
服务能独立部署单块架构系统,相互依赖,部署复杂

发布于 2022-10-20 21:57

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值