引子
伴随世纪变迁,我们愈发感觉到需要一些稳定的,恒定的甚至"不可触及"的东西,由他们去支配其他不断变化的事物。诸如宗教仪式、数学公理和地球形状等,都属这类恒定的事物之列。然而有时候,人们在不断进化的过程中所积累的知识又迫使人们去修正对那些恒定事物的认识,这类事情时有发生, 譬如,数学公理就是这样不断变化的事物之一,特别是欧几里德的几何理论和人们对地球形状的认识。赫拉克利特曾说过:“唯一不变的是变化本身”,我决定追随他的智慧。
有些人的态度是简单地相信那些恒定事物,这样做非常简单;而另一些人则常常勇于挑战那些不变的事物——寄以弄清它们是否真正地永恒……本文的形成受益于这里提及的两类人的长期争论,探讨的话题与一组设计模式有关,即当它们的应用环境改变时,其利与弊?
这里就有一个这样的热点话题,大家都知道两个经常被提到的模式——门面模式(Fa??ade Pattern)和仲裁者模式(Mediator Pattern);当其应用环境从最初假定的应用编程的范畴发展到企业技术层编程的范畴,并最终发展到贯穿于业务时,其作用会有如何变化呢?这个论题之所以如此有趣,我想是因为:
- 技术产品物化了这些模式
- 这些产品被厂商推向企业的 IT 部门,极大地影响了人们的日常工作。
在这类产品之中,企业服务总线(ESB)突然间变成了实施面向服务的架构(SOA)的“必备”要素,然而对于其中的缘由却缺乏说得过去的解释。现有的大部分“解释”谈论的是采用 ESB 产品我们能够做什么,但是这种解释的结果仍然没能解开谜团。
根据日常生活中得到的经验,在开始本文之前,必须要明确一些术语的定义,确定“相通”的语言。比如,当中文提到 SOA 时,它指的是 OASIS 的 SOA 标准,如参考模型(Reference Model)和SOA参考架构基础标准草案;而“业务服务(Business Service )”则指的是在OASIS SOA 的语境下,人工服务和自动服务的综合体。它们实现特定的业务功能或特性,提供访问业务能力的途径。业务服务的实现方式多种多样,比方说,业务流程就是一种实现方式。人们通常将业务流程理解成一组按特定顺序编排的人工活动或自动化活动的集合。
谈及模式时,我采用的是 GoF 著作中给出的定义。有时,模式与实现该模式的产品的名字相同,所以我们必须要交代清楚。
一千人眼中有一千个门面
让我们先从门面模式开始热身一下吧。自 1681 年开始,门面这个词语就指建筑物的正面。在技术领域中,我们从 GoF 著作中对门面的定义开始——门面是在面向对象(OO)的设计中屏蔽其他接口的前端接口。一般来说,门面模式的实现能够将发送方(根据粗粒度的前端接口)发送过来的消息拆分成细粒度的目标接口所能识别的一组消息。这一能力解放了发送者,它不再需要理解目标接口的详细信息。与此同时,位于门面接口之后的接收者扮演的是仲裁者的角色,因为它知道如何拆分请求消息,并将拆分后的消息分往目标接口。
Java 中有个 EJB 门面模式。该组件门面与其 OO 祖先略有不同。EJB 门面模式通过如下方式提供服务:1)接受粗粒度聚合请求,该聚合请求是由发往若干其他 EBJ 的请求组合而成的;2)拆分请求并调用合适的 EJB 组件。在此场景中,门面模式从面向对象到面向组件的环境改变中存活了下来,但这却是它最后一次幸存。
也许因为门面模式非常有吸引力,所以大家又在面向服务(SO)的环境中根据个人需要给出了新的定义。下面是对服务门面模式的三个不同的定义, 在 SO 环境中他们之间又相互有着“细微的差别”。
我们首先从 IBM 的定义开始:
“该模式致力于在服务请求者与应用程序提供的功能或不以服务的形式而存在的能力之间提供松耦合的连接。松耦合隐藏了服务提供者的复杂性,取而代之的是标准的 Web 服务接口……服务门面模式还引入了一个仲裁点,由它负责若干标准功能,如日志。”
后来 IBM 又对上述定义作了追述:
“遗留的应用系统本身不能天然地融入 SOA 环境,对这些系统作出改变即昂贵又需要稀缺的技能……当企业希望在 SOA 的环境中向服务客户端提供服务接口,同时服务提供者的应用程序又无法便利地升级到能够提供服务接口时,使用该模式再适合不过了。”
IBM 的目标和方法非常清晰——如果资源不能便利地通过服务的形式被访问,那就交由门面来处理。
与此同时,《.NET 模式:架构、设计和流程》一书中把服务门面描述成服务间的分界线,并将它提升到“控制器”的层面,而且是个具体的服务(再一次印证了“Web 服务”这个名字是多么地晦涩):
“提供一个 Web 服务的控制类,它是业务逻辑门面对象的接入点。业务逻辑门面对象又能在除了 Web 服务之外的其他环境里(比如基于 CORBA 的应用程序)得到重用。”
另一定义引自 Thomas Erl 所著的《SOA 设计模式》一书:
“一个服务如何能既适应其服务契约(Service Contract)或实现,又能支持核心服务逻辑独立发展呢?核心服务逻辑与其契约及实现资源之间的耦合性会阻碍其发展,并对服务消费者带来负面影响。”
所以,此处担心的是服务接口不适宜地暴露了服务实现。即,
“服务门面组件用于封装服务架构中有着负面的耦合可能性的那一部分。门面逻辑位于契约和核心服务逻辑之间,在核心服务逻辑与契约之间起着解耦合的作用。”
可以看出,上述引用的.NET 服务门面只不过是外部访问的 Web 服务接口与实际实现服务功能的类 / 对象的接口之间的一个仲裁者而已。根据我的理解,Web 服务接口一定是服务门面,但是,.NET 服务门面却退居 Web 服务之后,建立了一个门面的门面。这表明,不是 Web 服务接口有问题,就是服务实现 (即具有真正功能的类或对象)的设计未能按照 Web 服务接口而正确地设计。
对于 IBM 而言,服务门面屏蔽了“不以服务的形式存在的资源”的原始接口。这很好,如果该门面是一个服务,那我就没有任何疑问。不然,我就会对 IBM 的定义充满怀疑。因为,如果服务门面只是一个接口,这听起来好像 IBM 仅仅为非服务的资源加上一层“神奇的”门面接口就使之变成了服务。对我来说,大家好像是在应对一个经典的语义问题:在谈论什么是现实世界所需的东西时玩文字游戏。尤其,当我们增加一门面或连接器时,增加的只能是新的连接性,但不论增加何种接口,都不可能改变本质,即事物的精髓(如可服务性)。用透明的玻璃盖代替金属盖放在煎鸡蛋的平底锅上,鸡蛋就能变成比萨?你认为呢 ?
《SOA 设计模式》一书中描述的服务门面模式是一种与 MS .NET 和 IBM 的解释完全不同的事物。该解释,也就是上面的引文,引出了一个提问:服务门面模式是(如 Thomas Erl 所称的)架构模式,还是 SOA 架构中所看不到的一种实现模式?
在 Erl 的解释中,首先跃入我的眼帘的是“服务契约(Service Contract)”这个词,而它与 OASIS SOA 标准不符。基于上述引文我们只能推测“服务契约(Service Contract)”就是“服务接口(Service Interface)”(而“契约” 这个词汇的语义比“接口”更丰富,所以这种说法可能会误导开发者)。有了这层推测,引文中的最初的问题似乎是:“一个服务如何既能适应其服务接口(Service Interface)或实现,又能支持核心业务逻辑独立发展呢”?一个直观的结论是,接口在某处发生变化,而核心业务逻辑在另一处独立地发展,而服务体 / 实现也在自己的轨道上改变……这种做法,如果不能称之为荒谬的话,至少可以说是一团糟或在语义上是乱七八糟的。难道“位于契约和核心服务逻辑之间”的服务门面只求掩盖这种一团糟的局面,而不求解决问题吗?如果回答是“是”,那么至少这不是 GoF 定义的模式。
Erl 的解释很显然牵扯到的问题之二是,服务接口实现细节与服务接口之间的耦合,比如,服务接口由服务的实现细节驱动吗?但是,服务接口必须由服务功能的访问方式决定。如果有人违反这一规矩,通过特定的服务内部实现生成服务接口(如某些不负责任的厂商在 Web 服务采纳的初期所建议的那样),那么他最好请求消费者的原谅,完全摈弃这种服务接口,重新建立 / 发布新设计的接口。比起将错误隐藏在门面之后并将错误的接口留给用户,这种做法来的更加安全及公平。为了避免将来出现这样的错误,出错就应付出代价,而不是遮盖起来。
不论如何,通过门面分离服务接口与服务实现体的想法对我而言仍然非常做作、易错并且政治化。这种分离催生了一种想法,那就是即便接口没有业务价值(注:业务价值属于服务本身),也可能独立存在。对于那些曾经试图构建一层接口层而找不到地方放置该层的人们,这种接口让他们迷惑。在业务世界中,这类接口的存在非常扭曲,就像某些建筑物的前门一样,虽然门后的建筑物已经损毁,但仍然称之为公司的总部。职能部门无法理解一个无接口的服务或者独立存在的接口 / 门面。在业务服务领域里,接口和服务是统一的整体。
因此,我们看到在面向服务的环境中门面模式的含义已经发生了变化。许多主导厂商出于“服务”概念上的 Web 服务技术的目的或利益,重新阐述了它的含义。在以上看到的情形中,门面模式(比如,服务门面模式)有着不同的语义,它们只会把我们带向巴比伦式的建筑(译注:巴比伦城的空中花园是古代建筑史上的一个奇迹,在其贯穿南北的圣道尽头是没有完工的通天塔,作者用此比喻厂商们意在营造种种美妙的构想,但是却永远无法实现),而非 IT 建设。
ESB 现象
当 David Chappell(当时他在 Progress Software 公司)发明这个词并发布第一款企业服务总线产品时,我住在马萨诸塞州的波士顿,我的一些朋友也在 Progress 公司工作。对我来说,该 ESB 产品的发布不外乎是老套的消息系统与 Web 服务联姻之后的另一市场噱头。从模式的角度看,ESB 看起来像是仲裁者模式、发布订阅模式以及适配器模式等的结合体。当时我没怎么看好它,从目前看来我当初是错了。如果 ESB 占据所有业务消费者与业务服务间的交互范围,那么其仲裁特性就是为你的 IT 安置的一个定时炸弹。ESB 产品一点一点地蚕食所有业务的交互逻辑,成为了 SO 开发中不可或缺的一部分;它将所有服务绑在一起并紧抓不放。这真是我们的企业所需的吗?若是这样,ESB 产品的重要性不因为其业务需求或业务价值,而是因为我们的 SO 环境中的任何东西都依赖于它,厂商产品还能奢求什么?
ESB 产品的现象可以被一句经典的现实主义谚语一语中的:“通往地域之路由善意铺成”。简化了一双手之间整合的解决方案成了两双手之间沟通的障碍。尽管如此,我们还需沿着它发展的过程看看这些是怎么发生的。
仲裁者模式与门面模式的发展历史十分相似。在 GoF 的书中,仲裁者模式用于帮助开发者组织对象间的逻辑交互,解决设计的像意大利面式的交互或互相依赖等方面的问题。我非常喜爱此模式,也经常使用它。我也曾提到过,当门面模式需要决定如何分发消息时,其实现常常依赖于仲裁者模式的使用。当仲裁者模式的使用环境(译者注:从管理对象间交互)转向管理组件间交互时,我们并未看到太多的改变。
Web 服务的引入也没有极大地改变仲裁者模式的使用。标准的 Web 服务接口,其本身就是一个门面,它需要一个真正的“工人”去决定如何处理接收到的消息。从该角度看,服务本身就可以内在地实现仲裁者模式。同一个开发人员(一双手)就可以控制交互的双方——消费者和服务——而不会出现任何问题。
我认为,这种开发经验促成了将 ESB 模式建立成至少是门面、仲裁者、适配器和发布订阅等模式的结合体。相应的 ESB 产品没过多久就占领了技术服务的市场。然而,在业务(如 SOA 业务服务)范畴中的功能性仲裁应有许多新的职责,这些职责对与技术领域、面向对象或面向组件的编程世界是未知的。
根据 OASIS SOA 参考架构基础的草案中,SOA 被置于业务和技术中间,同时出现在此分界线的两边。这意味着在 SOA 环境中与业务逻辑相关的所有元素都会自动地提升到“业务”的地位并与某些业务职能相联系。然而,这不能代表它们已经从其技术职能中解放出来了;它们成了双重体,这也是现代 IT 的全新形象,即立志于提升业务敏捷性。
从以上推理来看,我们可以得到如下结论:如果 ESB 产品实现了业务服务消费者与业务服务本身之间交互的业务逻辑,那么 ESB 就成了一个业务面的事物(如同 ERP 系统)。考虑到此时,你一定瞪大了眼睛,所以我不得不后退一步温习一下我们所讨论的主题,一方面是 SOA 业务服务,它通过人工活动和自动过程的组合封装了业务和技术两方面;另一方面是服务契约(Service Contract),它是使服务提供者与服务消费者间达成一致,规定服务与消费者间的关系与交互的文档。
单凭 ESB 产品带来的迷惑,以及它没能在日常工作中起到真正作用,我就可责难此模糊的 ESB 模式,稍后我们会谈到这点。为了阐述我对 ESB 产品的疑虑,先让我对其若干个通用特性提出简要的质疑,看看它们掩饰了那些风险。(该视角是必要的,因为我们手头没有定义 ESB 是什么或应该怎样的标准。我们看到的每个 ESB 产品都是独特的……并且很难与另一个 ESB 兼容。)
因此,ESB 产品通常包含若干个引擎,它们可供请求者和接收者通过 Web 接口进行访问(不排除有些 ESB 产品还可能支持其他交互接口)。我所参考的是 Microsoft 的面向 Biztalk 的 ESB 开发工具箱中介绍 ESB 产品的特性,如表 1所示。
序号
ESB 特性
挑战
1
智能消息路由
“动态路由,基于内容的和基于路线的运行时路由,或者基于内容的消息路由。”
ESB 产品不仅能提供基于内容和消息的上下文(该信息一般不能事先预计)的路由,还能以消息发送方和接受方所不知的任何其他手段以及规则进行路由。人们坚信分发消息相干的职责是专属于 ESB 产品的。该特性源自发布 / 订阅和 MOM 系统,在这些系统中,发送方不知道接受方是谁,接受方也不知道谁请求了它的服务。
我想知道它们是怎样的业务用户和业务服务,它们不知道对方是谁,也根本不想知道。的确在某些场景中存在“中间人”这种角色,但是交互的双方相互之间非常了解(如“邮政服务”),或者中间人成了业务的一部分(如,专递服务)。
反对我的人可能会说 ESB 产品的工作是整合技术组件,不需要了解“业务规则”。我同意这种说法,只不过需要补充一点:基于此,ESB 产品就不应该支持业务服务(也包含其技术部分)的交互,因为业务消费者与服务之间需要相互了解。
2
动态数据转换
“动态数据转换和翻译,不同消息格式或消息语义间的映射的定义是在运行时被解析的。”
为实现动态数据转换,ESB 产品需要知道输入数据和输出数据的格式。然而有时候,尤其在实际工作中,输入数据是不完整的。这不成问题——因为 ESB 产品能够校验数据并从别处获得缺失的数据。很好!但是校验规则可能很快就跟不上交互策略的变化(因为 ESB 是 IT 基础架构层面的设施),特别当 ESB 由另一团队“掌管”时。
同样,如果 ESB 产品是服务消费者与业务服务间交互的“优等公民”的话,那么它必须承担业务职能。如果 ESB 产品只翻译交换双方的数据格式的话,那么 ESB 必须成为对服务消费者及(服务契约中所描述的)提供者双方负责的可信赖的翻译器。如果 ESB 产品足够高级,能够丰富消息,那么它就成了业务交易的一部分,而且必须符合所有业务规则 / 制度和安全认证和授权控制等。
例如,如果请求数据不完整,并且 ESB 产品所使用的其他数据源,在服务契约(Service Contract)中没有提及,那么消费者也许不能使用该数据源,若是这样,那么 ESB 支持团队就碰到问题了。相反,如果该数据源在服务契约(Service Contract)中明确地说明了,那么消费者为何选择 ESB 产品作为数据收集者,而不是事先通过另一服务来获得这部分数据呢?让人费解!
3
安全切入点和安全控制
人们认为 ESB 产品处于执行安全控制的有利位置。安全控制可包括消费者和服务认证,特定交互的授权 / 许可以及信息加密等 。
我不太清楚这是为什么,但是对我来说,在 ESB 中加入该特性应该是某些市场人员的主意;这不可能是安全专家的想法,因为这种“做法”违反了“安全 101 规定”。
多数研究者发现 75% 到 80% 的安全违例都发生在公司内部,而非企业周边。如果 ESB 是核心的交互协调者,那么恶意请求怎么可能没有通过检查而破坏核心系统呢?在 ESB 产品中处理请求者 / 响应者认证和授权控制已经为时已晚了……但是它的确方便了开发者,譬如,缩短了交付代码所需的时间。
以下安全违例在 IT 中非常普遍。许多开发者或架构师认为,即便他们所代替的用户并没有权限访问这些数据,他们也可以代替用户从存储库中获取数据。之后在内存中对获取到的数据进行过滤,所以该用户不会看到受限的数据,但是系统内存中的数据却失去了保护,也就可能被恶意程序轻易地截获。
4
运行时动态发现端点和端点虚拟化
“服务消费者不需要感知服务提供者的位置和端点的细节;人们可以轻易地向 ESB 添加新服务提供者,或更新服务提供者,而不会影响到服务消费者。”
该特性不同于“动态路由”特性,在这里,服务发送者和发送者也许知道对方是谁,但却不知道它们的实际端点。
端点虚拟化只有用于分离业务服务和服务消费者时才算是不错的实施方式。在 Web 技术中,向所有的网站客户暴露一个端口,并且在此门面的背后却配置了许多内部端口,该方法就是虚拟化的一个很好的证明。
就运行时发现而言,我认为,如果我们谈论的动态发现所发现的是上述提到的内部端口,那这的确是没有问题的。倘若“发现”指的是发现消费者并不知情的服务或服务提供者的话,那么我不建议这么做,除非你忽视“业务的约定”。
5
松耦合服务组合
“服务提供者和服务消费者无需感知服务的交互形式”
实际上,这段解释已经违背了微软的实施:ESB 产品能够执行多种执行路线,而且,为了制定特定的处理路线,核心处理引擎要求每个消息包含处理指示(process instruction),或者定义处理路线的元数据以及应用于消息内容的任务。因此,服务消费者必须对交互形式非常清楚,相反却无需了解前文所提到的服务(译者注:这里的服务指得是 ESB 产品所调用的后台服务)。
6
集中异常管理
“有了异常管理框架,服务和基础设施元素,服务消费者或 BizTalk 组件就能够创建、修复、再提交异常消息以及执行补偿。”
对于高度集中的系统这是一个非常有益的想法,但它却无法在分布式环境下工作。
这类集中式系统要求 ESB 产品独占地负责异常管理框架。此外,它的构建基于如下前提假设,一切(包括服务和服务消费者)必须通过 ESB 来交互。我称它为“分布式计算下的桌面思维模式”。
为了“创建、修复、再提交异常信息并执行补偿”,ESB 产品必须知晓所有服务提供者和消费者的消息细节。另外,它还必须了解规定消息修复规则和再提交机制的服务消费者的服务契约(Service Contract)。你曾见过这样的 ESB 产品吗?
7
协议转换
“为服务提供者与服务消费者提供跨各种不同协议的交互能力,其中包括 Web 服务的各种 WS-* 标准。
例如,某服务消费者可能递交一份基于 HTTP 的 Web 服务请求,由此而产生一条发往消息队列的消息。”
该陈述听起来更像是“整合”而非面向服务。
众所周知,消费者在与 SOA 业务服务交互时可能使用到的所有服务接口及协议都应列在服务契约(Service Contract)之中。如果服务消费者不能使用某个特定服务,它为何还要签订服务契约(Service Contract)呢?不过,我们倒是可以假定消费者希望通过某个中介,即 ESB 产品,来使用协定的交互协议。这种约定完全由服务消费者掌握,服务提供者一无所知,也不需要关心 ESB。所以,所使用的 ESB 产品成了服务的消费者,所以也必须符合服务契约(Service Contract)。因此,服务与消费者之间永远要使用服务契约(Service Contract)中协定的协议。
我尤其难以理解左边给出的示例,服务消费者发送 HTTP 请求时希望得到服务的即时响应。而与此同时,服务通过消息机制却无法保证即时给出回应,它是一个异步接口,响应时间也无法得到保障。
8
服务质量
“异步的发布 / 订阅引擎实现了多种级别的服务可用性,提供了 ESB 实现的高可用性、伸缩性、以及消息可跟踪性。”
这里的服务质量由 ESB 产品提供的,但它与 SOA 中的业务服务的质量不一定相关。
9
扩展性
“为运行时以及设计时进行端点发现、消息路由和更多 BizTalk 服务适配提供多处功能扩展点。”
ESB 产品若失去了增加更多端口和服务发现能力的话,它就是一个能力非常局限的“总线”。然而,单就“端口发现功能”的扩展而言,虽然使用增加新端点的方式增加业务功能是人们推荐的方法,但这只是新增业务功能的可选方法之一。不论如何,上述“扩展点”不足以宣称ESB 模式和相关产品提供了SOA 的扩展性。在SOA 中,扩展性可能通过其他方式得到,譬如,编排或对交换的消息的格式扩展等。
表1.
ESB 产品的某些特性用在面向服务的环境中更为准确,另外一些则有不那么合适,这些都是次要的。但是,在我看来,真正让 ESB 产品称为“定时炸弹”的特性是:介于业务服务和业务消费者之间的仲裁特性。我总结了以业务为中心的 SO 环境不适合使用 OO 的仲裁模式的三个主要原因。
首先是分布式授权,在 OO 设计中使用仲裁模式时,从来不需要考虑这种分布式的情况,仲裁模式的使用总是基于这样的假设,开发人员可以完全控制所有对象,他所要做的事情是简化对象与对象之间的关系。可是,在SOA 中,即便在同一个企业中,有时也不能保证单点授权。譬如,我们有两个业务服务A 和B,它们分别包含业务服务α和β,这两个服务必须以“消费者服务”的形式进行交互。由于A 和B 隶属于不同的部门,所以其所有者及使用权限也不同。这意味着要编制A-B/α-β交互的开发者可能受到不同业务策略的限制和制约。打个比方,A 和B 的业务所有者都知道ESB 产品由IT 部门全权掌控。虽然A 服务的所有者对此没有问题,但是B 服务的所有者可能不同意让B/β服务依赖于“不受业务控制的”IT 基础设施。基于这种业务情形,开发人员就(有可能)不能修改β以将它作为ESB 的端点(end-point),所以也就不能访问它。
第二个原因是SOA 服务的提供者与消费者之间的强制性服务契约(Service Contract)。除了其他方面之外,服务契约(Service Contract)还定了服务接口(包括协议)和SOA 服务交互过程中需访问并应用的策略等。我们列举一下ESB 产品对于服务契约(Service Contract)的可选做法:1)ESB 独立管理并授权;2)ESB 作为消费者域的一部分;3)ESB 作为服务域的一部分。
第一种情况,ESB 产品不应该这样使用,因为它违反了服务契约(Service Contract):服务契约中不会提到任何ESB 端点、交互协议以及ESB 策略。第二种情况,ESB 产品可能由服务消费者使用,但是ESB 产品必须代替服务消费者而存在(拿这消费者的身份,遵守服务契约(Service Contract)中指定的接口和协议),有这样的ESB 产品吗?最后,在第三种情况下,服务提供者可以将ESB 的服务接口和策略称作WSDL 文档中的SOA 服务的接口与策略,并在服务契约(Service Contract)文档中引用它们。因此,消费者不会知道他是与ESB 产品进行交互的。
看起来第三种情况明确了ESB 产品在以服务为中心的SO 环境中的定位。但是,别着急。你可曾见过服务提供者同意将ESB 整合到其服务域中(包括相关SLA 和其他业务职能)的先例吗?此外,在ESB 上开发的与不同(ESB 或SOA 服务)业务所有者相关的执行路线由谁负责呢?这不是个小问题。
第三种情况是业务交互中的中间人的角色。如果中间人介于业务服务与消费者之间,它必须承载业务交互中特定的业务职能。如果它失败了,就应接受业务惩罚。因此,对于此在业务交易占据中间人的位置的技术性基础设施,它该担当那些业务职能,拥有何种业务权利?如果不能为它找到合适的定位,迟早它会开始驱动业务。
下面我们来分析一个假想的案例。有一工厂A 和一供应商X。工厂A 雇佣了一个司机,要求他从供应商X 处运送零件到工厂,不过如何运输则由司机自行决定。这个司机非常聪明——他/ 她找到了运输这些零件最佳路径。后来,工厂A 又联系了另一供应商Y,同样要求司机有自己决定从X 或者Y 运送零件。一直以来,这都没有任何问题。现在,工厂A 开了一家分工厂B,还是雇佣该司机为A 和B 送货——司机需要找到获取和运送零件的最佳方案。最后,工厂A 似乎拿不到零件,因为司机大多数时间更喜欢把零件运往B 工厂,因为……B 离家更近。这种情况的发生是有可能的,因为司机并没有参与到业务流程中,也就没有业务职责。
不幸的是,上述例子并非空穴来风——微软的咨询顾问建议将ESB 当作企业中SOA 服务的唯一交互基础设施。那么,上述三种ESB 产品/ 模式与企业SOA 业务服务不匹配的情况他们都将碰到。
SOA 的主要业务价值之一是组合——通过再聚合 / 编排现有业务服务的方式灵活地应对业务变化。这要求业务服务必须最大程度地“活动”才能穿插到不同的编排之中。如果 IT 使用 ESB 产品连接业务服务和服务消费者,那么,起初看起来还没有问题,但是,由于所有交互都经过 ESB,服务间的交互越复杂(即服务参与的编排越来越多),它成为运行瓶颈和单点故障的可能性就越大。再者,好几个厂商因频繁地强制升级产品或做出不能向后兼容的产品更新而著称,ESB 产品当然也不例外。如果 ESB 产品是业务服务系统的核心,此类更新就会变得非常昂贵和耗时。而且你猜,谁会为造成的错误负责?没错,是你的 IT,而不是厂商。
何去何从
如今,一些 IT 领袖意识到,如金融业(主要是银行业)、电信业、媒体、医疗保健和其他非制造业,拥有大量的消费者与客户,若要取得进步和成功,就得依靠企业与其 IT 团队和和谐共处。众所周知的企业需要实现 IT 与业务的敏捷的事实见证了二者间的问题,“因为IT 组织与业务对其技术的期望越来越远了。”
在我看来,ESB 模式的内部就存在矛盾,当这些模式通过ESB 产品实现时,这些矛盾越发显得明显。最明显的疑惑应当是SOAPatterns.org 上给出的企业服务总线模式的定义;从《SOA 设计模式》一书来看,该模式的定义的确不仅限于“企业服务总线代表了一个能促进服务间复杂的互联的环境,它建立了中间处理层,有助于解决可靠性、延伸性和交互差异性等相关问题”。该模式只不过是一组技术,而不是关于如何使用这些技术或哪些情况下该(或不该)使用它们的手册。Thomas Rischbeck 说到,“ ESB 模式关心的是整合任务,在 SOA 中,它为对参与者完全透明的客户- 服务的交互带来了价值”。如果这种透明性不依赖于智能路由和数据丰富,而是一组与参与者交互相关的自有规则,那我还是很乐意接受的。在SOA 中,我们有一种约束交互的机制——服务契约(Service Contract)——可是ESB 似乎根本不把它放在眼里。
与此同时,正如前文提到的,ESB 模式是一组模式的组合。有这样一个模式可以展现多种视图固然很好,但是这些视图应该是一致的——可是,我们有一个仲裁者模式,它有助于相互了解的双方之间的交互逻辑;另一个则是发布订阅模式,而该模式却建议交互双方互不了解。
恐怕ESB 模式唯一的好处是隔离了业务服务和消费者。尽管没有发布订阅模式,在业务控制之外的ESB 产品的存在(因为它作为基础设施而存在)也分离了业务服务和业务消费者。因此,在认识了所有上述言论之后,ESB 产品还有积极的业务价值吗?
事实上是有的。而且,不论你信还是不信,该价值源自ESB 模式包括的另一模式,即适配器模式。其价值是一组面向多平台和多交互协议的适配器。为了实现这一点,消息系统必须实现与各种异构系统之间的物理连接。ESB 产品继承了这一适配层,因此能在技术整合层将业务消费者连接到业务服务。没错 ,我说的是“连接”,而不是“取代”交互的业务逻辑;ESB 产品也许会严格地依据服务契约(Service Contract)进行“连接”。
所以,ESB 模式和产品的业务价值与SOA 并不相干,但是却与过去在IT 基础设施方面的投资以及适配器的投资有关。在SOA 中,在业务服务领域,只有当ESB 产品产品成为业务服务或业务消费者的一部分时,比如管控并操作ESB 的业务实体承担业务职能时,才能实现其透明性。
总结——带走这些思考
我们谈论了门面模式和ESB 模式随着应用环境的变化而产生的不太明显的用法上的改变。对于门面模式,我们发现当该模式应用与对象、组件及服务时,其模式语义一直在改变。更准确地说,在SO 环境中,门面与服务接口融合于一体,门面模式融入了聚集服务。
ESB 模式更艰难、更危险的处境根源于仲裁模式与发布订阅模式的合并。因为 ESB 模式实现在 ESB 产品之中,所以当产品应用于业务服务时也继承了两个基础模式的矛盾之处。尤其是当 ESB 中的仲裁开始扮演独立角色,占据了除基本的路由功能之外的业务交互逻辑时,它就可能会破坏(服务提供者与消费者间的)服务契约(Service Contract)中的基本业务概念。直接地说,机械地将裁者 - 发布订阅模式的组合提升到业务提供者 - 消费者关系的层面是不可能的,除非作为中间人的 ESB 能像业务实体一样承担业务职能。由于 ESB 产品并不接受业务职能,这样的产品就不应该为业务服务所见,比如,他们必须成为服务的一部分或服务消费者的一部分 。只有这样,ESB 产品才能融入业务服务间的交互之中。
另外,若在服务契约(Service Contract)中没有明确地记录服务与服务消费者之间的相互了解,则 ESB 产品就不应该承担交互中数据转换的任务。出于安全控制的原因,ESB 产品本身被看作是安全的,但是当其用作某个服务交互的切入点,用作对交互参与者进行认证和授权,这是违背基本的安全规则的做法(非授权请求不可能穿透到核心系统的路由环境之中,在此之前就应已被拦截了)。
最后,文章总结到,ESB 产品常常提供的丰富的适配层,使得业务服务和服务消费者之间的技术整合成为可能。只要 ESB 产品不根据某些业务面不可控的规则和策略完成一些所谓“智能”路由时,它就是 SO 环境中最有价值的 ESB 特性。
最后,我将通过对一个著名谚语的重新解释来总结本文,该谚语如是说:业务服务的世界何时才能实现与业务一致。不论 IT 部门为业务服务带来何种技术解决方案,它都不应该改变业务的“规则约定”。如果某个技术方案的确改变了这些规则,那么它将不可避免地造成业务和 IT 之间真正的裂缝;若不是现在,则是不久的将来。
关于作者
过去十年间,Michael Poulin 博士一直从金融行业中担任企业级解决方案架构师的工作。他取得了 Java、TOGAF 和 SOA 等方面的架构师认证,也还在 2001 年世界 IT 名人堂中的一员。自 2007 年开始,他一直是 OASIS SOA 参考模型技术委员的一员,并参与起草了 OASIS SOA 参考架构的第一、第二次公众评阅稿。他著有《Ladder to SOE: How to Create Resourceful and Efficient Solutions for Market Changes within Business and Technology》一书;目前担任咨询公司 BuTechCon 的业务和技术架构主管一职。
查看英文原文: Patterns In The Context of SOA Business Services
感谢吴宇对本文的审校。
给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家加入到 InfoQ 中文站用户讨论组中与我们的编辑和其他读者朋友交流。
评论