作为一种软件设计模式,SOA技术为服务的开发者提供了良好的架构。该架构体现了较为彻底的接口和实现解耦的设计思想,主要表现在接口和实现分离、调用时机分离两个方面。接口和实现分离:可使得软件研发、部署更加灵活。调用时机分离:具体功能的选定推迟到运行时,该功能是SOA技术实现动态组装、快速重组的基础,也是SOA技术被广泛推崇的原因之一。另外,随着物联网技术的广泛应用,未来势必产生海量数据,传统硬件架构服务器将难以满足数据管理和处理要求。将云计算技术运用到物联网是必然选择,采用云计算的物联网服务平台可在很大程度上提高运行效率。
SOA将应用程序的不同功能单元称为服务(Service),并通过在服务间定义良好的接口和约定(Contract)将它们联系起来。接口采用中立的方式定义,独立于具体实现服务的硬件平台、操作系统和编程语言,使构建在这样的系统中的服务能采用统一和标准的方式进行通信。SOA最重要的两个概念如下。
(1)SOA是一种软件系统架构。SOA既不是一种语言,也不是一种具体的实现技术,更不是一种产品。从为软件和应用的开发者推荐一种所有人都应该遵从的开发方法的这个角度上来说,可以将其视为一种设计模式。
(2)服务是整个SOA实现的核心。SOA的基本元素是服务,SOA指定一组实体(服务提供者、服务消费者、服务注册表、服务条款、服务代理和服务契约),这些实体详细说明了如何提供和消费服务。遵循 SOA 观点的系统必须有服务,这些服务是可互操作的、独立的、模块化的、位置明确的、松耦合的,并且可以通过网络查找其地址。
SOA的设计思想独立于任何具体实现技术(如Web服务)。它描述了SOA应用的所有功能,此类应用以服务的形式提供给用户。本质上来说,服务是一类按照特定模式、规范实现的应用。也就是说,SOA服务包含所有服务功能和应用的相关服务流程,以及SOA应用的基础功能与必要的系统功能。除提供将应用功能分解为服务外,SOA对服务的其他要求如下。
1.自我约束
当服务自身状态的维护独立于使用它的应用时,此服务是自我约束的。
2.平台无关
如果服务可以被客户端通过使用任意网络、硬件和软件平台(如操作系统、编程语言等)来访问,则服务是平台无关的。平台无关性同样意味着SOA服务是去除细节的简明实现。
3.动态发现、调用和组装
SOA要求服务能够被动态发现、调用和组装。服务动态发现的前提是该服务能够随时随地地在网络中被找到。服务查询的途径主要包括服务目录、类别或拓扑,以便客户端查询,从而决定哪个服务能够提供其所需的功能。SOA能够提供网络平台无关性的服务调用机制,客户端既不需要清楚服务调用的网络协议,也不需要清楚建立连接的中间件平台组件,SOA允许客户端调用服务或者能够被服务端按需通知。服务调用和网络平台的无关性,允许客户端可以从网络的任何地方、任何时间按需调用网络中的任何服务。如果服务可以被特定服务模型所使用和组合,这些服务模型可能跨多个服务提供者和组织,那么服务是可组装的。
每个基于SOA应用的服务都可能实现了一个全新功能,它们也可能使用部分原有应用,这些应用是被服务移植和封装起来的,或者是由新代码和部分原有代码组成的。服务客户端的用户不必知晓服务的实现,而是间接地通过接口访问该服务。例如,Web服务只是发布其服务接口而非公开其服务的具体实现,或者服务提供者的内部工作。因此,SOA允许企业创建、部署和集成不同的服务,以及通过组合封装在服务中的新老应用来设计新的服务模型功能和流程。此外,由于它的动态特性,SOA能够潜在地提供服务实时集成,该方法能够提供从未向客户端提供过的新服务。从这点上来说,SOA提供了一种实现和接口解耦合的设计模式,它主要体现在两个方面:接口和实现分离、调用时机分离。
接口和实现分离指服务一旦定义好接口后,服务的具体实现可以进行完全独立的开发、部署、更新,而不影响服务使用者的使用。调用时机分离指SOA的设计思想将服务的调用推迟到运行时决策,而不是在开发时决定,这一改变对于软件开发者来说,影响是巨大的。
SOA模型涉及服务请求者、服务提供者、服务注册中心三类实体。这三类实体通过服务请求实现交互。服务提供者将封装与实现的各种服务向服务注册中心进行注册,服务请求者则根据需要在服务注册中心查找服务,并根据服务注册中心的返回结果调用或使用服务。SOA模型如图2-1所示。服务发现、服务注册和服务请求过程通常基于SOAP(Simple Object Access Protocol,简单对象访问协议)实现。
SOAP是一个轻量化协议,允许类RPC(Remote Procedure Call,远程过程调用)的调用,而且这种调用是通过使用HTTP、HTTPS和SMTP(Simple Mail Transfer Protocol,简单邮件传输协议)等传输协议实现的。原则上,SOAP消息可以使用任何协议来表达,只要同时绑定一个解析方法即可。SOAP请求是由运行的服务(SOAP监听服务)来接收的,该服务专门接收SOAP消息、提取XML消息体、将XML消息转换为所请求服务的协议,并在企业内部将请求转交给实际功能或者服务进程。在处理请求之后,提供者需要给客户端发送响应,该响应同样是携带XML消息的SOAP消息。
图2-1 SOA模型
服务请求者和服务提供者之间的交互过程是复杂的,因为它们需要从不同的潜在服务提供者那里发现/发布、协商、预定和使用服务。降低这种复杂性的方法是将服务提供者和服务请求者功能性地结合到一个服务聚合器(Service Aggregator,也称聚合服务)。服务聚合器具有两种角色,如图2-2所示。首先,它可以像应用服务提供者一样运行,通过创建更高级别的组合服务来提供完整的服务解决方案。服务聚合器能够通过特定的组合语言(如BPEL或者BPML)实现此种组合。另外,它也可以是服务请求者。
图2-2 服务聚合器的作用
所请求的Web服务操作是通过一个或者多个Web服务组件实现的。Web服务组件可能被托管在Web服务容器中,该服务容器作为Web服务和底层基础设施服务间的接口。Web服务容器与J2EE容器很相似,能够提供位置、路由、服务调用和管理等功能。一个服务容器能够同时容纳多个服务实例,即便它们不属于同一个分布式进程。线程池允许将很多服务实例附加到单个容器中的多个监听进程中。
在SOA中有两个基本的抽象元素:服务和消息。服务是网络中一些物理资源或者逻辑资源的逻辑表现,并且/或者能够在网络中提供一些应用功能的执行逻辑。服务交互是通过消息交换来实现的。为了更好地描述面向服务的概念,从以下三个视图对其进行描述。
1.结构视图
结构视图是一个面向服务系统的高层模型,SOA系统结构视图如图2-3所示,其中,系统的各个管理域是通过服务来沟通信息的,而服务就是发送和接收消息的简单实体。服务可以看成支持“处理消息(Process Message)”的简单逻辑操作,该逻辑操作允许服务使用网络来进行消息交换及处理消息。该操作只存在于概念中,而且所有的服务都采用统一的语义;调用Process Message操作代表一个从发送者传送到接收者的消息和对这个消息进行处理的请求。
图2-3 SOA系统结构视图
在SOA系统中,需要转换思维来研究Process Message,它提供了理解消息交换协议的方法,以及构建更多复杂精细消息交换模式的基础构建模块。当实现一个面向服务系统时,Process Message操作可以被底层传输技术的适当机制替换,但消息传输的语义是一样的。
2.协议视图
协议视图规定了面向服务系统中消息的格式和服务消息交换的形式,它提供了系统结构中更详细的内容。服务协议视图如图2-4所示。
服务之间消息交换协议的设计应遵循以下原则。
(1)边界清晰。
(2)服务自治。
(3)服务之间只共享概要和条款。
(4)策略决定服务兼容性。
以上原则是为了表达面向服务应用的优点,包含但不局限于健壮性、易维护性、可扩展性和可靠性。忽略这些原则中的一条或者多条将会导致影响重要特性服务的开发。
图2-4 服务协议视图
3.实现视图
实现视图给出了面向服务系统中独立服务功能的实现方法,以及服务如何被设计用来支持协议消息的交互。一个典型服务的组织结构如图2-5所示。它由资源层、服务逻辑层和消息处理层组成。
(1)资源层:表示可能被服务中逻辑实体使用的资源。典型的资源包括网络的通信带宽、路由表等,以及通信节点的内存、操作系统资源、数据、设备、其他计算机系统及服务甚至人。
(2)服务逻辑层:包含服务的各种功能。一个服务逻辑的典型行为是接收从消息处理层发来的消息到达通知,消息处理层用于执行服务相关的工作,并且可能导致进一步的消息交互。功能粒度可以是任何级别,包括从一个单独的操作系统进程到跨组织的多服务进程。
(3)消息处理层:为服务逻辑提供了程序级的抽象,以实现与其他服务的消息交换。服务中一个消息的到达通常会产生由消息处理层确认是否符合服务约定的消息,接着该消息通过协议栈交付给服务逻辑层。消息处理层将其采用的协议公布给服务逻辑层,这样服务逻辑层就可以兼容服务所支持的消息协议中的行为、不完整性和复杂性。在本地范围或者高耦合度的系统中,协议有可能被隐藏在方法调用这样的高层抽象中,通常要求消息传输具有低延迟和低故障率的特点。然而,在某些情况下,如果服务实现被设计成容忍延迟、消息丢失等情况,那么就应增强系统的健壮性。
图2-5 一个典型服务的组织结构
尽管Web服务技术是当前在SOA中使用最为广泛的技术,但也存在很多其他常规的编程语言和集成平台。任何一种遵循WSDL(Web Services Description Language,Web服务描述语言)并使用XML消息进行交互的技术都可以加入SOA系统。这样的技术包括J2EE(Java2平台企业版)和消息队列(如IBM的WebSphere MQ)。
既然客户端和服务可能由不同的开发者使用不同技术和不同设计理念来实现,那么它们之间就可能存在技术上的不匹配(例如,它们使用不同的通信协议),以及异构性(例如,消息语法和语义)。处理这样的技术不匹配和异构性问题需要以下两种方法。
(1)使用与不同客户端可能调用的服务的相同技术和设计理念来实现客户端。
(2)在服务及其客户端之间加入一个提供可重用交互和集成逻辑的层。
第一种方法要求开发每个点到点连接的服务接口。这种点到点的网络连接是非常难以管理和维护的,因为它们在服务器和客户端之间引入紧耦合关系。这种耦合需要在传输协议、文档格式、交互风格等方面下很大功夫。此方法会导致服务端和客户端不可修改,因为对服务端的任何修改都有可能影响所有客户端。此外,点到点通信非常复杂且缺乏可扩展性。随着服务端和客户端数量的不断增加,它们可能很快就不可控制了。为了处理这些问题,企业使用集成(Enterprise Application Integration,EAI)中间件提供了一个对话中枢集成模式。这就使得第二种方法更为可行。
第二种方法是引入一个集成中间层,ESB(Enterprise Service Bus,企业服务总线)可解决服务和客户端之间的互操作性,ESB提供了SOA和Web服务集成的基础设施。ESB展示出两个突出特点:一是它促进了服务端和客户端的松耦合关系,二是ESB将集成逻辑分隔为独立的、易于管理的分片。
ESB是一个开放的、基于标准的消息总线,用来实现、部署和管理基于SOA的解决方案。为了发挥其作用,ESB提供分布式处理、基于标准的集成和企业扩展所需的企业级基础服务。ESB尤其用来设计在大粒度应用与其他组件之间通过标准适配器和接口提供互操作功能。为了达到此目标,ESB功能作为传输层和转换器,此转换器允许服务发布在完全不同的系统和计算环境中。
从概念上讲,ESB是从中间件产品(如面向消息的中间件)的存储转发机制中演进而来的,它是传统中间件技术与XML、Web服务等技术相互结合的产物,用于实现企业应用不同消息和信息的准确、高效、安全传送。物理上,ESB提供了SOA的基础功能实现,它建立了适当的消息控制机制,并满足SOA对安全、策略、可靠性和统计的需求。ESB负责消息流的控制并执行服务间消息的转换工作。ESB使应用和独立的待集成组件组装成一个服务流程的工作变得简单方便,这反过来又促进了企业中的服务过程自动化。
ESB连接各种应用和技术的简化结构如图2-6所示。该结构集成了J2EE应用(使用JMS)、.NET应用(使用C#客户端)和MQ应用(它连接已有应用、其他外部应用和数据源)。正如在图2-6上半部分和中间部分所描绘的那样,ESB提供了将许多不同应用组件放在面向服务的接口之下且使用Web服务技术集成这些应用组件的有效方法。在图2-6中,一个分布式查询引擎提供了抽象底层数据资源复杂度的数据服务。图2-6上半部分的入口集合了很多ESB汇聚点,它们代表了服务资源且是面向用户的。
图2-6 ESB连接各种应用和技术的简化结构
图2-6中所描述的ESB节点提供了物理网络目的节点和连接信息(如TCP/IP主机名和端口号)的抽象,超越了传统紧耦合分布式组件的管道级集成能力。这些节点允许服务使用逻辑连接名称,由ESB在运行时来完成到真实物理网络目的节点的映射工作。目的节点的独立性使连接到ESB服务的升级、迁移、替换工作能够在无须修改代码或者打断现有ESB应用运行的情况下完成。例如,一个现有的列表服务能够很容易地通过新服务的替换而得到升级,并且无须中断其他应用的运行。
另外,ESB通过创建完全相同的程序来处理一个网络失效的情况。节点依赖服务容器之间异步和高可靠的通信。它们能够通过配置使用不同级别的服务,例如,当网络部分失效时能够保证通信的服务。
为了能够成功构建和部署分布式的面向服务结构,需要解决如下四个主要问题。
(1)服务支持:每个独立的应用都作为服务提供给用户。
(2)服务组合:分布的服务是在明确的具体进程中配置和组合的。
(3)服务部署:随着基于SOA应用的部署,完整的服务和进程需要从测试转移到产品环境中。
(4)服务管理:对服务必须进行监视,而且它们的调用和选择需要调整以更好地实现特定应用的目标。
服务是通过使用很多应用开发工具(如微软的.Net、Borland的Jbuilder或BEA的Web Logic WorkShop)来组合的,这些工具能够使新的或者已有的分布应用以Web服务的方式提供给用户。像JCA(J2EE Connector Architecture)这样的技术也可能以集成打包形式提供给用户的应用(如ERP系统)来创建服务。
为了达到可操作的目标,像连接和路由信息这样的ESB集成服务是基于服务规则、数据转换和应用适配器的。这些功能本身是基于SOA的,它们高度分散于整个总线,并且通常是由单独部署的服务容器提供的,这是与高度集中且整体化的传统集成代理模式的根本区别。ESB容器模型的分布式特点允许单个Web服务按需加入ESB骨干服务中。尽管ESB容器之间是相互独立的,但该特点使得它们能够高度分散且以高度分布的方式一起工作。图2.6中所示的应用运行的不同平台之间是相互独立的,但可以通过总线相互连接,因为逻辑节点是以Web服务的方式提供的。
在企业环境中,服务事件(例如,一名客户的订单、货物到达装卸码头或者支付账单)可能在任何时间点发生影响服务常规模型的过程。这说明了服务处理不能被设计为一个先验地认为事件会按照事先确定的常规模式处理,而是需要规定由异步事件驱动的动态处理流程。为了支持这样的应用,SOA需要加强EDA(Event Driven Architecture,事件驱动架构)设计,它在实现SOA的同时考虑到了服务事件的高度动态特性。一个ESB要求应用和事件驱动的Web服务在松耦合SOA环境中绑定在一起,在支持同一个服务处理流程和方法的同时,EDA允许应用和Web服务相互独立运行。
在ESB有效的EDA中,应用和服务被抽象在能够快速响应异常事件的服务节点。EDA提供一套抽象底层连接和协议细节的方法。
SOA改进版中的服务不要求理解协议的实现或者有任何其他服务的路由消息。一个事件产生器通过ESB发送消息,然后ESB发布消息给订阅此事件的服务。事件本身封装一个服务活动中,并形成一个完整的特定事件描述。为了实现该功能,ESB支持已有Web服务技术,包括SOAP(Simple Object Accrss Protocol,简单对象访问协议)、WSDL(Web Services Description Language,Web服务描述语言)和BPEL(Business Process Execution Language,业务流程执行语言),以及正在出现的标准,如WS-Reliable Messaging和WS-Notification。
如前所述,在SOA代理中,服务的提供者和请求者之间仅有的依赖关系就是由WSDL描述并通过服务代理广播出去的服务契约。服务请求者和服务提供者之间是运行时的依赖关系,而非编译时的依赖关系,客户端在运行时能够获取和使用所需服务的所有信息。服务接口是动态发现的,而且消息也是动态生成的。服务客户直到需要服务时才需要知道请求消息的格式或者服务的位置。
为了能够实现服务与其客户端之间的解耦,EDA要求事件生产者和事件消费者能够充分解耦。也就是说,事件生产者不需要特定的事件消费者信息。因此,不需要服务契约向客户端解释服务的行为。事件消费者和事件生产者之间仅有的关系就是通过ESB将自己注册为事件生产者或者事件订阅者。尽管EDA的重点放在了事件生产者和事件消费者之间的解耦,事件消费者可能需要它接收和处理事件的元数据。为了解决该需求,事件生产者经常根据一些对事件消费者有效的面向应用事件类型(有时是手动建立的约定)来组织事件。这种分类方法典型地规定事件的类型及其用来描述以下元数据,这些元数据是已发布的并且事件消费者能够订阅,包括事件相关属性的格式和可能在事件生产者服务和事件消费者服务之间进行交互的相关消息。