面向服务架构和域可插入性
本节讨论了SOA对更好地支持业务域可插入性的帮助程度。下面给出可插入性的定义。可插入性就是换出一种域实现(业务服务及相关域模型),然后使用另一种域实现来代替它。可插入性要求只能通过定义良好的接口(域的客户端,包括其他域,对接口以外的事情一概不知)来公开域实现。这可以使用基于组件的方法来实现;然而,这种方法具有局限性:域的客户端被绑定到特定版本的组件接口(至少不会通过反射/类加载器相关的循环进行跳转,或者使用某种脆弱的JNDI命名约定)。
通常,域模型太过于细粒度,以至于无法被直接公开为一组服务。因此,域模型中实现的任何域间关系都应该被最小化,以便为它的客户端(域服务)实现可插入性。这显然意味着,数据模型中的域间关系也要保持最小化。域模型只公开给域服务层。业务设备(如果需要)和用例服务层与域服务进行交互。域服务与它们的适用域模型进行交互,并把模型的细粒度的、面向对象的接口转换为粗粒度的、面向服务的接口。参见图3,您可以(通过例子)从概念上了解这些层是如何定义的。
图3 概念上的SOA分层
折衷
选择架构方法时总是要进行折衷,使用SODA的SOA方法当然也不例外。关于SOA(这个概念已经存在很多年了)和SODA的具体含义,有多种解释。在本文中,服务被定义为粗粒度接口(通常由工具生成,并且以XML编写)。这些服务可以(但是并不一定)被公开为Web services。这些服务应该在设计和运行时都是动态可配置的,这样我们才可以针对不同的目的重用某个特定的服务。
服务实现本身将会是定制构建和第三方的混合体。这些服务通常是分层的,而且在很大程度上会被编排成表示和业务流程。一旦谈到XML、分层和动态配置,就不可能不谈及性能和可伸缩性的问题。同样地,SODA对工具的巨大依赖性引发了对于厂商锁定的讨论。对特定工具集的依赖还引出了软件构建、修改管理、部署,以及这些工具如何与当前使用的基础架构互操作等方面的问题。
厂商锁定
SODA主要的价值在于工具支持表示和业务流程编排的方式、(几乎)无缝的XML/本地语言数据转换、设计/运行时服务配置、注册、发现,等等。这些都是在没有任何实际的、无所不包的SODA标准(当然,包含某一部分的标准是存在的,比如Web service/SOAP、BPEL/BPML、WS<fill-in-the-blanks>,等等)的情况下实现的。这保证了某种层次上的厂商锁定。厂商锁定的程度依赖于所选择的工具和这些工具的用法。
性能和可伸缩性
对于一个构建在基于XML的分层SOA上的应用程序来说,通常有很多影响它的性能的问题。这些问题与下列方面有关:使用像XML这样冗长的语言进行应用程序内部通信,客户端和服务都可能需要序列化和反序列化来把XML转换为本地的语言对象表示,这些都会带来潜在的开销。当更多的并发用户与应用程序交互时,就会带来更大的有效负载,这时候可伸缩性就开始起作用了。通过审慎地设计真正粗粒度的服务,只在定义良好的服务层之间进行通信,上述大部分问题都可以得到缓解。有限的长期状态确保了操作在适当的时候是异步的。通过优化XML转换(或者通过在它们的表示和业务流程流中本地操作XML),SODA工具通常可以减轻这个问题所带来的影响。但是最后肯定会带来更大的开销,而且在实际使用模式下,应用程序的性能分析必须更早地固定到流程中,以便确定哪里需要优化和调整。
构建、修改管理和部署
所挑选的工具必须可以与当前使用的基础架构互操作,或者具有能够轻松添加这种互操作能力的可扩展性。当前构建(通常是Ant)和源控制系统,以及标准的J2EE企业应用程序打包部署单元都是必需的。
结束语
真实情况是,使用基于SODA的最新工具构建的SOA无疑并非银弹,而实际上银弹是不存在的。通过数据/服务抽象和模拟,规范的SOA方法有助于在某种程度上缓解依赖性瓶颈的问题;然而,我们仍然必须对依赖性进行管理,尤其是在域层。另一方面,SOA的优点之一就是,由于服务和数据抽象,可以相对独立地开发高级服务。这也允许我们独立地开发表示和业务流程编排。