级别: 中级 Jaliya N. Ekanayake, 软件工程师, Lanka Software Foundation
2005 年 12 月 06 日 了解 Apache Sandesha 及其体系结构的概况。Apache Sandesha 是 WS-ReliableMessaging 协议在 Apache Axis 上的实现,Apache Axis 是下一代简单对象访问协议(Simple Object Access Protocol,SOAP),可为 Web 服务提供广泛的支持。随着软件行业逐渐转向面向服务的体系结构 (SOA),越来越流行对许多异构系统进行连接以提供企业解决方案,Web 服务将在这其中扮演重要的角色,而此类连接的基础将主要依赖于它们交换的消息。为了提供这种可靠的通信,必须能在出现软件组件、系统和网络故障的情况下在分布式应用程序之间可靠地传递消息。IBM、Microsoft Corporation、BEA Systems, Inc. 和 TIBCO Software, Inc. 发布的 WS-ReliableMessaging 协议可为以上情况提供与传输无关的解决方案,从而允许使用不同的网络技术对其进行实现。
模型
WS-ReliableMessaging 协议提供了使用端点管理器 (EPM) 概念的可靠传递消息的解决方案。所建议的模型使用了两个 EPM,即可靠消息传递 (RM) Source 和 RM Destination,用于处理消息的可靠传递。图 1 以非常抽象的方式显示了它们之间是如何交互的。
图 1:可靠消息传递模型
根据以上的模型,消息的可靠传递由 RM Source 和 RM Destination 进行处理,同时提供到 Application Source(Web 服务客户机)和到 Application Destination(Web 服务)的透明消息路径。
Sandesha 体系结构
Sandesha 是在 Apache Axis 上实现的,而 Sandesha 的体系结构主要受 Axis 的体系结构和上面图 1 中所示的机制的影响。根据规范中的说明,一项核心要求就是 RM Source 要具有端点引用。
“RM Source 必须具有唯一标识 RM Destination 端点的端点引用;以此唯一端点为目标地址的消息间的关联必须有意义。”(有关详细信息,请参阅参考资料中的 WS-ReliableMessage 规范。)
Axis 体系结构提供了一个同步消息传递框架。因此,仅使用 Axis 的功能,Sandesha 是不能支持异步消息传递要求的。所以,除了提供可靠消息传递功能之外,Sandesha 体系结构还必须提供一个异步消息传递框架。为了同时支持这两个要求,Sandesha 引入了一个具有到客户端和服务器端的独立 Sender 和 Receiver 的体系结构。为了支持根据特定的 EPM 在 Sender 与 Receiver 之间建立连接,Sandesha 体系结构将在缺省情况下使用内存中的队列。该体系结构提供了插入数据库(而非队列)的功能,这最终使得信息具有持久性。
高级体系结构如下面的图 2 所示。
图 2:Sandesha 的高级体系结构
此体系结构提供了对同步消息传递和异步消息传递方案的全面支持。当采用异步模式时,WS-Addressing 提供关于消息间相关的信息。不过,通过使用双向传输(如 HTTP),在可以通过同一个连接发送对请求的确认信息,如图 2 中的虚线所示。所以,两端的发送方应该据此做好处理这种情况的准备。
Apache Axis 上的 Sandesha 体系结构
在图 2 中添加了特定于 Axis 的组件后,将出现该体系结构的一个更为详细的视图。图 3 所示为 Sandesha 的完整体系结构。
图 3:Apache Axis 上的 Sandesha 体系结构
图 3 所示为 RM Source 和 RM Destination 中的组件。尽管图中的每个 RM 端点仅有一个 Axis 引擎,Sender 和 Receiver 都将在其发送和接收功能中使用 Axis,从而提供了一个完全基于 Axis 的体系结构。下面将对图 3 中的各个组件进行更为详细的描述。
Client:这是调用(使用)Web 服务的程序。根据高层体系结构中的描述,这就是 Application Source。Sandesha 提供了在 Client 上使用单个 RM Source 调用多个 Web 服务(可能在不同的 RM Destination 中)的功能。
SandeshaContext:此组件向用户提供 API 以设置各种特定于 RM 的参数。Axis 的调用机制主要基于 Call;不过,SandeshaContext 却是用于从客户机代码将额外的参数传递给特定于 Sandesha 和 Axis 的组件。如果 Client 需要覆盖缺省值,则使用此 Client 可以设置 WS-Addressing 的值。另外,SandeshaContext 还可以用于为 RM Source 设置各个运行时参数。
Call component:此组件为 Axis 的调用机制。此组件提供一个客户机的同步调用(使用单个传输连接阻塞 Client)范型。如果 Web 服务客户机需要非阻塞调用(仍然使用单个传输连接),则 Client 应该使用 AsyncCall,而非 Call。Sandesha 同时提供了在 Client 上使用 Call 和 AsyncCall 的功能。
Axis engine:此组件为 Apache Axis 的引擎,此引擎实质上是一个简单对象访问协议 (SOAP) 引擎——用于构造 SOAP 处理器(如客户机、服务器、网关等等)的框架。
RMSender:此组件为传输发送方,用户应当使用此发送方以启用 Aix 引擎的客户端上的可靠消息传递。不过,RMSender 将不会直接将请求写到传输层,而是将请求插入到“Queue”中。
Queue:这是 Sandesha 的持久层。可靠解决方案的是通过使用内存中的 Queue 实现的。不过,Sandesha 提供了可扩展的存储管理器 API,该 API 将基于数据库以相当直接的方式实现存储。(Sandesha 目前仅支持内存中的 Queue。)尽管 Queue 充当单个组件,但是,它将为传入和传出的消息维护两个队列。此外,Queue 的接口将由两个存储管理器控制,即 ClientStorageManager 和 ServerStorageManager。这两个存储管理器(未在图 3 中显示)使用 Queue 为 RM Source 和 RM Destination 提供了所需的功能。
Sender:这是线程池中正在运行的用于发送请求消息的线程。Sandesha 在客户端和服务器端都使用相同的 Sender 组件。Sender 用于发送从特定 EPM(RM Source 或 RM Destination)流出的所有消息。
当 Sender 使用双向传输协议(例如 HTTP)发送请求时,接收方可能会使用同一个连接发送确认信息(即当 <wsrm:AcksTo> 地址设置为匿名的统一资源标识符 (URI) 时。请参阅参考资料部分中的第一个和第三项参考。)尽管 Sandesha 会处理在同一个传输连接中发送的确认信息,但不支持在同一个传输连接中发送的应用程序响应。
Receiver:这是客户端的侦听器,是用作 Sandesha 的接收方的 Axis 的 SimpleAxisServer。Receiver 的功能是接受匿名 SOAP 消息,并根据消息本身中的关联信息将其插入到 Queue 中。Sandesha 在 Receiver 内使用的配置与在 RM Destination 中使用的配置相同,因此会使用相同的组件处理异步响应。(在 Sandesha 体系结构中,异步响应将作为传入请求进行处理。不过,响应不是用于调用 Web 服务,而会根据各自的关联信息将其插入到“Queue”中。)
RMProvider:此组件为 Sandesha 在服务器端 Axis 引擎内的使用的提供程序。RMProvider 将对传入消息进行标识,并将需要的消息插入到 Queue 中。它还将生成特定于可靠消息传递的消息,如 Acknowledgement 和 Terminate Sequence 消息。
RMInvoker:此组件为将 Web 服务请求调度到实际的服务的可运行组件。RMInvoker 还将服务请求(如果有)放入服务器端上的 Queue 中。Sandesha 提供了使用多个 RMInvoker 线程调度 Web 服务请求的功能,允许 Web 服务调用部署在同一服务器上的其他 Web 服务,而不会进入死锁状态。
Service:这是 Web 服务本身。在高层体系结构中,将其称为 Application Destination。
完整的消息传递场景说明
Web 服务客户机可以通过很多方式使用 Web 服务,具体取决于诸如服务操作(IN-OUT、IN-ONLY 等等)的消息交互模式 (MEP)、传输连接以及 Web 服务引擎为客户机应用程序提供的阻塞 API 和非阻塞 API 等因素。Apache Sandesha 提供了使用 Axis 为具有可靠消息传递的 Web 服务客户机提供的所有调用模式的功能。以下的消息传递场景说明了 RM Source 和 RM Destination 中不同组件的调用序列。
RM Source 中 SandeshaContext 的初始化
调用 Web 服务前,需要客户机应用程序对 SandeshaContext 进行初始化。Sandesha 建议的模型要求用户首先为 SandeshaContext 设置必需的参数,然后对其进行初始化。根据 WS-ReliableMessaging 规范,单个 SandeshaContext 的实例表示单个序列。不过,如果 Client 通过创建很多 SandeshaContext 实例的方式创建了许多序列,则 SandeshaContext 将作为序列的集合。图 4 演示了初始化 SandeshaContext 时的调用序列。
图 4:SandeshaContext 的初始化
结束 RM Source 中的序列
一旦 Client 接收到响应,或者,重新获得控制(如果这些响应是单向消息),则 Sandesha 要求 Client 通过使用 SandeshaContext 显式地通知 RM Source“结束”序列,SandeshaContext 将随后检查所有的活动序列,并尝试一一将其终止。SandeshaContext 等待特定序列的最大等待时间就是该序列的“不活动”超时时间。图 5 显示了序列终止的步骤。
图 5:结束序列
服务调用——双向(服务有响应。)
在此场景中,Web 服务客户机将调用 Web 服务的 IN-OUT 操作。在 Sandesha 中,将在异步环境中支持这种类型的 IN-OUT 操作,例如,使用独立的传输连接发送请求并接收响应。在此场景中,必须假定将 <wsrm:AcksTo> 值设置为匿名 URI,且在 <wsrm:CreateSequence> 标头中发送 <wsrm:Offer>,从而为 Web 服务响应提供序列。
RM Source
图 6 显示了客户端上的此场景的调用序列。
图 6:服务调用——RM Source
- Client 初始化 SandeshaContext,如图 4 中所示。
- Client 调用 Call。(这是 Client 调用 Axis engine 的位置。)
- RMSender 创建所需的特定于可靠消息传递的消息(Create Sequence、Terminate Sequence 等等),并将其与请求消息一起插入 Queue 中,并持续监视 Queue,直到接收到响应为止。
- Sender(在初始化步骤中已经由 SandeshaContext 启动)将持续监视要发送的消息的 Queue(通过 ClientStorageManager),找到新消息,并将其发送到目的地。Sender 仅获取可用于发送的消息。此机制验证:一旦 Create Sequence 操作完成,且消息使用恰当的定时设置重新传输, Sender 就发送 Web 服务请求。
- 在此场景中,Sender 首先发送 Create Sequence 请求。根据
<wsa:ReplyTo> 地址值,RM Source 可以使用同一个传输连接和不同的传输连接接收 Create Sequence 响应。无论在哪一种情况下,都会使用响应消息对 Queue 进行更新。这将允许 Sender 发送 Web 服务请求消息。只要消息没有得到确认,或者,根据 RM 策略断言,没有达到其不活动超时时间,特定的消息都可以用于发送。
- 一旦收到了所有消息的确认,Queue 允许 Sender 发送 Terminate Sequence 消息。
- 无论何时,只要 Receiver 接收到消息,它都将标识该消息,并使用消息中的关联信息作为地址标头更新 Queue。在此场景中,只要 Receiver 接收到 Web 服务请求,它将创建需要发送到 RM Destination 以确认收到 Web 服务请求的确认消息,并将其插入到 Queue 中。此消息将稍后由 Sender 拾取,并发送到 RM Destination。一旦 RM Destination 接收到了所有响应的确认,它还会发送此响应序列的 Terminate Sequence message 消息。
- 当 RMSender 在 Queue 中找到可用的 Web 服务响应时,它会将此响应返回给客户机应用程序。在这种情况下,无论 Client 使用 Axis 的 Call 还是 AsyncCall,都对 RMSender 的操作没有任何影响。
- 当 Client 获得了其所有调用的响应时,Sandesha 要求客户机应用程序结束序列。在此阶段,RM Source 将清理存储区,如果没有活动序列,它将通过将控制传输回 Client 而停止 Sender 和 Receiver。
服务器 EPM
当接收到消息时,RM Destination 中执行的步骤如图 7 所示。请注意,当初始化 Queue 时,Sender 和 Invoker 将仅在发送到特定 RM Destination 的第一条消息时才会出现。
图 7:服务调用——RM Destination
-
RMProvider接收消息,如果该消息是一个 Web 服务请求,则就将其插入到 Queue 中。如果此消息是特定于协议的消息,如 Create Sequence Request、Acknowledgement Request 或 Terminate Sequence 消息,则将执行必要的操作。例如,如果消息是确认的请求,则将确认消息插入到用于发送回的 Queue 中。
- RMInvoker 将监视 Queue(通过 ServerStorageManager)以获得 Web 服务请求并调用相应的服务。该组件假设 Queue 已对消息进行了正确的排序,以便由其进行调度。如果服务请求有响应,则 RMInvoker 会将此响应插入到 Queue 中,以发送回 Client。如果此消息为第一个响应消息,RMInvoker 还会插入一条 Create Sequence Request 消息。(仅在从 Client 发送第一个请求时没有使用
<wsrm:Offer> 指定输出序列时才这样。请参阅参考资料部分中的第一项参考。)当该序列的最后一条响应消息插入了 Queue 中时,RMInvoker 还将插入 Terminate Sequence 消息。
- 与 RM Source 中相似,发送方将持续监视 Queue,以获得要发送的消息,并将对这些消息进行标识,然后立即将其发送到 RM Source。
如果客户机使用 IN-ONLY 操作调用 Web 服务,则 RM Source 和 RM Destination 中的调用序列都将为图 7 中所示的序列的子集。RM Source 中将没有等待时间,直到从 RM Destination 中的发送部分获得响应。
结束语与进一步的工作
Sandesha 在 Apache Axis 上实现了 WS-ReliableMessaging 协议。这使得可以在 Axis 范围内可靠地通过 Axis 自身以及其他实现上述协议的 Web 服务平台(如 Microsoft .NET )执行 Web 服务调用。Sandesha 目前并不提供软件组件故障的持久性功能;不过,可以通过将数据库(而非内存中的 Queue)作为 SOAP 消息的存储区实现这个功能。未来的开发工作将主要集中于这一方面的工作,还要在 Apache Axis 2 上实现 Sandesha(Apache Axis 2 是还在开发中的 Axis 的新版本)。
参考资料 学习
获得产品和技术
-
您可以通过以下链接免费下载 WebSphere,Lotus,DB2,Rational 产品的评估版。
讨论
关于作者  | 
|  | Jaliya 目前是位于印第安那州布卢明顿的印第安纳大学 (University of Indiana) 的一名研究生,主修计算机科学。他获得了斯里兰卡的莫勒图沃大学 ( University of Moratuwa ) 学士学位。他还是 Lanka Software Foundation 的成员,Apache Sandesha 和 Apache Axis2 的委员,并且还是 Apache Sandesha 的 PMC 代表。Jaliya 具有两年的软件工程工作经验,曾供职于 Virtusa Corporation 和 Lanka Software Foundation。 |
对本文的评价
|