对于面向服务的体系结构(Service-Oriented Architecture,SOA)的几种定义:
W3C:SOA是一种应用程序体系结构,在这种体系结构中,所有功能都定义为独立的服务,这些服务带有定义明确的可调用接口,能够以定义好的顺序调用这些服务来形成业务流程。
Service-architecture.com:服务是精确定义、封装完整、独立于其它服务所处环境和状态的函数。SOA本质上是服务的集合,服务之间彼此通信,这种通信可能是简单的数据传送,也可能是两个或更多的服务协调进行某些活动。服务之间需要某些方法进行连接。
Gartner:SOA是一种C/S体系结构的软件设计方法,应用由服务和服务使用者组成,SOA与大多数通用的C/S体系结构模型不同之处,在于它着重强调构件的松散耦合,并使用独立的标准接口。
1. SOA 概述
8.1.1 服务的基本结构
-
服务模型的表示层从逻辑层分离出来,中间增加了服务对外的接口层。
-
通过服务接口的标准化描述,使得服务可以提供给在任何异构平台和任何用户接口使用。
-
这允许并支持基于服务的系统成为松散耦合、面向构件和跨技术实现,服务请求者很可能根本不知道服务在哪里运行、由哪种语言编写,以及消息的传输路径,而是只要提出服务请求,然后就会得到答案。
1.2 SOA的特征
SOA是一种粗粒度、松耦合的服务体系结构,其服务之间通过简单、精确定义接口进行通信,不涉及底层编程接口和通信模型。
-
松散耦合。
SOA是松散耦合构件服务,这一点区别于大多数其他的构件体系结构。
松散耦合旨在将服务使用者和服务提供者在服务实现和客户如何使用服务方面隔离服务。
提供者和服务使用者之间松散耦合的关键点是服务接口作为与服务实现分商的实体面存在。
服务实现能够在完全不影响服务使用者的情况下进行修改,大多数松散合力法都依靠基于服务接口的消息,基于消息的接口能够兼容多种传输方式(如HTTP、TCPIP、MOM等),基于消息的接口可以采用同步或异步协议实现。
-
粗粒度服务。
服务粒度(Service Granularity)指的是服务所公开功能的范围,一般分为细粒度和粗粒度。
-
细粒度服务是能够提供少量业务流程可用性的服务;
-
粗粒度服务是能够提供高层业务逻辑的可用性服务。
选择正确的抽象级别是SOA建的一个关键问题,设计应该在不损失或损坏相关性、一致性和完整性的情况下,尽可能地进行粗粒度建模。
通过一组有效设计和组合的粗粒度服务,业务专家能够有效地组合出新的业务流程和应用程序。
-
-
标准化接口。
SOA通过服务接口的标准化描述,使得该服务可以在任何异构平台和任何用户接口中使用。
这一描述囊括了与服务交互需要的全部细节,包括消息格式、传输协议和位置。
该接口隐藏了实现服务的细节,允许独立于实现服务基于的硬件或软件平台和编写服务所用的编程语言使用服务。
1.3 服务构建与传统构件
服务构件体系结构(SCA):
-
基于SOA的思想描述服务之间组合和协作的规范,它描述用于使用SOA构建应用程序和系统的模型。
-
它可简化使用 SOA 进行的应用程序开发和实现工作。
-
SCA 提供了构建粗粒度构件的机制,这些粗粒度构件由细粒度构件组装而成。
-
SCA将传统中间件编程从业务逻辑分离出来,从而使程序员免受其复杂性的困扰。
-
它允许开发人员集中精力编写业务逻辑,而不必将大量的时间花费在更为底层的技术实现上。
SCA服务构件与传统构件的区别:
-
服务构件往往是粗粒度的,而传统构件以细粒度居多;
-
服务构件的接口是标准的,主要是服务描述语言接口,而传统构件常以具体API形式出现;
-
服务构件的实现与语言是无关的,而传统构件常绑定某种特定的语言;
-
服务构件可以通过构件容器提供QoS的服务,而传统构件完全由程序代码直接控制。
1.4 SOA的设计原则
在SOA体系结构中,继承了来自对象和构件设计的各种原则,如封装、自我包含等那些保证服务的灵活性、松散耦合和复用能力的设计原则,对SOA体系结构同样非常要。
关于服务,常见的设计原则如下:
-
明确定义的接口。
服务请求者依赖于服务规约调用服务,因此,服务定义必须长时间稳定,一旦公布,不能随意更改;
服务的定义应尽可能明确,减少请求者的不适当使用,不要让请求者看到服务内部的私有数据。
-
自包含和模块化。
服务封装了在业务上稳定、重复出现的活动和构件,实现服务的功能实体完全独立自主,独立进行部署、版本控制、自我管理和恢复。
-
粗粒度。
服务数量不应该太多,依靠消息交互而不是远程过程调用,通常消息量比较大,但是服务之间的交互频度较低。
-
松耦合。
服务请求者可见的是服务的接口,其位置、实现技术、当前状态、私有数据等,对服务请求者而言是不可见的。
-
互操作性、兼容和策略声明。
为了确保服务规约的全面和明确,策略成为一个越来越重要的方面。
-
可以是技术相关的内容,例如,一个服务对安全性方面的要求;
-
可以是与业务有关的语义方面的内容,例如,需要满足的费用或者服务级别方面的要求。
这些策略对于服务在交互时是非常重要的。
-
2. 面向服务的分析与设计
2.1 基础设计层
SOAD的第一层是基础设计层,它采用了OOAD的思想,其主要目标是能够进行快速而有效的设计、开发以及执行灵活且可扩展的底层服务构件。
对于设计已定义的服务中的底层类和构件结构,OO是一种很有价值的方法。
目前与SOAD有关的OO设计在实践中也存在着一些问题:OO的粒度级别集中在类级,对于业务服务建模来说,这样的抽象级别太低。
类似继承这样的强关联产生了相关方之间一定程度的紧耦合。与此相反,SOAD试图通过松耦合促进灵活性和敏捷性。这使得OO难以与SOAD体系结构保持一致。
诸如这些问题有待进一步解决,尽管如此,OO还是为SOAD提供了丰富的理论源泉。
2.2 体系结构层
SOAD第二层是体系结构层,它采用了EA的理论框架。
企业应用程序和IT基础体系结构发展成SOA是一个庞大的工程,其中可能涉及众多的业务流水线和组织单元。
因此需要应用EA框架和参考体系结构,以努力实现单独的解决方案之间体系结构的一致性在SOA中,体系结构层必须以表示业务服务的逻辑构件为中心,并且集中于定义服务之间的接口和服务级协定。
2.3 业务层
SOAD第三层是业务层,它采用了BPM规则。
BPM是一个不完整的规则,包含许多不同的形式、表示法和资源,其中应用较为广泛的是UML。
SOA必须利用所有现有的BPM方法作为SOAD的起点,同时需要服务流程编排模型中用于驱动候选服务和它们的操作的附加技术对其加以补充。
此外,SOAD中的流程建模必须与设计层用例保持同步。
3. SOA的关键技术
3.1 发现服务层
发现服务层主要用来帮助客户端应用程序解析远程服务的位置,一般通过UDDI来实现。
-
UDDI规范由Microsoft、IBM和Ariba三家公司在2000年7月提出,它是服务的信息注册规范,以便被需要该服务的用户发现和使用它。
-
UDDI规范描述了服务的概念,同时也定义了一种编程接口。通过UDDI提供的标准接口,企业可以发布自己的服务供其他企业查询和调用,也可以查询特定服务的描述信息,并动态绑定到该服务上。
-
通过UDDI,Web服务可以真正实现信息的“一次注册到处访问”。
3.2 描述服务层
描述层为客户端应用程序提供正确地与远程服务交互的描述信息,主要通过WSDL来实现。
-
与UDDI一样,WSDL也是由Microsoft、IBM和Ariba三家公司在2000年7月提出的。
-
WSDL为服务提供者提供以XML格式描述服务请求的标准格式,将网络服务描述为能够进行消息交换的通信端点集合,以表达一个服务能做什么,它的位置在哪,如何调用它等信息。
3.3 消息格式层
消息格式层主要用来保证客户端应用程序和服务器端在格式设置上保持一致,一般通过SOAP来实现。
-
SOAP定义了服务请求者和服务提供者之间的消息传输规范。
-
SOAF用XML来格式化消息,用HTTP来承载消息。
-
SOAP包括3个部分:
-
定义了描述消息和如何处理消息的框架的封装(SOAP封装;
-
表达应用程序定义的数据类型实例的编码规则(SOAP编码规则);
-
描述远程过程调用和应答的协议(SOAPRPC表示)。
-
3.4 编码格式层
编码格式层主要为客户端和服务器之间提供一个标准的、独立于平台的数据交换编码格式,一般通过XML来实现。
-
XML是一种元语言,可以用来定义和描述结构化数据。
-
XML使用基于文本的、利用标准字符集的编码方案,从而避开了二进制编码的平台不兼容问题。
-
XML有很多优点,包括跨平台支持,公用类型系统和对行业标准字符集的支持,它是服务得以实现的语言基础。
-
服务的其他协议规范都是以XM形式来描述和表达的。
3.5 传输协议层
传输协议层主要为客户端和服务器之间提供两者交互的网络通信协议,一般通过HTTP( Hypertext Transfer Protocol,超文本协议)和 SMTP(Simple Mail TransportProtocol,简单邮件传输协议)来实现。
-
HTTP是一个在Internet广泛使用的协议,为服务部件通过Internet交互奠定了协议基础,并具有穿透防火墙的良好特性。
-
SMTP则适合于异步通信,如果服务中断,SMTP可以自动进行重试。
4. SOA的实现方法
从逻辑和高层抽象来看,目前实现SOA的方法也比较多,其中主流方式有Web Service、企业服务总线和服务注册表。
4.1 Web Service
在WebService(Web服务)的解决方案中,一共有3种工作角色,其中服务提供者和服务请求者是必需的,服务注册中心是可选的。它们之间的交互和操作构成了SOA的一种实现体系结构。
服务提供者。
-
服务提供者是服务的所有者,该角色负责定义并实现服务,使用WSDL对服务进行详细、准确、规范的描述,并将该描述发布到服务注册中心,供服务请求者查找并绑定使用。
服务请求者。
-
服务请求者是服务的使用者,虽然服务面向的是程序,但程序的最终使用者仍然是用户。从体系结构的角度看,服务请求者是查找、绑定并调用服务,或与服务进行交互的应用程序。服务请求者角色可以由浏览器担当,由人或程序(如另外一个服务)控制。
服务注册中心。
-
服务注册中心是连接服务提供者和服务请求者的纽带,服务提供者在此发布他们的服务描述,而服务请求者在服务注册中心查找他们需要的服务。
-
在某些情况下,服务注册中心是整个模型中的可选角色。例如,如果使用静态绑定的服务,服务提供者则可以把描述直接发送给服务请求者。
Web Service 模型中的操作包括发布,查找和绑定,这些操作可以单次或反复出现:
-
发布。
为了使用户能够访问服务,服务提供者需要发布服务描述,以便服务请求者可以查找它。
-
查找。
在查找操作中,服务请求者直接检索服务描述或在服务注册中心查询所要求的服务类型。对服务请求者而言,可能会在生命周期的两个不同阶段中涉及查找操作,首先是在设计阶段,为了程序开发而查找服务的接口描述;其次是在运行阶段,为了调用而查找服务的位置描述。
-
绑定。
在绑定操作中,服务请求者使用服务描述中的绑定细节来定位、联系并调用服务,从而在运行时与服务进行交互。绑定可以分为动态绑定和静态绑定。在动态绑定中,服务请求者通过服务注册中心查找服务描述,并动态地与服务交互;在静态绑定中,服务请求者已经与服务提供者达成默契,通过本地文件或其他方式直接与服务进行绑定。
在采用WebService作为SOA的实现技术时,应用系统大致可以分为6个层次,分别是底层传输层、服务通信协议层、服务描述层、服务层、业务流程层和服务注册层。
-
底层传输层。
底层传输层主要负责消息的传输机制,HTTP、JMS(Java MessagingService,Java消息服务)和SMTP都可以作为服务的消息传输协议,其中HTTP使用最广泛。
-
服务通信协议层。
服务通信协议层的主要功能是描述并定义服务之间进行消息传递所需的技术标准。常用的标准是SOAP 和REST协议。
-
服务描述层。
服务描述层主要以一种统一的方式描述服务的接口与消息交换方式,相关的标准是 WSDL。
-
服务层。
服务层的主要功能是将遗留系统进行包装,并通过发布的WSDL接口描述被定位和调用。
-
业务流程层。
业务流程层的主要功能是支持服务发现,服务调用和点到点的服务调用,并将业务流程从服务的底层调用抽象出来。
-
服务注册层。
服务注册层的主要功能是使服务提供者能够通过WSDL发布服务定义,并支持服务请求者查找所需的服务信息,相关的标准是UDDI。
4.2 服务注册表
服务注册。
-
服务注册是指服务提供者向服务注册表发布服务的功能(服务合约),包括服务身份、位置、方法、绑定、配置、方案和策略等描述性属性。
服务位置。
-
服务位置是指服务使用者,帮助它们查询已注册的服务,寻找符合自身要求的服务。
服务绑定。
-
服务使用者利用查找到的服务合约来开发代码,开发的代码将与注册的服务进行绑定,调用注册的服务,以及与它们实现互动。
4.3 企业服务总线
ESB的概念是从SOA发展而来,它是一种为进行连接服务提供的标准化的通信基础结构,基于开放的标准,为应用提供了一个可靠的、可度量的和高度安全的环境,并可帮助企业对业务流程进行设计和模拟,对每个业务流程实施控制和跟踪、分析并改进流程和性能。
ESB具有以下功能:
-
支持异构环境中的服务、消息和基于事件的交互,并且具有适当的服务级別和可管理性。
-
通过使用ESB,可以在几乎不更改代码的情况下,以一种无缝的非侵人方式使现有系统具有全新的服务接口,并能够在部署环境中支持任何标准。
-
充当缓冲器的ESB(负责在诸多服务之间转换业务逻辑和数据格式)与服务逻辑相分离,从而使不同的系统可以同时使用同一个服务,无须在系统或数据发生变化时,改动服务代码。
-
在更高的层次,ESB还提供诸如服务代理和协议转换等功能。允许在多种形式下通过像HTTP、SOAP和IMS总线的多种传输方式,主要是以网络服务的形式,为发表、注册、发现和使用企业服务或界面提供基础设施。
-
提供可配置的消息转换翻译机制和基于消息内容的消息路由服务,传输消息到不同的目的地。
-
提供安全和拥有者机制,以保证消息和服务使用的认证、授权和完整性。
ESB的优势:
-
扩展的、基于标准的连接。
ESB形成一个基于标准的信息骨架,使得在系统内部和整个价值链中可以容易地进行异步或同步数据交换。ESB通过使用XML、SOAP和其他标准,提供了更强大的系统连接性。
-
灵活的、服务导向的应用组合。
基于SOA、ESB使复杂的分布式系统(包括跨多个应用、系统和防火墙的集成方案)能够由以前开发测试过的服务组合而成,使系统具有高度可扩展性。
-
提高复用率、降低成本。
按照SOA方法构建应用,提高了复用率,简化了维护工作,进而减少了系统总体成本。
-
减少市场反应时间,提高生产率。
ESB通过构件和服务复用,按照SOA的思想简化应用组合,基于标准的通信、转换和连接实现这些优点。
5. 服务描述语言
5.1 WSDL概述
WSDL是对服务进行描述的语言,它有一套基于XML的语法定义。
WSDL描述的重点是服务,它包含 Service Implementation Definition(服务实现定义)和Service Interface Definition(服务接口定义)。
-
采用抽象接口定义对于提高系统的扩展性很有帮助。
-
服务接口定义就是一种抽象的、可重用的定义,行业标准组织可以使用这种抽象的定义规定一些标准的服务类型,服务实现者可以根据这些标准定义来实现具体的服务。
-
服务实现定义描述了给定服务提供者如何实现特定的服务接口。
-
服务实现定义中包含服务和端口描述。
-
服务描述了一个特定的Web服务所提供的所有访问入口的部署细节,一个服务往往会包含多个服务访问入口,而每个访问人口都会使用一个端口元素来描述。
-
端口描述的是一个服务访问人口的部署细节,包括通过哪个URL访问,应当使用怎样的消息调用模式访问等。
5.2 使用WSDL文档
在设计时期,开发者根据WSDL文档生成调用Web服务的客户端代码,可以将这样的代码称为服务代理类,实际的服务使用都发生在代理类与服务之间。
在编写客户应用程序的过程中,开发者就像使用本地类一样直接使用服务代理类,开发客户端程序。
在运行期,客户应用程序通过它所处的运行环境发出对服务的调用请求,运行环境根据WSDL文档生成正确的服务调用请求,并接受WebService返回的结果,然后把结果传递给客户应用程序。
5.3 WSDL文档结构
types(类型):数据类型定义的容器,提供了用于描述正在交换的消息的数据类型定义,一般使用XML Schema中的类型系统。
message(消息):通信消息数据结构的抽象定义。message使用types所定义的类型来定义整个消息的数据结构。
operation(操作):对服务中所支持的操作的抽象描述,一般单个operation描述了一对访问入口的请求/响应消息。
porttype(端口类型):描述了一组操作,每个操作指向一个输入消息和多个输出消息规范。
binding(绑定):为特定端口类型定义的操作和消息制定具体的协议和数据格式。
port(端口):指定用于绑定的地址,定义服务访问点。
service:相关服务访问点的集合。
6. 统一描述、发现和集成协议
UDDI的三个部分:
-
UDDI数据模型。
一个用于描述企业和服务的XML Schema。
-
UDDI API。
一组用于查找或发布UDDI数据的方法,基于SOAP。
-
UDDI注册服务。
一种基础设施,对应着服务注册中心的角色。
6.1 UDDI数据模型
6.2 注册web服务
注册web服务注意事项:
-
确定Web服务的tModel(WSDL文档)。
-
确定组织(企业、事业单位、各类机构等,下同)名称、简介以及所提供的Web服务的主要联系方法。
-
确定组织正确的标识和分类。
-
确定组织通过UDDI提供的Web服务。
-
确定所提供的Web服务的正确分类。
6.3 调用web服务
-
编写调用Web服务的程序时,程序员使用UDDI注册中心来定位并获得businessEntity。
-
程序员可以进一步获得更详细的businessService信息,或是得到一个完整的businessEntity结构。因为businessEntity结构中包含了已发布的Web服务的全部信息,所以,程序员可以从中选择一个bindingTemplate待以后使用。
-
Web服务在tModel中提供了相关规范的引用地址,程序员可以根据引用地址获得规范并编写程序。
-
运行时,程序员可以按需要使用已经保存下来的bindingTemplate信息,调用Web Service。
7. 消息封装协议
SOAP的组成部分:
-
SOAP封装。
定义一个整体框架,用来表示消息中包含什么内容,谁来处理这些内容,以及这些内容是可选的或是必需的
-
SOAP编码规则。
定义了一种序列化的机制,用于交换系统所定义的数据类型的实例
-
SOAP RPC表示。
定义一个用来表示远程过程调用和应答的协议
-
SOAP绑定。
定义一个使用底层传输协议来完成在节点间交换SOAP信封的约定
7.1 消息封装
封装:
-
封装的元素名是“Envelope”,在表示消息的XML文档中,封装是顶层元素,在SOAP消息中必须出现。
SOAP头:
-
SOAP头的元素名是“Header”,提供了向SOAP消息中添加关于这条SOAP消息的某些要素(feature)的机制。
-
SOAP定义了少量的属性用来表明这项要素是否可选以及由谁来处理。
-
SOAP头在SOAP消息中可能出现,也可能不出现。如果出现的话,必须是SOAP封装元素的第一个直接子元素。
-
SOAP头可以包含多个条目,每个条目都是SOAP头元素的直接子元素。
SOAP体:
-
SOAP体的元素名是“Body”,是包含消息的最终接收者想要的信息的容器。
-
SOAP体在SOAP消息中必须出现且必须是SOAP封装元素的直接子元素。
-
如果有头元素,则SOAP体必须直接跟在SOAP头元素之后;如果没有头元素,则SOAP体必须是SOAP封装元素的第一个直接子元素。
-
SOAP体可以包括多个条目,每个条目必须是SOAP体元素的直接子元素。
7.2 编码规则
值(value):
-
值是一个字符串、类型(数字、日期、枚举等)的名或是几个简单值的组合。所有的值都有特定的类型。
简单值(simple value):
-
简单值没有名部分,例如,特定的字符串、整数、枚举值等。
复合值(compound value):
-
复合值是相关的值的组合,例如,定单、股票报表、街道地址等。在复合值中,每个相关的值都以名、序号或这两者来区分,这称为访问者(accessor)。在复合值中,多个访问者有相同的名是允许的。
数组(array):
-
数组是一个复合值,成员值按照在数组中的位置相互区分。
结构(struct):
-
结构也是一个复合值,成员值之间的唯一区别是访问者的名字,访问者名互不相同。
简单类型(simple type):
-
简单类型是简单值的类,例如,字符串类、整数类、枚举类等。
复合类型(compound type):
-
复合类型是复合值的类,它们有相同的访问者名,但可能会有不同的值。
7.3 在HTTP中使用SOAP
把SOAP绑定到HTTP,无论使用或不用HTTP扩展框架,都有很大的好处:在利用SOAP的形式化和灵活性的同时,使用HTTP种种丰富的特性。
在HTTP中携带SOAP消息,并不意味着SOAP改写了HTTP已有的语义,而是将构建在HTTP之上SOAP语义自然地对应到HTTP语义。
SOAP自然地遵循HTTP的请求/应答消息模型,使得SOAP的请求和应答参数可以包含在HTTP请求和应答中。
7.4 在RPC中使用SOAP
设计SOAP的目的之一就是利用XML的扩展性和灵活性来封装和交换RPC调用,在RPC中使用SOAP和SOAP协议绑定是紧密相关的。
在使用HTTP作为绑定协议时,一个RPC调用自然地映射到一个HTTP请求,RPC应答同样映射到HTTP应答。但是,在RPC中使用SOAP并不限于绑定HTTP协议。
要进行方法调用,一般需要以下信息:目标对象的URI、方法名、方法签名(signature)、方法的参数、头数据,其中方法签名和头数据是可选的。
SOAP依靠协议绑定提供传送URI的机制。例如,对HTTP来说,请求的URI指出了调用的来源。
除了必须是一个合法的URI之外,SOAP对一个地址的格式没有任何限制
7.5 REST设计概念和准则
网络上的所有事物都被抽象为资源。
每个资源对应一个唯一的资源标识符。
通过通用的连接件接口对资源进行操作。
对资源的各种操作不会改变资源标识。
所有的操作都是无状态的。
8. 补充
-
什么是SOA?SOA具有哪些特征?
-
简单描述Web服务体系结构模型,Web服务体系结构开发生命周期及其优势。
-
Web服务作为Web服务体系结构的核心,简要说明Web服务的核心技术及其作用。
-
简述面向服务的体系结构的概念及其设计原则。