Web 服务可靠消息传递重载

了解 WS-ReliableMessaging 规范更新

Comments

引言

Web 服务中的可靠消息传递的目的在于允许应用程序间以简单、可靠、有效的方式发送和接收消息,甚至在应用程序、操作系统平台或网络连接失败的情况下也能如此。最近由 IBM®、BEA®、Microsoft® 和 Tibco® (参见 参考文献) 发布的 WS-ReliableMessaging 规范 (WS-RM) 定义了一个协议和一组机制,使 Web 服务的开发人员能够确保在两个端点之间可靠地传递消息,该规范还具有各种传递保证和健壮性特征。

相对于 2004 年 3 月版本的变化

相对于 2004 年 3 月发布的版本,WS-RM 规范最值得注意的变化是版权。规范的作者在 royalty-free (RF) 条款下发布了 WS-RM 规范。如果您已经订阅了规范实现,这将是一个好的消息。尽管编者的 publicly-stated 保证所有 WS-* 系列的规范都可在 RF 协议下获得。

至于在技术内容方面,实际上协议并没有很大改动。改动的大部分都是源于参与者的反馈、互操作 Workshop (参见参考文献)的讨论和随后的端点测试,这些修改大大改进了规范。大部分的变动都与创建 RM 序列相关。

新的命名空间 URI

所有的 WS-RM 协议元素被指派为如下新的命名空间 URI :

http://schemas.xmlsoap.org/ws/2005/02/rm

可靠消息传递模型

可靠消息传递模型除了下面的一处改动,基本没有任何变动:CreateSequence 握手交换和 TerminateSequence 消息现在成为必需的,而不再是可选的。

作者作出此修改是为了确保对于终止的 RM 序列,在 RM 的目的地端能够进行有效的资源回收。因为 RM 目的地端分配序列号标志符,一旦序列被终止,RM 的目的地端能够清除所有与终止的序列相关的资源。另外,RM 的目的地端可以安全的将一些接收到的消息丢掉,不管这些消息属于一个被终止的序列还是属于一个无效的序列。

应用程序源和目的地以及 RM 的源和目的地的角色相对与上一个版本没有发生变化,它们都支持至多一次、至少一次、仅一次和顺序类型的传输保证。

图 1. 可靠消息传递模型
可靠消息传递模型
可靠消息传递模型

在以前的版本中,RM 协议的核心思想在于消息序列的概念。RM 源通过发送 CreateSequence 来创建一个序列。RM 目的地通过 CreateSequenceResponse 消息来回应,它指派了一个唯一的序列 Identifier

需要可靠传输保证的每个消息都包含一个序列头部区域。序列头部区域包含一个唯一的序列 Identifier。 序列中的每个消息被指派一个唯一的 MessageNumber。它从 1 开始并对序列中随后的消息依次增长。RM 目的地端通过包含一个 SequenceAcknowledgement 头部区域来成功回应接收到的消息,在消息中向 RM 源返回接收到的序列中消息的全部范围。这允许以不可靠的方式发送回应,因为这一特定信息几乎在每个 SequenceAcknowledgement 消息中都被携带。

RM 源通过在Sequence 头部区域中包含一个 LastMessage 子元素来标志序列中的最后一个消息。在序列生命周期的任一时间,RM 源都可以发送一个包含 AckRequested 头部区域的消息,这一消息请求 RM 目的地端发送 SequenceAcknowledgement 消息来响应。

一旦 RM 源接收到序列中的所有消息都被成功接收的确认后,它发送一个 TerminateSequence 消息,用来结束序列。只要 RM 目的地端接收到 TerminateSequence ,它就可以安全地将所有与序列相关的状态信息丢弃掉。

协议元素

在规范的第 3 部分定义的协议元素中, SequenceSequenceAcknowledgementAckRequested 头部区域元素基本没有变化,除了上述三者的 Identifier 命名空间发生变化,以及 可选的 Expires 元素从序列中去掉。序列的生命周期通过 CreateSequence 操作来建立(参见下面的 "序列创建" 一节)。另外,还提到了一处 schema 与规范之间细小的不一致(例如,规范前面的修正删除了通过 schema 实现的特定的扩展点)。

清单 1 所示的如下代码片断中演示了 SequenceSequenceAcknowledgementAckRequested 元素的新的格式:

清单 1. 示例: SequenceSequenceAcknowledgementAckRequested
<wsrm:Sequence>
  <wsrm:Identifier>http://example.com/sequence/564</wsrm:Identifier>
  <wsrm:MessageNumber>1</wsrm:MessageNumber>
</wsrm:Sequence>
<wsrm:SequenceAcknowledgement>
  <wsrm:Identifier>http://example.com/sequence/564</wsrm:Identifier>
  <wsrm:AcknowledgementRange Upper="3" Lower="1"/>
