SOAP应用模式:处理与性能

日期: 2011-11-09 来源:TechTarget中国 英文

   在SOAP消息的增量解析和处理模式下,SOAP发送者可能生成了一个非常冗长的SOAP消息,由于等到完整接收这个冗长的SOAP消息后再处理会造成大量的技术时间的浪费,并且将延迟响应速度,因此就需要发送者具备增量发送的能力,而接收者具备增量接收的能力。当SOAP接收者在接收消息的时候,使用一个能够增量处理消息体的SOAP处理器来实现这一目标(一般的,当消息体开始被接收的时候,开始使用一个SAX风格的XML解析器来处理)。

   这种方法对于内存有限的SOAP处理器而言是特别的有效,同时对于那些面向增量的实时数据传输的服务而言也是非常的有效。另外它还适用于这样的应用场景:消息具备冗长的消息体,同时这些消息体能够通过SOAP处理器模块直接被转换成应用程序中的数据结构和事件。事实上,此时我们并没有必要为这些数据额外地构造相应的DOM模型,SAX方式的处理更为适合。在增量处理的情况下,对于SOAP数据模型的支持仍然是可能的, 如何这些模型是能够被增量地构造的话。

   概括地说,本节所描述的SOAP消息的增量解析和处理模式需要接收者能够增量地解析和处理SOAP消息。这是一个适用于有限内存的处理环境的一个通用模式。如果SOAP Body包含了大量的数据,同时在具体应用中适合分段处理,那么通过SAX解析器采用增量处理模式是非常贴和需求的。下面的代码展示了一个可分段处理的SOAP请求消息示例,其中使用了BodyDataChunk元素来表示不同的数据段。

以下是引用片段:
<env:Envelope > 
<env:Header> 
<!-Set of headers processed before Body –> 
</env:Header> 
<env:Body> 
<b:BodyDataChunk > 
<b:DataLength>1024</b:DataLength> 
<b:Data>kfkk34jkhfSomeBase64EncodedDatajdsgkjgjajgo34093589uvsjv 
…………… jhfjhf350giqhf</b:Data> 
</b:BodyDataChunk> 
<!- More BodyDataChunk elements –> 
<b:BodyDataChunk > 
<b:DataLength>1024</b:DataLength> 
<b:Data>oqjrj45cmoLastLotOfBase64EncodedData12r9vnhofjhckzlmxjws 
…………… skfjk23ogkkjhq</b:Data> 
</b:BodyDataChunk> 
</env:Body> 
</env:Envelope> 

   此时,如果SOAP请求是以流 (stream) 的方式被传输并被增量处理的话,那么相应的响应消息也可以以流的方式被传向初始的请求发送者。在这样的应用实例中,对于接受应用的设计,我们需要在实时性和错误处理方面格外加以重视。

   如果SOAP请求的Header条目引发了错误的话,那么SOAP Fault将被插入到响应消息中,同时请求消息的处理也同时被中止。SOA消息的接受处理程序将会把每个BodyDataChunk元素视为一个原子。处理中,将视每个BodyDataChunk元素被成功处理与否,而将积极的或消极的确认加入到 SOAP响应的流 (stream)中去。当SOAP请求消息被处理完毕之后,SOAP响应消息的生成处理也同时被完成。另一个可选择的方案是,SOAP接受处理程序可以当SOAP请求被完整接受完毕再处理每个BodyDataChunk元素。如果在接受之中发生错误,那么一个SOAP Body Fault元素将被加入到SOAP响应流中,同时SOAP请求的处理被中止。在缓存(Caching)模式下,一些应用程序因为效率上的原因,例如为了获得更快的响应时间、占用更小的带宽或一些其他的方面,而进行可能的缓存操作。为了实现这一点,我们需要在相关的环境中设置缓存机制。例如,“读”缓存可以被SOAP中间介用于保存消息,以备在请求/响应消息交换模式的响应阶段重用。这样的缓存机制可以作用在整个消息的范围,也可以作用在一个SOAP模块的范围,或是作用在个别的SOAP模块的元素上。类似的,当在请求/响应消息交换模式下(当然也可以是其他的消息交换模式),请求消息不需要被立即转发或者响应的话,“写”缓存就变得有用了。这种缓存机制同样可以作用在整个消息的范围,也可以作用在一个SOAP模块的范围,或是作用在个别的SOAP模块的元素上。对于能够作用在不同元素上的缓存机制而言,它可以使用一个属性来关联目标缓存元素,具体的,属性可以通过 XML Query 的表达式或是 XPath 的表达式,在消息头或是文档中描述目标元素。同时缓存机制除指定目标结点外,还要制订一些其他的缓存参数,诸如生存时间(增量时间)、失效时间(绝对时间)、实体有效性、时间有效性、失效服务的订阅以及对象更新和清理等。最后,一些应用程序还要求缓存机制具备描述消息元素之间的依赖和关系的能力。例如,一个响应消息中的元素可能适用于一个较大范围的请求消息,如果能够描述该元素与那些请求元素的关联关系将会对处理有帮助,如此,在应付这些请求的时候,我们就可以使用一个经济的方式(使用缓存元素)来给出响应消息。缓存机制经常在分布式系统中作为优化机制而使用。它可以用于避免重复执行相同的计算操作,或是避免当结果集在一段时间内持续有效的前提下重复执行复杂的数据库访问。此时,一系列针对相同信息的请求可以使用被缓存的版本来响应,而无需重复地处理并占用系统开销。缓存机制的另一个用途则是针对数据的传输,应用了缓存机制之后,数据的副本可以存于叶节点服务器以方便本地的服务,而无需重复地访问中央信息库。如此,不仅加快了对信息的访问,同时缩减了对网络带宽的占用,同时还减轻了中央服务器的负载。缓存机制可以以底层传输架构的一部分被提供使用,不过在本节描述的应用模式中,我们假设这个缓存机制是与任何底层传输相独立的。

   本应用模式的一个例子是,当一系列请求可以安全地以相同的结果返回的时候,缓存对应于该请求的响应消息。BizCo是一家销售软件产品的在线商场,它每天上午8:00更新它的在线产品报价数据库,那么在上午8:00之后访问该商场的SOAP报价服务的远程用户都可以缓存报价消息直至第二天上午8:00。如果远程客户需要重复访问相同产品的报价的话,它就不需要重复地访问远程的BizCo的SOAP报价服务,而只需要从本地的缓存中使用缓存下的版本。在本地缓存中的所有数据在第二天的更新时间(8:00)之前会被全部清空。图1展示了一个可能的实现体系架构。

