前言
谈及企业服务总线(ESB),在有面向服务的架构(SOA)实施经验的开发者眼中一定不会陌生。这些年,人们一直在谈论它,以至有些人认为“实施 SOA 一定需要 ESB”,或“只要将 ESB 架起来了,我们就 SOA 了”。这些说法有可取之处,也存在片面之嫌,由于业界对于 ESB 没有统一、标准的定义,所以一千个人眼中有一千个“ESB”也就成了情理中的事情了。然而,怎么才能将 ESB 用好?我们需要清楚地认识 ESB 在 SOA 中所扮演的角色,理解哪些工作是 ESB 的职责之内,哪些却不是。只有正确地认识了 ESB 的职能,并委以恰当的任务,才能将它用在刀刃上、发挥其巨大的能量。
本文是这样安排的:
第一部分,简单介绍 ESB 在 SOA 中所起的作用。
第二部分:介绍三种常见的 ESB 的误用。
第三部分,介绍三种推荐实施。
第四部分,对 ESB 产品发展方向的展望。
申明:文中的出现所有观点仅代表作者个人看法,不代表作者所供职公司的观点。
正确理解 ESB 在 SOA 中的作用
平心而论,ESB 的确是 SOA 中一个非常重要的集成层组件(Integration Layer),不论是 OpenGroup 发布的 SOA 参考架构,还是几大主流 SOA 供应商(参考 IBM 通过参考架构实施 SOA 解决方案 , Oracle 与 F5 的 SOA 参考架构, Microsoft 的 BizTalk ESB Toolkit 中对 ESB 的定义),都将 ESB 置于 SOA 架构的核心位置。
事实上,ESB 在 SOA 中扮演着重要的角色,在技术层解决了 SOA 的整合问题,耦合了应用与应用之间的集成逻辑,使得 SOA 更灵活,更易于扩展,更敏捷。有了 ESB,新建的服务消费者应用程序不需要关心服务的提供者在哪里,使用何种通讯协议,与其交互的数据是怎样的……,它只需向 ESB 发出请求,使用开放的、标准的通讯协议。相反,若某个可重用的价值较大的服务位于某一个遗留系统中,而由于种种原因,该遗留系统不能在短期内重写,此时 ESB 可以架起该服务与其使用者之间沟通的桥梁。当然,ESB 的作用远不止这些,业内也有很多讨论,本文不再赘述。读者可在 Google 上搜索 ESB Patterns 获得相关资料。
然而,ESB 并非“救世主”,它注定也不可能解决应用系统整合中出现的所有问题。道理很简单,计算机发展历史长从没有出现过一个产品 / 工具可以满足所有的应用需求,技术发展得很快,需求发展更快,所以技术永远跟不上需求。此外,ESB 或 ESB 产品有其特定的适用范围,它是基础设施层的概念 / 产品,解决的是整合中的常见问题,比如服务连通、路由、消息丰富、服务的注册 / 查找 / 发布等服务的管理、服务监控和质量保证等。ESB 不能解决的问题比其能解决的问题多很多。比如,让它去做人工流程的编排是不合适的,让它提供门户类产品那样的用户交互也是极其困难的……。
笔者支持过许多客户项目。在这些项目中,有的客户将 ESB 用的好,有的则勉强用上,用的功能很简单,有的则用 ESB 做一些原本不属于它该做的工作。在这里,笔者仅从个人的立场,分享自己这些年来积累的 ESB 实施经验。下面列出笔者常看到但不推荐的实施和笔者在实施 ESB 的过程中积累的一些较好的实践方式,供读者参考。同时欢迎批评指正。
不推荐实施
挟 ESB 以令外围应用
-
现象:ESB 的架构师在 ESB 上设计一套标准的数据接口(通用的 XML 格式),规定使用统一的协议(如 Web Service/HTTP)。所有的 ESB 服务消费者和接入 ESB 的服务必须符合该标准。其目的是为了简化 ESB 上的开发工作。这就是一种“挟天子以令诸侯”的做法,因为在实际情况中,可能领导规定了“所有的服务必须要经过 ESB,即便是透传”。
-
分析:国内的 ESB 实施者大多数是一些 SI/ISV,出于成本 / 人力或其他个方面的原因,总会有一些架构师希望达成这样一个目标:我能否设计 / 实现一个一劳永逸的 ESB 中间平台,将来不论哪种服务都可以方便地接入到 ESB 上?
这是一个很浪漫很理想的目标,但这个目标是不可能实现的。原因有二:其一,仲裁逻辑一般是非常具体的,具体的服务有具体的整合需求。譬如,一个服务提供者基于 HTTP 提供了一个 Web 服务 WS1,而我们希望将这个服务通过 ESB 暴露给两个客户端 ClientA,Client B;Client A 使用 XML/HTTP 访问服务,而 Client B 却使用 SOAP/JMS 访问该服务,如图 1 所示。有过 ESB 实施经验的人都能看出里面的仲裁逻辑是非常具体的,我们要考虑的不仅仅是协议之间的差别,还需要考虑消息格式的差别。其二,如果有这样的设计 / 实现存在,ESB 产商为何不把这个特性直接实现了呢?你也许会说产商不理解具体的业务,而具体的业务是复杂的,SI/ISV 却了解这些复杂业务。而事实上,ESB 解决的更多是技术层面的工作,业务层面的工作大多数不属于 ESB 的范畴,复杂的业务逻辑不是在业务系统中实现,就是在其它 SOA 组件中实现,如流程管理引擎。
图 1. ESB 的主要功能之一是连接异构协议和数据。
-
原因及危害:该实践出现的根本原因是:没有认清 ESB 本身的作用,过分看重了 ESB 之上的设计能力。其实,ESB 针对的是一个个功能各异的整合逻辑,服务之间的整合逻辑也是迥异的。所以,一劳永逸的 ESB 之上的架构是不存在的。
其危害是:丢失了 ESB 本身最强大的连通性方面的功能,正式因为需要联通的应用之间的差异性,才逐渐发展出了 ESB 这样的组件。如果要求所有的外围应用的协议标准和数据标准都统一了(事实上,这是不可能实现的,特别在与第三方应用整合时),那么 ESB 的必要性就逊色不少。
-
建议:不要试图实现一个一劳永逸的 ESB 之上的架构,这个架构不存在也没有其存在的必要性。不过,笔者并非反对设计。实际上,ESB 上可以设计,也可以通过一定的设计实现某种程度的自动化,灵活性和通用性。举个例子,某一组功能类似的服务,对这一组服务的所有请求必须进行审计、安全加固等操作,对于这一类需求,我们可以事先在 ESB 上设计好相应的技术组件 / 服务,然后在 ESB 的仲裁流中间调用该组件 / 服务即可。
用 ESB 实现业务流程
-
现象:有些架构师看到 ESB 支持服务组合(Service Composition)模式,进而认为可用该模式来实现业务流程。因此,ESB 产品就演变成了 BPM 产品。
-
分析:如果读者关心过 ESB 的通用使用模式,就会发现 ESB 的服务组合模式(Service Composition)与 BPM 中的服务编排(Service Cherography)非常相似,二者都是将细粒度的服务组合 / 组装起来,形成大粒度的服务,或者业务流程。
事实上,二者有着本质的区别。其一:ESB 是一个偏向技术层整合的组件,比如将“客户资料查询”服务与“日志”服务组装起来,得到的结果还是“客户资料查询”服务,只是在仲裁流中间插入了一个新的附加功能,即“日志”服务。BPM 中的服务编排的含义很侧重于业务流转的概念。比如“项目立项审批流程”,该流程的实现可能需要来自几个相关系统中的服务的参与,它们可能是“立项申请”,接着是“一级职能经历审批”,然后是“部门经理审批”,“财务审批”等。这些服务流转起来形成的是一个完整的业务流程。其二:ESB 上的服务组合是无状态的,ESB 运行时会为每个请求建立一个实例来执行其仲裁逻辑,请求与请求之间没有时序关系,是互不相干的、各自独立的。相反,BPM 上的服务编排这不一样,未完成的业务流程实例一直会存活在 BPM 运行时中,存活期可能为一天、一周、甚至 1 个月或更长;请求与请求之间可能存在着一定的关联性,比如对与一个项目(相同的项目 ID)的立项审批流程,一级职能经理、部门经理和财务对流程发出的请求都是针对同一运行时实例的。
-
原因及危害:除了其他非技术的因素外,导致该实践的一个重要原因是:混淆了 ESB 的服务组合与 BPM 的服务编排两个概念。
危害:让 ESB 实现 BPM,特别是长运行的流程时,虽然在技术上可以实现,但是这违背了 ESB 产品的设计理念,会大大影响其 ESB 运行时的整体运行效率。
-
建议:认清技术上的服务组合与服务编排之间的差异,分析每个产品所属的概念范畴,选择合适的产品解决合适的问题。
用 ESB 实现大数据传输
-
现象:将 ESB 用于在两个系统间传输大量数据,比如传输视频文件、大文档等。在这些场景中传输的信息 / 文件 / 消息有一个共同的特点:只使用了 ESB 提供的连通性功能,而没有使用其他功能,如消息解析,转换,路由等。
-
分析:为了在 ESB 市场上抢占有利位置,各大厂商提供的 ESB 产品的能力越来越强。ESB 产品的设计是支持消息从一个系统传到另一个或几个系统的。所以,一些架构师利用 ESB 产品本身提供的此项功能架设了一个数据传输总线。
可是 ESB 并不适合完成该项功能,虽然它可以实现这一功能,但这并非最佳实践。ESB 作为企业级的服务联通、管理平台,需要穿透 ESB 的服务应该是企业内重用可能最大、价值最大的那些服务,应用程序对这类服务的访问应该非常频繁,因此同一时刻需要 ESB 支撑的业务可能非常繁重。所以,ESB 产品的设计初衷是实现一个无状态、高吞吐的服务总线,为企业内重要的业务服务提供透明、标准、开放的接入能力。
-
原因及危害:这种实践的原因是过分放大了 ESB 对数据的传输能力,如果在 ESB 传输巨大的信息,可能会导致 ESB 整体性能的下降,损害其他重要服务的 QoS。
-
建议:如果需要传输的数据有解析或转换的需求、或者需要根据数据里的信息进行某种路由或其他仲裁逻辑需求时,则建议使用 ESB;但如果同时消息体又过与庞大,可以考虑将需要解析的消息与不需解析的数据部分进行拆分,通过其他专门的数据传输平台去传输不需解析的部分,如 FTP,数据库备份机制等,而在 ESB 中实现该传输任务的控制流。
推荐实施
服务要管理起来
ESB 的一个重要功能是将企业内 / 合作伙伴处的服务以开放的、标准的服务方式暴露出来,使得服务消费者能够便利地查找到服务,以促进服务的重用、管理。而许多 ESB 产品不包含服务的注册、存储、发布、订阅等功能,这些功能包含 UDDI 库中。所以,ESB 一般需要一个服务注册 / 存储库与之协作。ESB 执行各种仲裁逻辑,而注册库为 ESB 提供必要的元数据信息。
服务注册库可以存储服务的元数据,包括服务的描述、功能、版本、输入 / 输出消息的模式、服务端点、SLA、安全策略等内容,这些信息可被 ESB 用来进行消息格式验证、服务的动态路由、执行安全策略和 SLA 保证等。
ESB 可以多级实施,可以实现整个企业级 / 全国级的 ESB,也可以实现部门级 / 地市级的 ESB。服务消费者应该能在注册库中找到自己所需要的服务,获得调用该服务所需的位置、服务的描述文件、请求 / 相应消息格式等信息。若是没有注册库,则随着 ESB 接入的服务越来越多,仲裁逻辑不断增加,必将造成服务管理的混乱。最后抵消了 ESB 带来的价值。
复杂的动态路由规则应服务化
路由是 ESB 中非常重要的仲裁逻辑之一。路由场景是非常普遍的。譬如,针对不同的客户提供不同 QoS 的场景,执行时需根据客户的类型将其路由到不同执行能力的服务提供者;再比如当响应消息到达 ESB 时,总是需要将该响应消息送回最初的服务请求者处。
路由可分为静态路由和动态路由。静态路由指得是设计时已经明确路由分支的情况,而动态路由的路由分支选择是在运行时动态确定的。不论是静态路由还是动态路由,路由分支的选择一定伴随着一个或一系列决策依据。决策依据可简单如一个 If-Else 语句,也可以复杂到需要通过多维决策表并通过多次判断才能得到最后的路由分支。
对于复杂的路由,推荐将路由规则的逻辑外部化,并将它服务化,如图 2 所示。如此,仲裁逻辑在分发消息前可先访问该路由规则服务,从而得到明确的路由结果。至此,可能有人会问到,“复杂”与“简单”如何界定。这个问题没有统一的规定,根据笔者以往的实施经验,如果符合以下条件之一,就可以认为是复杂的路由规则:
- 判断维度大于等于 2
- 连续决策节点大于等于 3
- 路由分支可能随时增加或减少
图 2. 动态路由规则服务化。
将复杂的动态路由规则服务化的好处简单明了。首先,让复杂的规则服务化,可以降低仲裁逻辑的变化性。当规则发生改变时,不需要修改仲裁逻辑,而只需更改规则服务即可。进一步,如果该规则服务是由某种专业的规则引擎实现的,更改起来将更加简单。其二,由于 ESB 产品的实现与设计并无业界的标准,所以基于 ESB 产品的配置开发无法在不同产品间互相移植。将规则服务化之后,还可减少仲裁逻辑在不同的 ESB 产品间移植时所需的工作量。最后,规则的服务化符合 SOA 原则,企业内业务规则应该以服务的形式管理起来,以促进规则的重用。
转换逻辑的实现尽量选用 XSLT
数据转换也是仲裁逻辑中非常常见并且重要的功能。同一数据在不同的业务系统中表现方式可能不一样,如上文例子中的 Client A 访问服务 WS1 的情况,仲裁逻辑需要将 XML 消息转换为调用服务 A 的 SOAP 消息。
一般而言,大多数 ESB 产品都提供了多种数据转换的方式,很多产商宣传中力推的都是“拖拽式”可视化映射的转换方式。该功能听起来的确很酷,看上去很直观。但是正如我们前面所说的,ESB 是一个偏向技术层整合的组件,业务人员一般不会关心 XML 是如何转换成 SOAP 的。所以,对于开发者来说,这种“炫”功能并无太大吸引力。更重要的是,他们可能非常习惯于自己的编程语言,如 Java、XSLT、ESQL 和 PHP 等,这些语言操作起来要简单很多。笔者本人就不太喜欢使用可视化隐射的方式去实现数据转换的需求,尤其碰到需要循环运行、复杂计算等转换逻辑时,在可视化映射上实现起来更加不容易。
在此,笔者推荐的方式是使用 XSLT 实现数据转换的功能,如图 3 所示。原因如下:首先,XSLT 是一个标准的 XML 转换语言,使用 XSLT 实现的转换逻辑可很轻易地在不同 ESB 产品间移植。据笔者调查,几乎所有主流商业 ESB 产品都支持 XSLT 的转换机制。其二,选择 XSLT 还可增加 ESB 之上的架构灵活性。因为仲裁逻辑中的转换逻辑是最计算密集型的逻辑,它最消耗 CPU,影响整体性能。在这种架构中,我们很容易地将此转换逻辑剥离出仲裁逻辑,由一些专门的 XML 转换加速软件 / 硬件(如 IBM WebSphere DataPower)来完成这一工作。这样的设计可提高架构的灵活性,通过分布式计算的方式提高整体计算性能。
图 3. XSLT 实现数据转换逻辑及架构扩展
展望
在 SOA 架构中,ESB 扮演的重要角色是毋庸置疑的。随着企业架构的不断演变和进化,ESB 也不能一层不变。它只有与时俱进,才能顺应技术和思想的发展和进步。随着 RESTful Web 服务的兴起,SOAP 服务不再是最受宠爱的标准;SOA 架构也在不断突破企业防火墙,延伸到云计算的世界里。在这样的历史大环境下,ESB 至少要需要以下向两个方向发展,才能在竞争中立于不败之地,否则就可能被新产品所替代。
首先,ESB 需加强对 RESTful Web 服务的整合支持。RESTFul Web 服务相比于 SOAP 服务有着简单、易学、易扩展等方面的优势。将 RESTFul Web 服务作为 SOA 的基础构建元素的呼声非常高。虽然不通过 HTTP 传输的服务无法转变成 RESTFul 服务,但是这种对 RESTFul 服务的呼声至少代表了人们向往简单的愿望。笔者认为这种趋势不可逆转,ESB 产品必须加强对 RESTFul 服务的整合支持。譬如,可通过 ESB 将后台遗留的 MQ 应用的功能转变成一个 RESTFul 的服务,供 RESTFul 客户端访问。
其次,ESB 需加强与 SaaS 云应用的整合支持。随着云计算的铺天盖地席卷而来,人们对云的认识越来越清晰,对云计算经济越来越认可,云端应用变得炙手可热。在 SaaS 应用越来越受到热门的欢迎同时,出于安全、性能、已投资资产等方面的原因,企业不可能将所有的数据 / 应用部署在云端,所以本地应用与云端 SaaS 应用之间的整合必将成为未来几年最热的集成需求,这就催生了笔者对 ESB 第二个方面的展望。
给 InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家加入到 InfoQ 中文站用户讨论组中与我们的编辑和其他读者朋友交流。
评论 1 条评论