</wsrm:SequenceAcknowledgement>
<wsrm:AckRequested>
  <wsrm:Identifier>http://example.com/sequence/564</wsrm:Identifier>
</wsrm:AckRequested>

Sequence 创建

CreateSequenceCreateSequenceResponse 元素根据 2004 年 3 月执行的 WS-RM 互操作试验的反馈进行了修改。第一个变化是在 CreateSequence 中添加了 AcksTo 子元素。

添加了此元素后,RM 目的地端发送 SequenceAcknowledgement 的端点就可以在序列创建的时候建立。规范以前的版本并没有定义那些 RM 目的地端用来发送 SequenceAcknowledgement 消息的目标端点,因此,实现者一般通过 wsa:From 来区分将 SequenceAcknowledgement消息发送到端点。虽然这种方法在大多数情况下都能解决问题,但是编写者认为上述方法应该排除以下特定情况,即端点接收到的 SequenceAcknowledgement 消息可能来自一个不同与原始消息发送者的其它地址(如,被管理端点或 RM 代理)。另外还有一些问题比如如何处理 wsa:From 的值在序列的过程中发生变化这一情况。编者选择添加 AcksToCreateSequence,因为它可以避免在序列的消息与消息间的 wsa:From 的多种可能带来的各种问题。

xsd:duration 类型的一个可选元素 Expires 作为一个子元素被添加到 CreateSequence 消息。如果 Expires 元素出现,它说明所产生序列的期望的生存周期。 如果没有出现或设置为 0 (表示为值 PT0S),它暗示序列将永远不会过期。编者作出此改变主要考虑到使用 Sequence/Expires 元素所产生的问题。例如,如果它的值在序列的生命周期中发生变化,RM 目的地端是否需要对这种变化作出响应?进一步讲,因为 Sequence/Expires 元素是 xsd:datetime 类型的,这就产生了需要同步 RM 源和目标端点的时钟同步问题。通过将类型变为 xsd:duration 并在 CreateSequence 中定义其值,这些问题就能够很容易解决。

最后,为了有效地支持与 WS-Security 系列规范的整合,CreateSequence 元素可以包含一个 WS-Security 相关的 SecurityTokenReference (STR) 来作为安全令牌,RM 目的地端应该利用它来为创建的序列认证接收到的消息。 因此,序列内所有发送的消息必需保证它们拥有 STR 引用的 key,否则 RM 目的地端将会把它们丢弃。

清单 2. 示例: CreateSequence 消息
<S:Envelope xmlns:S="http://www.w3.org/2003/05/soap-envelope"
    xmlns:wsrm="http://schemas.xmlsoap.org/ws/2005/01/rm">
 <S:Header>
  ...
 </S:Header>
 <S:Body>
  <wsrm:CreateSequence>
    <wsrm:AcksTo>
      <wsa:Address>http://example.com/rm/endpoint</wsa:Address>
    </wsrm:AcksTo>
    <wsrm:Expires>PT0S</wsrm:Expires>
  </wsrm:CreateSequence>
 </S:Body>
</S:Envelope>

序列双向协同

CreateSequence--CreateSequenceResponse 交换的另外一个变化是增加了序列双向协同优化的支持。在 WS-RM 规范前面的版本中,如果两个端点在每个方向都需要建立 RM 序列,那么每个端点都需要调用 CreateSequence 操作,这样,总共需要 4 条消息。编者添加了这种能力来通过在 CreateSequence 中添加一个 Offer子元素以及在 CreateSequenceResponse 中相应地添加一个 Accept 子元素 来为一个端点可选地提供一个响应序列 (在这种情况下,两个端点 RM 源和目的地的角色将发生互换)。这种优化允许 端点通过一个单一的消息交换对创建响应的 RM 序列。

下述的清单 34 SOAP 消息示例演示了一个实际的序列双向协同。 第 1 个消息 (清单 3) CreateSequence 请求创建一个新的序列并通过 Identifier http://example.com/sequence/67 来提供一个响应序列。 第 2 个消息 (清单 4) 中 CreateSequenceResponse 说明创建一个新的序列的请求被接受。 新建的序列携带一个 Identifier http://example.org/sequence/42 。 另外,响应端点通过在 CreateSequenceResponse 消息中包含一个 Accept 元素来表示接受提供的序列, SequenceAcknowledgement 消息已经发往这一端点。