图1展示了一个可能的实现体系架构。

   其中,SOAP应用A初始化了一个对产品价格目录的询价请求,具体的SOAP消息如下:

以下是引用片段:
<env:Envelope > 
</env:Body> 
<c:CatalogPriceRequest > 
<c:PartNumber>ABC-1234</c:PartNumber> 
</c:CatalogPriceRequest> 
</env:Body> 
</env:Envelope> 

   缓存中间介SOAP应用B无法依靠其本地的缓存数据库来满足请求,因此它将该请求转发并最终到达询价目录服务SOAP应用C。该服务处理了这个请求,并且将被请求的报价信息装配在响应消息中。在响应消息中,被添加了一个额外的SOAP Header条目,用于在返回的消息路径上控制所有的缓存服务模块。这个 CacheControl SOAP Header条目包含了一个CacheKey元素和一个Expires元素,CacheKey元素被用于在以后的请求发生时,用于匹配被缓存的响应,而Expires元素则设置了本地的副本应当在何时被清理( 失效 )。这个响应消息将通过缓存中间介被返回。

以下是引用片段:
<env:Envelope > 
<env:Header> 
<ca:CacheControl > 
<ca:CacheKey>ABC-1234</ca:CacheKey> 
<ca:Expires>2001-03-09T08:00:00Z</ca:Expires> 
</ca:CacheControl> 
</env:Header> 
<env:Body> 
<c:CatalogPriceResponse > 
<c:PartNumber>ABC-1234</c:PartNumber> 
<c:PartPrice c:currency=”EUR”>120.37</c:PartPrice> 
</c:CatalogPriceResponse> 
</env:Body> 
</env:Envelope> 

   在缓存中间介上,CacheControl SOAP Header条目被用于生成响应消息的本地副本,这个副本可以通过键值CacheKey来标识和访问。同时该副本将在Expires元素所描述的时间被清理出缓存。然后,CacheControl元素被中间介从响应消息中剔除,而报价信息则被返回给最初的请求发送者。从最初的SOAP发送者到最终的SOAP接受者的完整请求 / 响应消息路径即为图1中的消息路径1。

