使用Fabric3实现服务组合的模块化
模块化是良好的应用设计的基石。随着系统变得越来越分散,我们面临着实现有效的模块化的挑战。如何组织,封装实现松耦合的服务?
本案例展示如何使用模块化架构构建两个不同的Java的应用:一个高度可靠的SOA税务处理平台,和基于事件低延迟的外汇货币交易系统,模块化是使用OSGI完成,服务组件架构SCA和Fabric3作为运行支撑。
没有一种技术能够完全提供模块化的解决方案,这是因为模块提供很多特征,并且存在各种应用层次中如下图,模块化意味着:
- 通过分割代码到离散单元降低复杂性
- 提供一种机制,允许应用程序组件进行版本控制
- 定义子系统之间契约促进重用

应用模块
服务的组合和架构的模块化是有意义的,面向服务(组织应用程序的逻辑进入基于合约的单元)和依赖注入(由框架例如Spring和Guice提供)是现代建筑的模块化的基础。概括地说,他们有助于去耦子系统,从而使应用程序更加模块化。
现在缺少的是架构的封装和组成。例如,应用程序通常需要公开那些本身由多个细粒度的服务组成的粗粒度的服务。传统的集成平台如ESB产品和Java EE缺乏以一种简单有效的方式实现。现实中,通过企业服务总线(ESB)或Spring应用程序上下文实现包含数百甚至数千Bean公开扩散服务。
类似面向对象,我们需要的是一种方法,将服务组的集合在一起,然后实现有更好的管理机制来封装特定服务的实现细节:

服务模块
fabric3提供了这样一个服务组合实现,这是为SOA和事件驱动设计一个组合机制。现在谈谈如何在税收处理系统和外汇交易平台实现。
这两个例子中每个应用程序都有不同的要求。税收制度是以SOA集成平台为特征:它接收异步请求的税收数据,与多个遗留系统存在接口,发送给请求方处理结果的响应。在FX外汇系统,与此相反,极端只能允许微秒级别延迟:它接收到市场数据流,对其进行处理,进而提供了衍生的外汇定价发送到客户机系统。
SOA模块
税务系统架构如下:

税务系统架构
税收信息的请求是通过一个定制的可靠的消息传递层到网关服务实现接受,
事务地持久化消息请求,并启动处理。在与多个遗留系统交互和一系列复杂的规则过程中发生很多处理。
当数据已经被接收和处理时,响应经由消息传输层发送给请求者。
在设计系统时所面临的主要挑战,分离核心处理(通过各种请求驱动切换的状态机)和规则的评价以及遗留系统的逻辑。
模块化一个主要目标是提供一个简单的版本控制机制。例如,
每一个纳税年度税收规则通常会改变。因此,旧的沿着当年的规则必须被保存(处理涉及以前纳税年度的数据请求)。模块化允许他们在不影响系统其它部分时更新。
来自传统系统接口检索税务数据的部分也被隔离在一个模块中。这允许在没有影响系统的其余部分情况下改变外部接口。
模块化担任一个额外的实际用途:与遗留系统的接口是复杂和繁琐。
通过分割复杂性,整个系统更容易理解和维护。
模块化如何在实践中实施?开发环境需要设置一个Maven多模块构建。该基本的API模块包含了对各种服务的Java接口。与核心处理,规则和集成模块相关的独立API模块:

服务组合使用 Fabric3的 SCAcomposites.实现如下,类似Spring的应用上下文:
<composite name="IntegrationComposite" …> |
02 |
<service name="TaxSystem" promote="TaxSystem"/> |
03 |
<component name="TaxSystem> |
04 |
<implementation.java class="…"/> |
05 |
<reference name="idprocessor" target="IdProcessor"/> |
08 |
<component name="IdProcessor"> |
09 |
<implementation.java class="…"/> |
10 |
<reference name="locationProcessor" target="LocationProcessor"/> |
12 |
<reference name="legacySystem"> |
13 |
<binding.ws uri="…."/> |
17 |
<component name="LocationProcessor > |
18 |
<implementation.java class="…"/> |
19 |
<reference name="dataProcessor" target="DataProcessor"/> |
20 |
<reference name="legacySystem"> |
21 |
<binding.ws uri="…."/> |
EDA