下载
 Oracle SOA 套件
 
   标签
soa, esb, 全部
 
架构师:SOA

在 SOA 中通过 JMS 存储转发和动态路由实现 Oracle Service Bus 联合

作者:Irene Rusman

2008 年 6 月发表

本文描述 Oracle Service Bus(以前称为 BEA AquaLogic Service Bus)联合的体系结构、设计和配置。联合由通过消息存储转发 (SAF) 系统链接的 Oracle Service Bus (OSB) 集群域形成。具体来说,本文讨论两个外围集群域启动与第三方中央域的请求-响应通信时所处的体系结构。外围域使用 SAF 来传输请求。中央域使用 SAF 将响应传回外围域。

在本文中,您将学习如何配置 Oracle Service Bus 域,并了解一些外围但相关的问题,如联合体系结构中的动态路由和响应相关性。

背景

Oracle Service Bus JMS 是一个支持 Java 消息服务 (JMS) 规范 JMS 1.1 的企业级消息系统,并为标准 JMS API 提供了大量扩展。它紧密集成到 Oracle WebLogic Server 平台中,因此您可以构建可通过 Oracle Service Bus 控制台来监视和管理的安全 Java EE 应用程序。

除完全支持扩展体系结构 (XA) 事务外,Oracle Service Bus JMS 还通过其集群和服务器移植特性提供了高可用性。存储转发特性允许存储一时无法传送的消息,直至目标位置(可能位于远程主机上)可用。SAF 预先采用默认值进行了配置,每个值都可进行调整以满足具体应用的需求。

有三种常见的部署拓扑:

  • 分布式枢纽 — 分布式 OSB 域负责相互路由,无中心协调器。组枢纽服务于各个分组的应用程序域。
  • 企业枢纽 — 作为部门 OSD 域的中央协调器(或企业服务总线)的中央企业 OSB 域。组枢纽反过来服务于各个分组的应用程序域。
  • 组合模式 — 企业和分布式方案的组合。在这种情况下,分布式 OSB 域仍可相互路由,如当服务交互程度较高时。企业 OSB 域可以支持新近并购的企业,将联合与外部应用程序相连。

举例来说,假设一个公司部署了 Oracle Service Bus 企业枢纽:两个外围域连接至一个中央域。此案例在体系结构概述中的“部署拓扑”一节中有述。

下面,我将介绍实现跨域消息传递的企业枢纽的部署体系结构。

部署体系结构和设置

外围域接收来自 JMS 客户端的请求,使用代理服务处理它们,并将它们路由至本地业务服务。该本地业务服务只是一个 shell。它定义为实现传出请求消息存储,并将它们转发到远程中央枢纽。

中央枢纽使用其代理服务处理传入的消息,并将它们路由至本地后端业务服务。当业务服务发送响应消息时,它将首先到达本地代理服务。然后,这一本地代理服务存储传出的响应消息,将它们转发至远程外围域,最终传送至 JMS 客户端。

您至少要配置三个集群域。联合需要两个外围域(下面图 1 中的 Domain 1 和 Domain 2),客户端通过它们向中央域发送初始请求。中央域 (Domain 3) 接收请求,然后通过每个外围域将响应发送回客户端。中央域托管中央代理和后端业务服务。

图 1 描绘了一个企业枢纽体系结构示例。它显示了三个集群域(每个域上都配置了代理和业务服务)、JMS 目标以及请求和响应消息的流程。

企业枢纽体系结构
图 1. OSB 至 OSB(通过 SAF)配置,两个外围代理服务域发送请求至托管后端业务服务的中央域

为简便起见,假设每个域包含一台管理服务器和一个有两台受控服务器的集群。

要描述这一设置,首先介绍名称。两个外围域为 osb1 和 osb2。中央域为 OSB3。集群服务器的名称为:

  • 域 osb1 — osb1Slave0、osb1Slave1
  • 域 osb2 — osb2Slave0、osb2Slave1
  • 域 osb3 — osb3Slave0、osb3Slave1
