3. 构建SOA架构时应该注意的问题
3.1 原有系统架构中的集成需求
当架构师基于SOA来构建一个企业级的系统架构的时候,一定要注意对原有系统架构中的集成需求进行细致的分析和整理。我们都知道,面向服务的体系结构是当前及未来应用程序系统开发的重点,面向服务的体系结构本质上来说是一种具有特殊性质的体系结构,它由具有互操作性和位置透明的组件集成构建并互连而成。基于SOA的企业系统架构通常都是在现有系统架构投资的基础上发展起来的,我们并不需要彻底重新开发全部的子系统;SOA可以通过利用当前系统已有的资源(开发人员、软件语言、硬件平台、数据库和应用程序)来重复利用系统中现有的系统和资源。SOA是一种可适应的、灵活的体系结构类型,基于SOA构建的系统架构可以在系统的开发和维护中缩短产品上市时间,因而可以降低企业系统开发的成本和风险。因此,当SOA架构师遇到一个十分复杂的企业系统时,首先考虑的应该是如何重用已有的投资而不是替换遗留系统,因为如果考虑到有限的预算,整体系统替换的成本是十分高昂的。
当SOA架构师分析原有系统中的集成需求的时候,不应该只限定为基于组件构建的已有应用程序的集成,真正的集成比这要宽泛得多。在分析和评估一个已有系统体系结构的集成需求时,我们必须考虑一些更加具体的集成的类型,这主要包括以下几个方面:应用程序集成的需求,终端用户界面集成的需求,流程集成的需求以及已有系统信息集成的需求。当SOA架构师分析和评估现有系统中所有可能的集成需求的时候,我们可以发现实际上所有集成方式在任何种类的企业中都有一定程度的体现。针对不同的企业类型,这些集成方式可能是简化的,或者没有明确地进行定义的。因而,SOA架构师在着手设计新的体系结构框架时,必须要全面的考虑所有可能的集成需求。例如,在一些类型的企业系统环境中可能只有很少的数据源类型,因此,系统中对消息集成的需求就可能会很简单,但在一些特定的系统中,例如航运系统中的EDI(Electronic Data Interchange 电子数据交换)系统,会有大量的电子数据交换处理的需求,因此也就会存在很多不同的数据源类型,在这种情况下整个系统对于消息数据的集成需求就会比较复杂。因此,如果SOA架构师希望所构建的系统架构能够随着企业的成长和变化成功地继续得以保持,则整个系统构架中的集成功能就应该由服务提供,而不是由特定的应用程序来完成。
3.2 服务粒度的控制以及无状态服务的设计
当SOA架构师构建一个企业级的SOA系统架构的时候,关于系统中最重要的元素,也就是SOA系统中的服务的构建有两点需要特别注意的地方:首先是对于服务粒度的控制,另外就是对于无状态服务的设计。
服务粒度的控制
SOA系统中的服务粒度的控制是一项十分重要的设计任务。通常来说,对于将暴露在整个系统外部的服务推荐使用粗粒度的接口,而相对较细粒度的服务接口通常用于企业系统架构的内部。从技术上讲,粗粒度的服务接口可能是一个特定服务的完整执行,而细粒度的服务接口可能是实现这个粗粒度服务接口的具体的内部操作。 举个例子来说,对于一个基于SOA架构的网上商店来说,粗粒度的服务可能就是暴露给外部用户使用的提交购买表单的操作,而系统内部的细粒度的服务可能就是实现这个提交购买表单服务的一系列的内部服务,比如说创建购买记录,设置客户地址,更新数据库等一系列的操作。虽然细粒度的接口能为服务请求者提供了更加细化和更多的灵活性,但同时也意味着引入较难控制的交互模式易变性,也就是说服务的交互模式可能随着不同的服务请求者而不同。如果我们暴露这些易于变化的服务接口给系统的外部用户,就可能造成外部服务请求者难于支持不断变化的服务提供者所暴露的细粒度服务接口。而粗粒度服务接口保证了服务请求者将以一致的方式使用系统中所暴露出的服务。虽然面向服务的体系结构(SOA)并不强制要求一定要使用粗粒度的服务接口,但是建议使用它们作为外部集成的接口。通常架构设计师可以使用BPEL来创建由细粒度操作组成的业务流程的粗粒度的服务接口。
无状态服务的设计
SOA系统架构中的具体服务应该都是独立的、自包含的请求,在实现这些服务的时候不需要前一个请求的状态,也就是说服务不应该依赖于其他服务的上下文和状态,即SOA架构中的服务应该是无状态的服务。当某一个服务需要依赖时,我们最好把它定义成具体的业务流程(BPEL)。在服务的具体实现机制上,我们可以通过使用 EJB 组件来实现粗粒度的服务。我们通常会利用无状态的Session Bean来实现具体的服务,如果基于Web Service技术,我们就可以将无状态的Session Bean暴露为外部用户可以调用的到的Web服务,也就是把传统的Session Facade模型转化为了 EJB 的Web服务端点,这样,我们就可以向 Web 服务客户提供粗粒度的服务。
如果我们要在 J2EE的环境下(基于WebSphere)构建Web服务,Web 服务客户可以通过两种方式访问 J2EE 应用程序。客户可以访问用 JAX-RPC API 创建的 Web 服务(使用 Servlet 来实现);Web 服务客户也可以通过 EJB的服务端点接口访问无状态的Session Bean,但Web 服务客户不能访问其他类型的企业Bean,如有状态的Session Bean,实体Bean和消息驱动Bean。后一种选择(公开无状态 EJB 组件作为 Web 服务)有很多优势,基于已有的EJB组件,我们可以利用现有的业务逻辑和流程。在许多企业中,现有的业务逻辑可能已经使用 EJB 组件编写,通过 Web 服务公开它可能是实现从外界访问这些服务的非常好的选择。EJB 端点是一种很好的选择,因为它使业务逻辑和端点位于同一层上。另外EJB容器会自动提供对并发的支持,作为无状态Session Bean实现的 EJB 服务端点不必担心多线程访问,因为 EJB 容器必须串行化对无状态会话 bean 任何特定实例的请求。 由于EJB容器都会提供对于Security和Transaction的支持,因此Bean的开发人员可以不需要编写安全代码以及事务处理代码。 性能问题对于Web服务来说一直都是一个问题,由于几乎所有 EJB 容器都提供了对无状态会话 Bean 群集的支持以及对无状态Session Bean 池与资源管理的支持,因此当负载增加时,可以向群集中增加机器,Web 服务请求可以定向到这些不同的服务器,同时由于无状态Session Bean 池改进了资源利用和内存管理,使 Web 服务能够有效地响应多个客户请求。由此我们可以看到,通过把 Web 服务模型化为 EJB 端点,可以使服务具有更强的可伸缩性,并增强了系统整体的可靠性。