清单 3. 示例:带有序列双向协同的 CreateSequence 消息
<S:Envelope xmlns:S="http://www.w3.org/2003/05/soap-envelope"
xmlns:wsrm="http://schemas.xmlsoap.org/ws/2005/01/rm">
 <S:Header>
  ...
 </S:Header>
 <S:Body>
  <wsrm:CreateSequence>
    <wsrm:AcksTo>
      <wsa:Address>http://example.com/rm/endpoint</wsa:Address>
    </wsrm:AcksTo>
    <wsrm:Expires>PT0S</wsrm:Expires>
    <wsrm:Offer>
      <wsrm:Identifier>http://example.com/sequence/67</wsrm:Identifier>
      <wsrm:Expires>PT0S</wsrm:Expires>
    </wsrm:Offer>
  </wsrm:CreateSequence>
 </S:Body>
</S:Envelope>
清单 4. 示例:带有序列双向协同的 CreateSequenceResponse 消息
<S:Envelope
xmlns:S="http://www.w3.org/2003/05/soap-envelope" 
  xmlns:wsrm="http://schemas.xmlsoap.org/ws/2004/12/rm">
  <S:Header>
    ...
  </S:Header>
  <S:Body>
    <wsrm:CreateSequenceResponse>
      <wsrm:Identifier>http://example.org/sequence/42</wsrm:Identifier>
      <wsrm:Expires>PT0S</wsrm:Expires>
      <wsrm:Accept>
        <wsrm:AcksTo>
         
<wsa:Address>http://example.com/rm/endpoint</wsa:Address>
        </wsrm:AcksTo>
      </wsrm:Accept>
    </wsrm:CreateSequenceResponse>
  </S:Body>
</S:Envelope>

序列终止

TerminateSequence 元素基本没有变化除了 Identifier 元素的命名空间的改变以及提到的在 schema 和规范之间的一些小的不一致。

清单 5. TerminateSequence 消息示例
<S:Envelope xmlns:S="http://www.w3.org/2003/05/soap-envelope"
    xmlns:wsrm="http://schemas.xmlsoap.org/ws/2005/01/rm">
 <S:Header>
  ...
 </S:Header>
 <S:Body>
  <wsrm:TerminateSequence>
    <wsrm:Identifier>http://example.com/sequence/67</wsrm:Identifier>
  </wsrm:TerminateSequence>
 </S:Body>
</S:Envelope>

RM 策略声明

2004 年 3 月版本的规范中的 RM 策略声明部分被进行更改来遵循最新的 WS-Policy 系列规范,并且新加了一个独立的规范:WS-RM 策略声明(参见 参考文献)。

修订的 WS-RM 策略声明规范定义了一个单独的策略声明(RMAssertion)并将前面定义的 RM 策略声明(InactivityTimeoutBaseRetransmissionIntervalExponentialBackoffAcknowledgementInterval)作为 RMAssertion 的子元素和属性,就像下面的清单 6 所示。这些属性(以前的声明)的语法与前面的 WS-RM 规范保持一致。

清单 6. RM 策略声明示例
<wsp:Policy wsu:Id="MyRMPolicy" >
  <wsrm:RMAssertion>
    <wsrm:InactivityTimeout Milliseconds="600000" />
    <wsrm:BaseRetransmissionInterval Milliseconds="3000" /> 
    <wsrm:ExponentialBackoff /> 
    <wsrm:AcknowledgementInterval Milliseconds="200" />
  </wsrm:RMAssertion>
</wsp:Policy>

另外,WS-RM 策略声明规范的 RMAssertion 与端点策略主题相对应。WS-PolicyAttachments 为 WSDL1.1 定义了附件节点,对于端点策略主题来讲,就好比 portTypebindingport。然而,因为 WS-RM 是一个 SOAP 协议,这并不意味着将 RMAssertion 绑定到 wsdl:portType,因为它也可绑定到一个非 SOAP 绑定。因此,携带端点策略主题的 WS-Policy 附件可将 RMAssertion 附加到 WSDL1.1 定义的其余附件节点,称为 bindingport

RM Faults

RM Faults 这一节大部分没有改变,尽管它被更新为采用与最近发布的 WS-Addressing 规范一致的文档类型来定义如何绑定 fault 属性到 SOAP1.1 和 SOAP1.1 。

附录

WS-RM 规范的附录被更新来反映规范在 schema 和消息交换示例上的变化。另外,还包含一个 WS-RM portType 操作的抽象的 WSDL1.1 描述。

结束语

相对与以前的版本,新近修正的 Web 服务可靠消息传递规范有了很大提高。这种提高在很大程度上归功与实践经验以及在互操作试验(参见 参考文献)期间获得的众多反馈. 然而,协议的基本思想仍旧与以前版本的规范在很大程度上保持一致。


相关主题


评论

添加或订阅评论,请先登录注册

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=SOA and web services
ArticleID=58277
ArticleTitle=Web 服务可靠消息传递重载
publish-date=03012005