使用该体系结构,让我们多了解一点我们的目标方案:
  • 第一个 JMS 客户端将请求发送至 osb1 中的请求-响应 JMS 代理服务。第二个 JMS 客户端将请求发送至 osb2 中的请求-响应 JMS 代理服务。
  • 为实现响应的正确分发,这些请求包含“reply-to”属性,由 Oracle Service Bus 在运行时读取。
  • 然后将请求路由至其自己的域 osb1 和 osb2 中的请求-响应 JMS 业务服务。
  • 通过 SAF 将请求转发至 osb3 中的请求-响应 JMS 代理服务。
  • 将请求路由至 osb3 中配置为请求-响应 JMS 业务服务的后端服务。
  • 后端应用程序将响应相关性 ID 设为请求消息 ID,然后按请求消息 ID 来关联响应消息。
  • 后端应用程序读取请求“reply-to”属性以确定响应队列。
  • 将响应置于后端业务服务的响应队列中。
  • 从后端业务服务的响应队列将响应发送至 osb3 中 JMS 代理服务的响应队列。
  • 通过 SAF 将响应转发至 osb1 和 osb2 中业务服务的响应队列。
  • 然后再将响应发送至 osb1 和 osb2 中代理服务的响应统一分布式队列 (UDQ)。
  • 如果客户端按消息 ID 进行关联且入站响应 JMS 相关性 ID 与入站请求 JMS 消息 ID 匹配,则客户端将接收响应(每次 JMS 服务器生成消息时将为消息分配一个 ID)。
这里要记住的重要一点是,Oracle Service Bus 通过合约设定,用户必须履行合约中关于他/她的内容。
  • 中央域 osb3 中的后端用户应用程序必须从消息头部读取“reply-to”属性,并发送响应消息至该目标。
  • 用户必须在中央域 osb3 中的代理服务上按消息 ID 设定相关性。只有这样,才会基于“reply-to”动态设定响应目标,将响应转发至正确的外围域。
所述中央枢纽体系结构是可伸缩的。可以有两个以上的外围域。每增加一个外围域,中央域中入站响应队列的数量将增加,以服务于添加的外围域。

客户端可通过任何外围域自由发送请求以请求中央域中的服务。因此,任一外围域的脱机都不会影响客户端获取中央域中服务的能力。

在中央域中提供后端应用程序可提升集中化服务的重用。客户端得到的好处是,对本地服务使用外围域,对集中化服务使用中央域。因此,企业枢纽中 OSB 域的机构提升了服务使用优化程度。

本文其余部分将描述如何配置这样的企业枢纽。

配置

在以下部分中,您将学习如何配置组成企业枢纽的域。

SAF 配置

从 WebLogic Server 文档的“配置 JMS SAF”一章开始。您可以在本章找到关于 SAF 管理和配置的详细说明。(注:本文面向具有 SAF 经验的高级用户。我将仅列出企业枢纽的 SAF 配置的细节。)

每个域将在集群上部署一个 SAF 代理。中央域 osb3 中的代理服务将获得导出的请求物理统一分布式队列 (UDQ):

ExpReqProxyUDQ-Domain3
外围域 aslb1 和 osb2 中的业务服务将获得相应的导入请求 UDQ:
ImpReqBusUDQ-Domain1
ImpReqBusUDQ-Domain2
使用 JMS 消息 ID 相关性模式时,您需要指定业务服务的本地响应队列(如果需要的话,还要指定每个受控服务器的 UDQ),如了解用于 JMS 请求/响应的消息 ID 模式和相关性 ID 模式中所述。因此,域 osb1 和 osb2 中的代理服务将具有本地导出响应队列。

osb1:

ExpResBusQ1-Slave0
ExpResBusQ1-Slave1
osb2:
ExpResBusQ2-Slave0
ExpResBusQ2-Slave1
中央域 osb3 中的代理服务将具有相应的导入本地响应队列。 转发至 osb1:
ImpResBusQ1-Domain31
ImpResBusQ2-Domain31

转发至 osb2:
ImpResBusQ3-Domain32
ImpResBusQ4-Domain32
外围 osb1 和 osb2 SAF 配置的一个重要元素是 <reply-to-saf-remote-context-name> 参数。SAF 系统读取该参数的值来定义中央域中的响应目标,再将它转发至外围域。<reply-to-saf-remote-context-name> 应是一个完全限定名,包含 JMS 系统模块名称和中央域中远程环境的名称。例如:
<reply-to-saf-remote-context-name>
SystemModuleTest3!DOMAIN31-SAF-REM-CONTEXT
</reply-to-saf-remote-context-name>
使用 WebLogic 管理控制台对导入的其他目标参数中的 <reply-to-saf-remote-context-name> 进行设置,如 WebLogic Server 文档的“配置 JMS SAF”一章所述。

Oracle Service Bus 管道配置

基于 JMS 的 SOAP 消息管道配置细节

WebLogic JAX-RPC Web 服务引擎代码使用以下算法来关联响应消息:如果 JMS 相关性 ID 出现在请求消息上,JAX-RPC Web 服务引擎将在响应消息上设置相同的 JMS 相关性 ID,如果请求上 没有 设置相关性 ID,则将响应相关性 ID 设为请求消息 ID。

