【IT168 专稿】
根据摩尔定律,自从1958年发明集成电路以来,处理速度和存储容量一直在以每两年翻一倍的速度增长。
但是软件系统的发展速度貌似不可避免地超过了这一切的指数增长速度。SOA的应用越来越广泛,而且随之还有服务之间的XML数据传递方式及增长更为迅速的网络应用。虽然你取得了成功,但是你的系统很可能会马上超载,而且是在你最意想不到的时候。
怎么解决这场危机呢?鉴于企业计算的内存和存储需求的持续增长,软件也需要维持相应的步伐。我们从一开始就要使用正确的方法以取得可控制延迟的线性可扩展性。数据文件和信息的容量也在持续增长,需要更多的处理能力,也使那些在使用前需要先将其具体化的软件显得更为笨重。在某些情况下,这些操作在执行前还需要多个输入。
那些构建极限事务处理(XTP)类应用——比如电话公司呼叫建立和计费、网络游戏、安全交易、风险管理和在线旅游订票服务——的人对这方面应该很有了解。还有更广泛的用例就是网络应用需要根据网络容量的增长而提高,但是后台系统却无法应对这样迅猛的流量。
边界成本
在与客户讨论对SOA进行延迟可控的扩展时,我们经常使用一个称为"边界成本"(Boundary Costs)的术语。为便于理解,请考虑以下情景:由一个网络应用(或数据库、外部业务伙伴、从EDI文档转换而来)生成的XML文档需要经过多个服务的处理,而这个过程由BPEL或ESB进行协调。通常的方法是把XML交给总线,由总线根据处理定义调用相应的服务,并将XML文档作为服务请求负载的一部分传递给服务。需要对数据进行处理的服务将依此对XML进行读取。还有需要与数据库交互的情况。这种方法(如图1)看起来非常简单。
但是,在实际中使用这种方法的时候却会遇到扩展性上的问题。从一个服务穿到另一个服务的成本是多少呢?在调用一个简单的业务过程的时候,这个成本消耗要发生多少次呢?如果XML文档非常大,达到几M的范围、数量成百上千,或者两种情况同时发生呢?
而且考虑到大多IT环境是多平台和多种技术的复合体,因此又给这种情况增加了新的困难。即使处理引擎或服务总线的性能非常出色,服务终端的处理过程仍然会成为瓶颈。最近在一家客户网站上显示,一个原来通过需要15秒处理时间的业务过程,最近在峰值负载时经常超过其SLA协议约定的30秒。在过去两年里,开发人员把大部分时间都用在了优化调整这15个服务的每一处细节,但是最后揪出的黑手却是各服务之间的边界成本。他们进行的一次详细检测显示,这15个服务调用都要花费1到2秒的时间在一个开源网络服务工具包里对XML进行解析处理。这并不是有意污蔑开源网络服务工具包,只是简单地说明一下在终端解析处理XML会增加延迟,并且相加效果非常可观。
如图2所示,所调用的各个服务都需要从XML的在线串行化形式中读取其有效内容并解析为本地Java或.NET对象形式,然后才能被业务逻辑处理。并且,如果还涉及到与数据库的交互,那么还会发生额外的相关匹配对象。最后,还要发生相反的过程,产生与服务请求相应的响应并根据业务过程将其发送到下游服务。
在SOA中,比较常用的处理XML的方式是使用网络服务和XMLBeans。通过XMLBeans可把输入和输出完全具体化然后再生成对象,这样可以最大化可用性和处理性能。内存处理可能包括分类、过滤、合并等操作,而所有这些操作都会增加处理每次调用所需的整体内存容量。这种方式缺乏扩展性,而且无法应用到这个领域的许多场景中。许多产品支持XML流,但这种方式也有局限性,即如果不先存放数据可能就无法进行任何有意义的操作。
那么,能不能设计一种方式,把信息储存在一个可以忽略数据大小和单机处理能力的应用网格中呢?该应用网格可以利用多台机器的组合内存和处理能力来完成一项操作,比如处理一个复杂的公式或对海量数据进行过滤。该应用网格还可将数据的生命周期延长到服务请求周期之外,持续到服务器重启,甚至跨越网络边界。
如果你能将网格数据存储的能力和高效的流处理结合到一起,就能够产生一个处理能力远大于以前的、高度的、可扩展的系统。通过将一些补充技术结合到一起,我们就能取得把计算操作扩展到分布式的计算网络中,减少SOA服务、应用服务器和客户应用等数据消费者的处理和内存需求。我们还消除了数据处理过程中对中间存储数据库的需求。通过应用网格我们还可以传送数据的参数而不是数据本身,这样可以极大地提高通信层的效率并且减少甚至消除边界成本。
本文还有一段显示应用网格中处理大型XML文件的代码示例。在典型的XML文件中通常有一些元素在没有任何预定义限制的情况下重复。通过STAX解析器对XML进行处理,并且用JAXB处理XML与Java对象之间的会话,我们可以将这些重复的元素从XML流中提取出来,然后放到应用网格中作为单独的对象。这样对象便填充到了网格中,并且只需消耗有限的内存资源。填充到网格之后,网格便可以使用构成网格的多台机器对数据进行处理。每个网格成员进行一项操作或过虑,然后将中间结果传递给网格客户端并由其处理成最终结果。