全文刊载于2007年5月出版的《程序员》杂志上。 在线阅读:http://www.cnki.com.cn/Article/CJFDTotal-ITSJ200705045.htm 摘要: 在许多次与客户的接触中,我需要给出一系列基本的SOA原则。 以下各部分介绍了一个面向服务的架构(Service-Oriented Architecture)所应体现的基本原则。这些并非绝对真理,但是在进行SOA相关论述时可以作为一个参考。 你会发现,前四条原则是基于了Don Box提出的四点宗旨[1],尽管随着时间的推移,其中可能已经掺入了我个人的理解。 1. 显式边界(Explicit Boundaries)在调用一个服务时,应该向它提供完成其功能所需的全部信息。访问一个服务的唯一途径是通过其公开接口;调用一个服务不需满足任何隐含的前提。“服务与消息传递是紧密联系的,因为消息是进入和离开服务的唯一手段”[2]。一次服务调用不应依赖于共享的上下文;相反,服务调用应该是一种无状态的(stateless)模型。服务所暴露(expose)的接口是由契约(contract)来定义的,契约描述了服务在功能性(functional)及非功能性(non-functional)方面的能力与特征。对服务的调用(invocation)是一个产生业务效果的动作(action),这一动作可能会耗费相当多的资源,并引入跟本地方法调用(local method invocation)或远过程调用(remote procedure call)的错误不相同的一类错误。服务调用跟远过程调用是不一样的。 <略> 2. 共享的是契约和模式,而不是类(Shared Contract and Schema, not Class)有了服务描述(也就是契约),服务的消费者和提供者便有了使用或提供服务所需的全部信息。根据松耦合原则,一个服务提供者不能指望其消费者有能力来重用提供者在自身环境中提供的任何代码;毕竟,他们所使用的开发或运行环境可能会有不同。本原则严格限制了可在SOA中交换的数据类型。理想的情况是,数据以XML文档的形式被交换,XML文档可以针对一个或多个模式(schema)来进行验证(validation)——这是每个编程环境都支持的。 <略> 3. 策略驱动的(Policy-driven)要与服务交互,有两个正交的需求集合是必须要满足的: 1. 服务提供者必须在功能、语法和语义方面符合服务消费者的需求, 2. 服务提供者与服务消费者在技术方面的能力及要求必须相匹配。 <略> 4. 自治的(Autonomous)与“显式边界”原则相关,服务是自治的,因为(至少从SOA的观点来看)接口是服务与外界联系的唯一途径。 <略> 5. 线上格式,而不是编程语言APIs(Wire formats, not Programming Language APIs)服务是通过特定的线上格式(wire format)来访问的。这一原则跟头两条原则十分相关,不过它引入了一则新的观点:为了确保最大的可用性(因此具备长久的易用性),必须能够通过任何平台来访问服务,只要该平台支持符合服务接口的消息交换、并且交互符合服务的策略。 <略> 6. 面向文档的(Document-oriented)为了与服务进行交互,数据是以文档的形式传送的。这里的文档指的是一种显式建模的、层次化的数据容器。自描述性(self-descriptiveness)是面向文档(document-orientation)的一个重要方面。理想的情况是,文档应该根据现实世界的文档(例如订购单、发票、对帐单等)来建模。文档的设计应该令文档在问题域环境中有用,也就是说能够满足与一个或多个服务交互的用途。 <略> 7. 松耦合的(Loosely coupled)许多SOA的支持者们都同意松耦合(loose coupling)是一个重要的概念。不过,关于一个“松耦合的”系统应该具备什么样的特征,则存在多种不同观点。一个系统松耦合还是紧耦合,可以从多个方面来考量,而且还跟需求及上下文有关;一个系统可能在某些方面是松耦合的,而在另一些方面是紧耦合的 <略> 8. 遵从标准的(Standards-compliant)SOA方法要遵从的一个关键原则就是应依赖于标准,而不是私有的API与格式。各个技术方面(比如数据格式、元数据、传输和传送协议)和业务级成分(比如文档类型UBL[7])都有相关的标准。 <略> 9. 厂商中立的(Vendor independent)任何架构原则都不应依赖于任何特定厂商的产品。要把一个抽象概念转变为实实在在运行着的系统,不可避免地要对特定产品(商业软件和免费/开源软件)做出选择。但产品的选择,必须确保不能产生任何架构级上的影响。 <略> 10. 元数据驱动的(Metadata-driven)整个SOA里的所有元数据成分,都需要以一种有利于在设计和运行时被发现、获取和解释的方式来存储。元数据成分(metadata artifacts)包括服务接口、参与者、端点及绑定信息、组织单元及职责、文档类型/模式(schemas)以及消费者/提供者关系等的描述。对这些元数据成分的运用应该尽可能地自动化(通过代码生成或解释),并成为服务和参与者生命周期的一部分。 <略>