对于联合体系结构,我们需要按消息 ID 进行关联,因此,我们需要确保后端应用程序接收到的是未设置 JMS 相关性 ID 的请求消息。因为入站和出站传输都是 JMS,您将要为 WebLogic JAX-RPC Web 服务引擎代码提供所需的头部,方法是,通过使用 Route 节点中的 Transport Headers 动作明文直接传递出站请求消息的传输头部。

要将 JMS 相关性 ID 从传递的头部集中删除,使用另一 Transport Headers 动作删除 JMS 相关性 ID。这将确保 JAX-RPC Web 服务引擎的后端代码将按 JMS 消息 ID 关联响应。

使用动态消息路由选择远程域

如果代理和业务服务端点的静态配置不足以满足当前的使用情况,您可以基于其头部(在运行时读取头部)来路由消息。要完成此目标,您将配置动态路由(或者如果需要响应的话,配置动态发布)。

配置动态路由时,必须指定服务。如果它是纯 JMS 服务,请指定它的完整路径。如果服务基于 WSDL,从 WSDL 中选择它。指定操作是可选的。动态路由和动态发布允许基于消息内容或头部进行动态服务选择,且能基于目标服务转换消息。

以下提供了一个基本示例,说明您可直接提供服务名称或使用 XQuery:

<ctx:route>
   <ctx:service isProxy="false">soapjms/JMSTransportService-BS</ctx:service>
   <ctx:operation>{$operation}</ctx:operation>
</ctx:route>

<ctx:route>
   <ctx:service isProxy="false">{$header/service[0]/text() }</ctx:service>
   <ctx:operation>{$operation}</ctx:operation>
</ctx:route>
您也可以为动态路由创建一个 XQuery 作为资源,并在配置中指定资源的名称。这一路由说明将匹配业务服务定义中的服务和操作(如果提供),并调用该服务(操作)。

动态路由是一个强大的特性。在 OSB 联合的分布式域环境中应用动态路由可以实现向任何远程域发送消息。动态路由是运行时在 Route 节点中执行的消息目标计算。计算结果将覆盖预先定义的目标服务和操作(如果指定有操作)。

组织动态路由的最佳方式是创建路由表。路由表只是一个注册为 XQuery 资源的 XML 文件,如:

<routing>
   <row>
      <logical>osb1</logical>
      <physical>soapjms/JMSTransportService-BS1</physical>
   </row>
   <row>
      <logical>osb2</logical>
      <physical>soapjms/JMSTransportService-BS2</physical>
   </row>
</routing>
您可以使用消息处理的 Assign 动作通过传递逻辑目标来获取物理目标:
<ctx: route>
    <ctx: service>
        {$routingtable/row[logical/text()=$logicalidentifier]/physical/text()}
    </ctx: service>
</ctx: route>
$logicalidentifier 将是用于从消息中提取逻辑标识符的实际 XPath。如果消息在其正文中包含逻辑标识符,XPath 表达式将以 $body 开始。

动态路由的 OSB 配置在 OSB 中建模消息流的“使用动态路由”部分中有述。

使用路由选项设置路由属性

Routing Options 动作用于设置出站 Message Context 变量中的各种属性。这些属性包括 Quality-of-Service、URI 和 Mode,它们影响 Publish 和 Route 动作的行为。尽管可以用 Assign、Insert、Replace 和 Delete 来设置这些元素,但使用这些操作要求对 XPath 和/或 XQuery 以及出站环境变量 XML 结构有一定了解。

Routing Options 动作的目标就是方便用户设置这些属性。另外一个目标是性能,因为自 AquaLogic Service Bus 2.5 开始,入站和出站环境变量的主要表示为 POJO(普通旧式 Java 对象)。这一动作允许直接的 POJO 操作,而不是要首先将 XML 表示实质化,后者是更为常见的转换动作所要求的。

可以使用 Routing Options 动作来操作的一系列属性为:

  • URI — 指定消息发送目的地
  • Mode — 指定通信模式是“只请求”还是“请求-响应”
  • Quality-of-service — 指定服务质量为“尽力”还是“一次性”
  • Retry-count — 指定传输层在遇到传输失败时重试的最大次数
  • Retry-interval — 以微秒为单位指定重试的等待时间
注:当执行 Routing Options 动作时,将从 Message Context 中检索出站环境变量。如果尚未定义变量,将出现错误。不然,该动作接下来将把出站环境变量中的元素设置为动作配置中指定的内容。

结论

本文的目的是展示 Oracle Service Bus 可灵活地形成联合。我们希望鼓励 IT 部门在部署时利用服务总线网络。展望 IT 基础架构的未来发展,这将是正确的战略方式。

配置细节将让高级用户相信服务总线网络的选择是正确的。免去了猜测,提升了最佳实践的传播速度。


Irene Rusman 是 Oracle 的高级软件工程师。她的工作是 Oracle Service Bus 系统集成。