以下是引用片段:
<env:Envelope > 
<env:Body> 
<c:CatalogPriceResponse > 
<c:PartNumber>ABC-1234</c:PartNumber> 
<c:PartPrice c:currency=”EUR”>120.37</c:PartPrice> 
</c:CatalogPriceResponse> 
</env:Body> 
</env:Envelope> 

   当产品ABC-1234的报价信息被缓存在中间介的缓存数据库中后,后继的针对产品ABC-1234的询价SOAP请求就能够被中间介所满足了,此时,实际的SOAP消息路径就变成了图1中较短的请求 / 响应消息路径2。发送非XML数据的模式一般适用于这样的应用背景:数码相机期望能够使用SOAP消息机制通过无线网络连接来将图象数据传送给远程服务器。在SOAP消息中将包含二进制图象数据 ( 非XML)。这个数码相机的应用实例呈现了一个特别的应用情况,此时从接收者到发送者的网络连接是无法建立的,这是因为数码相机这个设备不具备接收连接的能力,当然在其他类似的情形下,可能是因为防火墙的原因。对非XML数据的支持在一些相关的技术文献中已经被提及,“SOAP with Attachments”是一个由W3C接收的规范草稿,其中描述了如何使用类似Email附件的形式在SOAP消息交换中传输非XML的附件。在SOAP规范中也提供了Base64编码的数据类型,以进行少量的非XML数据的传输。其中“SOAP with Attachments”规范已经被ebXML消息服务规范接收为定义具备非XML数据支持的消息结构的基础架构。具体的,支持非XML数据需要有一些额外的消息包装机制,多片断MIME结构是一种适用的包装机制,这种机制将影响和作用于消息与底层通讯协议的绑定。在具体传输时,多个非XML的数据流将被表述成多个MIME结构,也就是形成了多片断的MIME结构。而图中实现的消息装载处理器将生成对这个多片断MIME数据包的一组引用标识,每个引用指向一个MIME片断部分,在SOAP消息正文中,将使用片断标识来引用这些MIME片断。

图2演示了如何使用多片断MIME来包装消息的不同组成部分。

   图2演示了如何使用多片断MIME来包装消息的不同组成部分。其中,最外层的MIME信封包装了一组MIME片断个体。第一个MIME片断包含了一个 SOAP 消息,这个SOAP消息包含了一个由消息装载处理器创建的“装载SOAP Header条目”。第二个及其后面的MIME片断所包含的消息负载可以是 XML 文档,也可以是其他的MIME内容类型的内容,诸如图象、声音或是视频数据等。“装载SOAP Header条目”可以包含引用独立MIME片断的引用标识,这个引用标识与 MIME 片断的内容标识是相一致的。在下面的例子中,我们是使用 XLink 引用来实现的。XLink role 属性可以被用于进一步区分在消息负载中包含的数据的类型。

以下是引用片段:
<env:Envelope > 
<env:Header> 
<n:Manifest > 
<n:Reference n:id=”image01″
xlink:href=”cid:payload-1″
xlink:role=”http://example.org/image”> 
<n:Description>My first holiday photograph</n:Description> 
</n:Reference> 
<n:Reference n:id=”image02″
xlink:href=”cid:payload-2″
xlink:role=”http://example.org/image”> 
<n:Description>My second holiday photograph</n:Description> 
</n:Reference> 
</n:Manifest> 
</env:Header> 
<env:Body> 
—– 
</env:Body> 
</env:Envelope> 

我们一直都在努力坚持原创.......请不要一声不吭,就悄悄拿走。

我原创,你原创,我们的内容世界才会更加精彩!

【所有原创内容版权均属TechTarget,欢迎大家转发分享。但未经授权,严禁任何媒体(平面媒体、网络媒体、自媒体等)以及微信公众号复制、转载、摘编或以其他方式进行使用。】

微信公众号

TechTarget微信公众号二维码

TechTarget

官方微博

TechTarget中国官方微博二维码

TechTarget中国

相关推荐