在2008年10月发行的Dr Dobbs杂志中,Michael Swaine撰写了题为《您的下一代语言是COBOL吗?》的文章。他指出,“每年新增的数十亿行COBOL代码”证明了当前传统大型机应用的规模和强度仍在继续发展。毫无疑问,整合大型机应用和分布式系统,尤其是基于Java的系统,仍然是一个重要的课题。
这些年来人们在大型机集成中积累了很多经验,其中一个惨痛教训是系统间的紧耦合是不可取的。当然,除了大型机应用之外,应用间的技术差异正在进一步 扩大:比如一些应用是基于COBOL、CICS/IMS,另一些应用是基于Java、J2EE 、Eclipse的。具有不同生命周期、由不同开发者使用不同工具开发出的应用之间存在着过多的依赖,这些导致了系统的脆弱和不稳定。
大型机集成商很早就采用了面向服务架构(SOA),这导致了受SOA启发的第一代大型机集成解决方案的出现。这些解决方案的大多数是以大型机为中心的,在某种程度上是将COBOL绑定到XML和直接运行在大型机之上的SOAP消息传递系统。
最近,由于某大型IT社区对企业集成模式的推广和作为SOA基础设施的企业服务总线(ESB)的出现,大型机集成有了新的可选架构。本文中,我们将提倡一种以ESB为中心的大型机集成的新观点,同时也将介绍一种实现这个架构的开源解决方案,即在JBoss ESB中使用LegStar实现大型机整合。
Michael Swaine指出,COBOL语言正在通过自身不断地发展来支持XML,像CICS系统现在也支持SOAP。除了IBM,还有许多供应商在大型机上将 COBOL绑定到XML和SOAP协议栈上。近几年来,专注于遗留集成系统的分析师一直赞同这种以大型机为中心的整合方式,即将XML和SOAP直接运行 在大型机上。
由于当时标准的大型机SOAP栈还没有出现,大部分以大型机为中心的集成商不得不开发自己的SOAP栈。有些甚至还自己开发XML解析器。
然而从那之后,SOA和Web服务发展非常迅速。几年前,只要提供基本的XML处理和SOAP 1.1就足以声称是面向服务的。再后来,客户对SOA的期望和认识逐步清晰,开始采用新标准,如WS-*。因此对集成商而言,维护自己开发的SOAP栈的成本快速增长。
大型机开发人员缺少像开源所能提供的大型开源社区和丰富资源。因此,一些大型机的SOAP栈还不支持SOAP 1.2或者WS-Addressing规范,而这些规范则是许多WS-*规范的基础。相比之下,Apache中最新发布的Axis2,其大小为20MB, 其中包括了59个lib,覆盖了SAAJ(SOAP1.1和SOAP1.2)、XML Schema、WSDL 1.1和WSDL 2.0、WS-Addressing、Fastinfoset、WS-MetadataExchange、MTOM、WS-Policy等规范。
另外,许多新技术还在不断涌现,如RESTful Web Services。在Google、Yahoo和Amazon的支持下,这类架构越来越受欢迎,并且针对RESTful Web Services的Java API已经成为JSR 311规范,这足以说明RESTful Web Services的受欢迎程度。作为XML的轻量级替代品的JSON也备受关注。比如Axis2已经支持JSON 。在不久的将来,使用RESTful Web Services集成大型机应用和对JSON的支持很可能会成为需求,而且还可能会给本来就已经很长的需求列表中增加更多的项目。除了基本Web服务功能 外,对Web服务编排和脚本语言的需求也已经出现,这给以大型机为中心的开发团队带来了更大的压力。
SOAP出现后,这些以大型机为中心的解决方案,不仅在功能方面长期滞后,而且也遭受了因草率而做出的设计决定所带来的痛苦。
例如,以大型机为中心的解决方案往往将绑定层、消息传递层和传输层紧耦合在一起。相反,开源社区则强调将语言绑定(比如,从Java到XML的绑 定)从传输和消息传递中清楚地划分出来。在Java中,符合JSR 222的Java for XML binding(JAXB)通常是独立于任何Web服务技术而实现的;可以将它同SOAP或者RESTful Web Services一起使用。同样,消息传递和传输通常也是相互独立的,除了可以将SOAP消息使用HTTP/HTTPS传输之外,也可以将它使用JMS或 TCP传输。因此,以大型机为中心的解决方案很难适应不断变化的SOA。
在设计上,以大型机为中心的集成解决方案也把大型机作为IT基础设施的中心来考虑。分布式应用被看作是大型机的外围应用。这导致了一种非对称的大型 机集成愿景,其中唯一的需求(或是最重要的需求)是这些外围应用消费大型机资源。随着分布式应用重要性的日益显现,大型机应用不再相互孤立。最近,许多以 大型机为中心的集成商感觉到了威胁,并开始提供向外发送请求的功能,但是它们极少经过彻底改造,而这正是支持一个使IT基础设施中的大型机角色更为平衡的 愿景所需要的。在大型机上的SOAP客户端功能非常薄弱和有限,这严重制约了对外部分布式服务的访问。
最后,以大型机为中心的集成的另一个重要问题就是成本。大型机的软件许可证和维护费用非常昂贵。开源不会或许永远不会涉及到这些费用问题。另外,XML和SOAP处理是一种CPU密集型活动。大型机的CPU成本仍然相对较高,虽然IBM的某些举措对此有所缓解。
总之,对于以大型机为中心的整合提供商,要遵循最新的Web服务标准,响应新需求,适应大型机应用的变化角色以及由开源普及的新费用结构,变得越来越困难。
在开源社区中,企业服务总线(ESB)已成为SOA的最佳基础设施。ESB支持多种传输协议、注册服务、消息转换、服务编排等功能。从某种程度上,它们涵盖了曾经由私有的企业应用集成(EAI)平台涉及的领域。
以ESB为中心的大型机集成解决方案通过建立在ESB架构之上,充分利用了这些优势。例如,将COBOL绑定到Java或XML就是作为ESB的内 部转换活动处理的。大型机中的消息交换可以使用ESB标准传输协议或现有的传输协议。大型机应用程序还没意识到ESB的优势,ESB也可以与其他大型机交 换数据。
在开源社区中,ESB社区非常活跃,与大型机相比,社区中的年轻开发人员能更好地理解ESB。ESB得益于大型的开源社区,同时它也直接面临着新技 术的挑战,如BPM、动态语言和RESTful Web Services。BPM和BPEL已经广泛运用于ESB,但以大型机为中心的集成解决方案却面临着很多挑战。借助以ESB为中心的集成,大型机集成能直 接参与复杂的业务流程。
和以大型机为中心的解决方案一样,以ESB为中心的大型机集成工具在设计时和运行时都起到了作用。相同的是,设计时工具需要将COBOL映射成复杂 的数据类型。不同的是,以ESB为中心的设计时工具所生成的制品是专门针对ESB的。这些制品一旦部署到ESB,它们将把大型机的数据流转换成开放世界中 的对象。数据转换是ESB的功能之一,并受益于ESB的多线程、可伸缩架构。
ESB为中心的大型机集成还得益于丰富的XML优化技术,如今在开放社区,这些技术广泛用于减少内存消耗,以及降低处理XML所消耗的CPU使用 率。可以说,分布式平台上的CPU成本比大型机上的要便宜得多,但最重要的是,像profiler这样成熟的工具已经广泛地在Java中使用,而在大型机 中尤为少见。以ESB为中心的解决方案可以更好地监测和控制CPU或内存消耗,从而降低整体集成成本。
在以ESB为中心的解决方案中,所生成制品与任何可以部署在ESB上的制品(Java,XML,jars等)是一致的。这意味着这些制品可以使用丰 富的管理工具(源代码控制、构建控制、依赖管理和持续集成等)来管理,而且可以被单元测试、测量和保护。集成制品是非常重要的开发制品。它们往往是事务性 系统的关键部分。在以ESB的为中心的解决方案中,这些制品可以看作是软件开发生态系统中的一等公民。
和以大型机为中心的SOAP堆栈相比,ESB还提供了一个更高层次的抽象层。为了说明这一点,可参考下面的用例:在分布式平台中,大型机应用所消费的服务 是由大型机之外提供的。因为分布式环境的特性日益增多和在IT资产中发挥越来越大的作用,分布式环境提供引用数据和流程也越来越常见。在这种情况下,大型 机上原有流程需要使用这些分布式功能。在以大型机为中心的集成解决方案中,COBOL程序会发出SOAP请求。相反,在以ESB为中心的集成解决方案 中,COBOL程序对某次特殊的消息传递或者对它正在对话的分布式平台一无所知。它只需是将大型机数据放入一个WebSphere MQ队列中或是一个HTTP有效负载中。目标服务和协议的细节被隔离在ESB的内部。以ESB的为中心的解决方案提供了更高层次的解耦,这正是系统集成最 期望得到的特性。
LegStar for JBoss ESB是一种开源的大型机集成技术,它是第一个专门面向ESB作为整合平台的方案。本文演示了如何使用Redhat的开源ESB——JBoss ESB和LegStart让大型机的COBOL程序访问外部系统。这种组合架构使用同步或异步消息传递(这是大型机极少涉及的技术)有效地将大型机应用和 分布式流程进行了解耦。
我们将为COBOL消费者暴露一个Java对象(Plain Old Java Objec或者POJO )。
LegStar for JBoss也能满足更经典的用例,即COLOBL程序被暴露给Java消费者。但当COBOL代码作为客户端时,尤其是对松耦合要求比较高时,会面临一些特殊挑战。
LegStar for JBoss也可以让COBOL代码访问ESB服务和Web服务。出于简单考虑,本用例中我们选择消费一个POJO。
在大型机一侧,我们假设COBOL是开发语言,WebSphere MQ是传输机制。
在服务器端,我们使用免费的开源技术:JBoss ESB和LegStar。
部署架构如下:
对于这个架构选择有如下几点值得说明:
你也可以选择使用HTTP与ESB交换数据,但WebSphere MQ已在大型机上得到广泛使用,与HTTP相比它能提供更好的异步消息。COBOL代码可运行在TSO中,作为一个批处理程序运行在CICS或IMS中。 WebSphere MQ API正好适用于这些环境,甚至更多。
COBOL程序将原始的大型机数据发送到WebSphere MQ队列。在大型机上这个内容不需要转换。这意味着JBoss ESB只需要接收原始的大型机数据。这样做有两个优点:
就解耦来说,第二点尤其重要。
虽然架构图显示了一个在z/OS上运行的WebSphere MQ管理器,但是在分布式平台可能存在另外一个WebSphere MQ管理器。为了架构简单,我们并没有给出额外的管理器,同时也因为这样做并不是必需的。
从ESB的角度来看,我们使用一个标准的监听器与JBoss ESB连接在一起。这是一个高性能、多线程的监听器,它能够支持来自大型机的高负荷传入消息、并发和请求。
COBOL客户端代码可以使用标准WebSphere MQ API等待响应,也可只要请求发送后就返回。异步通信模式是通过使用WebSphere MQ标准的触发机制实现的,在收到应答后COBOL程序可以处理应答。
异步是可取的,因为它减少了系统间的依赖。这种消息交换模式同样也适用于ESB。
JBoss ESB支持多种传输协议并提供了我们这里使用的通用管道的概念。
JMS网关是一个标准的JBoss ESB的监听器,它负责监听WebSphere MQ队列,当接收到消息时会触发一系列动作。JBoss自带了一些开箱即用的工具,比如我们这里会用到的对象调用器或JMS路由器。
列集/散集(marhaling/unmarshaling)原始大型机数据所需要的消息转换动作是由LegStart在设计时产生的,其细节将在下一节中描述。LegStar生成的制品是特定于JBoss ESB的,而且经过专门优化。
在某种程度上,ESB代理服务使COBOL客户端不受那些可能会导致目标POJO改变的变更的影响。首先,改变POJO位置或软件包的名字不会影响 COBOL客户端。你还可以在不影响客户端的前提下为POJO添加新特性。当然如果发生较大变化时,如删除属性或者改变属性的类型,仍会对COBOL代码 产生一定的影响。
本小节中我们描述了为POJO创建ESB服务代理的主要步骤,开发者可以按照这些步骤来操作。LegStar提供了Eclipse插件,简化了开发。另外,相同的工具也可作为ant脚本获得,但我们选择LegStar的Eclipse插件,因为它更友好。
本实例的Eclipse项目代码可以在这里下载。
在本文中我们使用POJO,相同的做法也适用于JBoss ESB服务或ESB外的Web服务。
它不仅是一个Java对象,我们还期望该类被暴露成一个粗粒度的方法,接受参数为一个复杂对象,输出则为一个对象,如果发生错误还会抛出异常。这种行为涉及到远程门面模式(Remote Facade pattern )。在这一模式中,输入和输出对象被称为数据传输对象(Data Transfer Objects)。在下文中,我们将称这些对象为数据对象。
这里显示了一种独特的方法。表示请求的输入数据对象被称为JVMQueryRequest。它包含一组环境变量名。被称为JVMQueryReply的输出数据对象将包含一组被请求环境变量的值,以及一组本地化相关的值。
public class JVMQuery { public JVMQueryReply queryJvm(JVMQueryRequest request) throws JVMQueryException { List envVarValues = new ArrayList (); try { for (String envVarName : request.getEnvVarNames()) { if (envVarName == null) { throw new JVMQueryException("Invalid variable name"); } String value = System.getenv(envVarName); if (value == null) { envVarValues.add("Not found"); } else { envVarValues.add(value); } } } catch (SecurityException e) { throw new JVMQueryException(e); } JVMQueryReply reply = new JVMQueryReply(); reply.setEnvVarValues(envVarValues); Locale locale = Locale.getDefault(); reply.setCountry(locale.getDisplayCountry()); reply.setLanguage(locale.getDisplayLanguage()); reply.setFormattedDate( DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL, locale).format(new Date())); reply.setCurrencySymbol(Currency.getInstance(locale).getSymbol()); return reply; } }
当原始大型机数据被传送到ESB时,LegStar会将这个数据列集(marshal)到一个Java数据对象。这是LegStar所起到的作用。 LegStar提供了设计时工具将COBOL结构映射到XML Schema和Java。它还提供了一个运行时绑定框架来完成原始大型机数据的列集/散集(marhaling/unmarshaling)。
LegStar还提供了Eclipse插件,允许用户选择Java对象和请求自动映射到COBOL结构:
其结果是一个具有特殊COBOL注解的XML Schema。下图中Eclipse的标准XML Schema编辑器显示了JVMQueryReply的数据结构:
您可能会注意到,有些COBOL属性有默认值。例如,字符串的默认大小是32。这是因为COBOL只支持固定大小的字符串。类似的,COBOL不支持非固定的数组。在XML Schema编辑器中可以方便地修改这些默认值。
LegStar的COBOL绑定类是Java类,这些Java类完成原始大型机数据到Java数据对象的列集/散集(marhaling/unmarshaling)。
在Eclipse插件中,可以从XML Schemas提取复杂类型(complext type)。然后你可以选择需要生成绑定类的复杂类型。在下面的例子中,我们选择输入和输出类型:
LegStar的COBOL绑定机制是建立在Java到XML的绑定框架之上的,它被称为JAXB 或 JSR 222。绑定过程会产生带有COBOL注解的JAXB类。如果你打开一个已生成的JAXB类,就能看到Java对象中的每个属性如何持有COBOL注释:
最后一步会生成一系列制品,以帮助部署和测试JBoss ESB的代理服务。在Eclipse中,我们选择WebSphere MQ选项并指定目标JBoss ESB服务应当部署的位置:
LegStar会生成JBoss ESB示例配置文件,文件包含了处理管道的完整动作,以供测试。它还生成了COBOL客户端示例代码,这些代码可以调用JBoss ESB的服务,并为开发做好准备。
在JBoss ESB中使用LegStar是一个以ESB为中心的下一代大型机集成解决方案的例子。
这种新架构具备如下特征:
COBOL和大型机应用程序将在很长时间内继续存在。许多这样的应用程序可以很好地履行其职责。与此同时,以SOA和ESB为基石的开源应用也正在逐步扩大规模。在这种背景下,以ESB为中心的大型机集成带来的独特优势是值得我们考虑的。
Fady Moussallam | LegSem的首席执行官,拥有20多年的大型机应用和集成技术经验。 |
Mark Little | Redhat的SOA技术研发经理以及JBoss分公司的技术主管。 |
查看英文原文:Mainframe Integration with JBoss ESB and LegStar。