总结发现我们实际要解决的问题是:企业应用集成(Enterprise Application Integration,EAI) 是完成在组织内、外的各种异构系统,应用和数据源之间共享和交换信息和协作的途径,方法学,标准和技术。
SOA(Service Oriented Architecture) 中文释义为 “面向服务的架构”它是一种设计理念,其中包含多个服务, 服务之间通过相互依赖最终提供一系列完整的功能。各个服务通常以独立的形式部署运行,服务之间通过网络进行调用。要求各个服务遵循统一的规范和契约。
ESB(Enterprise Service Bus,即企业服务总线) 就是一根管道,用来连接各个服务节点。ESB的存在是为了集成基于不同协议的不同服务,ESB 做了消息的转化、解释以及路由的工作,以此来让不同的服务互联互通
当前实现ESB比较成熟的模型为EIP(Enterprise Integration Patterns)1。他的包含如下规范:
当前热门的EIP集成框架分别有:Spring Integration、Mule ESB、Apache Camel。接下来分别对三个框架进行分析(打分为博主的评估,仅供参考):
Spring Integration只提供了非常基础的支持,如文件,FTP,JMS,TCP,HTTP或Web服务。集成是通过编写大量的XML代码(没有一个真正的DSL)实现的。使用它,寓意着大量的XML编写工作。
Mule ESB不是仅仅一个集成框架,而是一个包括一些额外功能的完整ESB,比Spring集成它更像是一个DSL。
因为是一个完整的ESB,所以集成逻辑会比较复杂。
Apache Camel实现了你能想到的几乎每一个技术,提供很多组件,同时你可以很容易的自定义组件。而且Camel和Spring的集成很完善。Camel可以实现用到才依赖,不用不依赖。
Apache camel 是一个基于EIP的开源框架。实现了EIP定义的一些不同应用系统之间的消息传输模型,包括常见的Point2Point、Pub/Sub模型。
Camel的消息传递系统(Message System)2:
from("amqp:queue:order")
.to("uri:validateBean", "uri:handleBean", "uri:emailBean");
from("amqp:queue:order")
.multicast()
.to("uri:validateBean", "uri:handleBean", "uri:emailBean");
from("amqp:queue:order")
.process(new XmlToJsonProcessor())
.to("bean:orderHandler");
<route>
<from uri="amqp:queue:order"/>
<multicast>
<to uri="uri:validateBean"/>
<to uri="uri:handleBean"/>
<to uri="uri:emailBean"/>
multicast>
route>
from("amqp:queue:order")
.filter(header("foo")
.isEqualTo("bar"))
.choice()
.when(xpath("/person/city = 'London'"))
.to("file:target/messages/uk")
.otherwise()
.to("file:target/messages/others");
Endpoint是Camel与其他系统进行通信的设定点。
Camel自身提供了广泛的通信协议支持,例如:RPC协议、HTTP协议、FTP协议……
Camel中的Endpoint使用URI描述对目标系统的通信。
对Endpoint实例的创建通过对Camel中org.apche.camel.Component接口的实现来实现的。
Camel通过Plug方式提供对各种协议的Endpoint支持,如果需要使用某种Endpoint,需要引入响应的plug。例如要使用Camel对Netty4-Endpoint的支持,要引入camel-netty4的依赖包。
Properties:Exchange对象贯穿整个路由执行过程中的控制端点、处理器甚至还有表达式、路由条件判断。为了让这些元素能够共享一些开发人员自定义的参数配置信息,Exchange以K-V结构提供了这样的参数配置信息存储方式。
Patterns:Exchange中的pattern属性非常重要,它的全称是:ExchangePattern(交换器工作模式)。其实现是一个枚举类型:org.apache.camel.ExchangePattern。可以使用的值包括:InOnly, RobustInOnly, InOut, InOptionalOut, OutOnly, RobustOutOnly, OutIn, OutOptionalIn。从Camel官方已公布的文档来看,这个属性描述了Exchange中消息的传播方式。
Message IN/OUT:当Endpoint和Processor、Processor和Processor间的Message在Exchange中传递时,Exchange会自动将上一个元素的输出作为这个元素的输入使用。
Processor用于接受从Endpoint、Routing或者另一个Processor的Exchange中传来的消息,并进行处理。
Camel核心包和各个Plugin组件都提供了很多Processor的实现,开发人员也可以通过实现org.apache.camel.Processor接口自定义Processor。
// 一个自定义处理器的实现
public class OtherProcessor implements Processor {
@Override
public void process(Exchange exchange) throws Exception {
Message message = exchange.getIn();
String body = message.getBody().toString();
//===============
// 您可以在这里进行数据格式转换
// 并且将结果存储到out message中
//===============
// 存入到exchange的out区域
if(exchange.getPattern() == ExchangePattern.InOut) {
Message outMessage = exchange.getOut();
outMessage.setBody(body + " || other out");
}
}
}
Routing用于处理Endpoint和Processor之间、Processor和Processor之间的路由跳转。
Camel中支持的路由规则非常丰富,包括基于内容、接收者列表、循环动态路由等。
在Apache Camel中有一个比Endpoint、Component、CamelContext等元素更基础的概念元素:Service。
包括Endpoint、Component、CamelContext等元素在内的大多数工作在Camel中的元素,都是一个一个的Service。
Camel应用程序中的每一个Service都是独立运行的,各个Service的关联衔接通过CamelContext上下文对象完成。每一个Service通过调用start()方法被激活并参与到Camel应用程序的工作中,直到它的stop()方法被调用。也就是说,每个Service都有独立的生命周期。
CamelContext横跨了Camel服务的整个生命周期,并且为Camel服务的工作环境提供支撑。
企业集成模式 ↩︎
消息传递系统 ↩︎
Camel核心要素 ↩︎