IT项目的需求很容易改变,包括与其他系统集成的需求。对像这样的改变能否做出快速反应,对项目的成功至关重要,因此软件和开发过程必须能适应(这些改变)。幸运的是,企业应用集成(EAI),给我们提供了建立可扩展性,可维护性和在生产方式上的可集成的解决方案,所需要的所有知识,技术和最佳实践。
然而,大多数集成解决方案将我们置于进退两难的境地:虽然他们功能全面,对于大型项目和要求苛刻的环境也相当高效,但当它们涉及到对系统进行学习,部署和维护它,他们也需要大笔投资。
由于这些原因,当面对简单的集成需求的时候,临时的解决方案似乎非常有吸引力。但他们变得维护困难,在集成需求增长时也会遇到效率问题。引用EAI最佳实践能解决这些问题,但要实现他们,需要你自己付出努力并知道如何正确的去做。一开始好像阻力最小的路径,后续可能成为一个死胡同。
当我们面对简单又复杂的集成任务时,怎样能变得更加高效,同时避免在早期进行大量投资?在本文中,我将对 Apache Camel 提供的一种解决方案进行说明。我的目标是说明Camel 可以满足复杂的集成挑战,并让你充分利用EAI提供的最佳实践,同时易于学习和掌握。同时所有这些,Camel可以让你把精力集中在提供商业价值上,而不是处理一些通过框架进行的复杂实施。
我通过一个典型的具有挑战性的集成的实际例子进行说明,看看Camel是如何帮助我们面对这些挑战的。这些例子都在一个开始简单,但随着时间的推移,出现新的整合需求增长的背景下集成解决方案。每次我将主要从管理的复杂性和保持生产力的角度来探讨Camel 如何满足这些需求的。
我选择 Apache Camel,因为依我看,它对像 Service Mix, MuleESB, OpenESB 和 JBossESB这样全面的ESB产品,提供了一个优秀的、轻量级的替代方案。它最接近的对手可能是 Spring Integration,如果你的项目已经使用了SpringSource 技术,这将是一个很好的选择。正如你所看到的,你也可以一起使用Camel和Spring。 Gunnar Hillert在这里对替代方案提供了更加深入的讨论。
集成往往始于简单。例如,从一个FTP服务器获取文件并将其存放到本地文件中。在这一阶段DIY的解决方案似乎机具吸引力。但让我们更加仔细的瞧瞧。
自我搭建的解决方案看起来像这样:
public class FTPFetch { public static void main(String[] args) { FTPClient ftp = new FTPClient(); try { ftp.connect("host"); // try to connect if (!ftp.login("camel", "apache")) // login to server { ftp.disconnect(); return; } int reply = ftp.getReplyCode(); if (!FTPReply.isPositiveCompletion(reply)) { ftp.logout(); ftp.disconnect(); return; } ftp.changeWorkingDirectory("folder"); // get output stream for destination file OutputStream output = new FileOutputStream("data/outbox/file.xml"); ftp.retrieveFile("file.xml", output); // transfer the file output.close(); ftp.logout(); ftp.disconnect(); } catch (Exception ex) { ex.printStackTrace(); } finally { if (ftp.isConnected()) { try { ftp.disconnect(); } catch (IOException ioException) { ioException.printStackTrace(); } } } } }
该解决方案使用了Apache Commons包里的FTPClient 类。由于它仅仅是一个客户端,我们需要建立FTP连接并进行我们自己的错误处理。但如果在FTP服务器上的文件后期改变了怎么办?我猜我们应该安排定期运行。
现在让我们看看Apache Camel。Camel是一个集成框架,通过EAI最佳实践,专门用来解决这类问题。Camel应该被看作是现成的集成组件和运行时可以通过结合他们的具体需求定制的工具箱。有了Camel,这就是我们如何解决上述问题的方法所在:public class CamelRunner{ public static void main(String args[]) throws Exception { Main camelMain = new Main(); camelMain.enableHangupSupport(); //ctrl-c shutdown camelMain.addRouteBuilder(new RouteBuilder() { public void configure() { from( "ftp://host/folder?username=camel&password=apache&fileName=file.xml&delay=360000" ) .to("file:data/outbox"); } }); camelMain.run(); //Camel will keep running indefinitely } }
请注意 from and to方法。Camel称之为‘route’:从源到目的的数据传输的路径。此外,数据以最初的形式而没有发生改变,但以消息的形式被包装:实际数据的容器。这和SOAP 信封很相似,包括正文部分,附件和消息头。
消息源和目的地称之为‘终端’,通过他们Camel接收和发送数据。正如在from and to方法参数中所看到的,终端由一个URI格式的字符串指定。因此,我们告诉Camel做什么的方式是通过声明方式创建端点之间的路由,然后用Camel注册这些路由。源于Camel DSL的紧凑性和代码的清晰度,领域特定语言‘domain’是EAI。这意味着,不像其他解决方案,从EAI问题域到Camel应用域没有传输: 两个基本上是相同的。相比较来说,这有助于保持平缓的学习曲线和较低的进入点:一旦你理解了你的EAI问题,用Camel去解决它将会是小菜一碟。
但你写的代码并不是唯一简单地事:所有这些都需要camel-core.jar和camel-ftp.jar以及其他所依赖的包才能运行,这些加起来只有几MB。主类能通过命令行运行。并不需要增加额外复杂的应用服务器。事实上,因为Camel如此轻巧,它能被嵌入到任何地方。选择一个DIY解决方案的唯一基础是框架增加了大量的复杂性是无效的:Camel是简单易懂,简单易用和简单易运行的。
如今我们说到越来越多的集成需要整合。我们不仅希望能有更多的集成,而且要保持可维护性。对这些问题Camel如何应对呢?
随着越来越多的连接需要建立,我们仅仅需要给Camel增加更多的路由。新的路由可能需要通过其他像HTTP、JMS、SMTP等等终端进行连接。幸运的是,Camel的终端支持列表是可扩展的。如此美妙的是这些代表可重用的代码你不必重写。
当然,或迟或早你需要的一些东西在列表上找不到。问题就变成:我能将自己的代码插入到Camel有多容易?在这种情况下,我们能够使用Camel称之为‘组件’的(工具)。组件定义一个契约,(该契约)在实施时会使你的代码从被称为DSL的另一个端点可用。
到现在为止,我们知道我们能够增加更多的路由,与任何类型的协议进行连接,(不管)Camel是否提供开箱即用。但是,在某些点开始路由获得相当多,你会发现你在重复自己。我们像重用比特路由,甚至可以将整个解决方案,分割成独立的、粗粒度的部分。Camel对于重用的策略是基于特殊的、外部终端,而这些只有Camel能看到。如果要重用现有理由的一部分,它很有可能将路由重构为被外部终端相连的两部分。请参见下文:
源:
//original from(“ftp://server/path”). to(“xslt:transform.xsl”). to(“http://server2/path”);
重构后:
//receiving from internal endpoint d1 from(“direct:d1”). to(“xslt:transform.xsl”). to(“http://server2/path”); //sending to d1 from(“ftp://server/path”). to(“direct:d1”); //also sending to d1 from(“file://path”). to(“xslt:other-transformation.xsl”). to(“direct:d1”);
连接终端是‘direct’类型。该类型的终端只能在相同的Camel上下文环境内进行寻址操作。另一个有趣的终端类型是VM。VM终端可以从另外的Camel上下文环境下寻址,提供了在这两种情况下,运行相同的JVM的实例。
Camel上下文就像是你的路由器容器。每次你运行Camel的时候,它就实例化一个上下文并在内部寻找路由。因此当我们运行Camel的时候,我们实际上是在运行上下文实例。下面的图片展示在不同Camel实例之间发散的各种路由,彼此独立的运行在相同的JVM实例上,通过VM终端彼此寻址:
(点击查看大图):
2KB项目(www.2kb.com,源码交易平台),提供担保交易、源码交易、虚拟商品、在家创业、在线创业、任务交易、网站设计、软件设计、网络兼职、站长交易、域名交易、链接买卖、网站交易、广告买卖、站长培训、建站美工等服务