分享

互用性技术:数据层

 欢欢2008 2011-03-31

互用性技术:数据层

发布日期 : 10/20/2004 | 更新日期 : 10/20/2004

Microsoft Corporation

摘要: 集中讨论应用于数据或资源层的技术。涉及的技术包括共享数据库和异步消息队列。最后,本章简要讲述了其他的异步技术如在 Microsoft Host Integration Server 中使用 MSMQ-MQSeries Bridge。

本页内容

简介 简介
通过共享数据库链接 通过共享数据库链接
实现异步互用性 实现异步互用性
使用 Host Integration Server 2000 使用 Host Integration Server 2000
小结 小结
参考资料 参考资料

简介

第 4 章,“互用性技术:点对点”,描述了实现点对点互用性技术,如 .NET 远程处理和 Web 服务。这一章讲述的技术可以帮助您在 .NET Framework 和 Java 应用程序的数据层(如数据库连接和通过消息队列异步连接)之间实现连接。

一个互用性场景是您有一个现有的数据仓库,您现在要从 .NET Framework 和 Java 应用程序中访问它。结合创建共享数据库的最佳实践建议,本章考虑如此一个设置的含义。

.NET 远程处理和 Web 服务在 intranet 上或者跨越 Internet 提供链接紧耦合或松耦合系统的能力。然而,这些技术无法处理必须经受很长的滞后时间或者非永久连接环境,例如,越来越多地使用通过某种形式的无线链路进行连接的手持设备。异步方法可以克服非永久链接的问题。

通过共享数据库链接

您可能遇到过这样的情况,有两个应用程序在不同的平台,而您要使它们共享同一个基础数据库。这种配置解决了要维护多个数据存储区的问题。在 .NET Framework 和 J2EE 应用程序间共享一个数据库是在这两个环境间实现互用性的一个简单而有效的方法。

5.1:.NET Framework 和 J2EE 应用程序共享一个公共数据库

使您能这样做的技术并不是新的。自从这两个平台问世以来,它们就都有各自的数据库连接实现的机制。数据库驱动程序的存在使您可轻松地将业务层应用程序链接到一个公共的后端存储区,及在两个平台间共享表、记录和字段。

这两个平台都可提供到多个数据库的链接,如 Microsoft SQL Server、Oracle、Informix、MySQL 和 DB2。这一节讨论 .NET Framework 和 Java 应用程序同时连接数据库的方法和一些共享数据库的最佳实践。

在您了解如何共享数据库之前,您必须清楚每个平台如何连接到数据库。每个平台都有一个内置的数据访问 API:

  • .NET Framework 中的 ADO.NET。

  • Java 中的 JDBC。

对大多数实现来说,您选择的数据库和平台不应该是一个要考虑的因素。

虽然在本节中的示例参考的是 SQL Server 2000,但是这里说明的这些策略可以应用于所有的数据库。

用 JDBC 连接

JDBC 是允许 J2EE 应用程序访问任何兼容数据库中的表、记录、字段和存储过程的 API。您可以用 JDBC 连接几乎所有的表格数据,包括电子表格和平面文件格式中的信息。

JDBC 3.0 是该规范的最新的版本,现在有许多供应商承认,包括 IBM、Hewlett-packard、BEA、Simba 和 Oracle。Sun 最近提出了 JSR221,这包含了 JDBC 4.0 API 的规范。

Java 2 Platform, Standard Edition (J2SE) 1.4 在软件包 Java.sqlJavax.sql 包含了对 JDBC 3.0 完整的支持。这些软件包中的类和接口允许 Java 应用程序访问任何它们拥有 JDBC 数据库驱动程序的数据库。

有四种类型的 JDBC 数据库驱动程序:

  • 类型 1(JDBC 到使用 ODBC 驱动程序的 ODBC bridge))第一种类型的驱动程序通过 ODBC 驱动程序提供对 JDBC 的访问。Sun 在 J2SE 中提供了一个 JDBC-ODBC 桥接驱动程序驱动程序,如果没有其他的驱动程序可用,您可以使用它。第 1 种类型的驱动程序要求在客户端计算机上安装本机代码。

  • 类型 2(带有 Java 技术驱动程序的本机 API)第 2 种类型的驱动程序将 JDBC 调用转换为对客户端 API 的调用。就像第 1 种类型的驱动程序一样,这种实现也要求在客户端计算机上安装本机代码。

  • 类型 3(用于数据库中间件的纯 Java 驱动程序)第 3 种类型的驱动程序将 JDBC 调用转换为中间件供应商的协议。中间件然后将此协议转换为 DBMS 调用。您不必在客户端计算机上安装任何本机代码,但是您必须为 Internet 操作指定安全配置设置。

  • 类型 4(直接到数据库的纯 Java 驱动程序) 第 4 种类型的驱动程序直接将 JDBC 调用转换为 DBMS 调用,并且使用本机协议访问数据库。

类型 4“纯 Java”驱动程序是首选项,因为它们通常可提供最好的性能。

JDBC 使用了 ResultSet 的概念。一个 ResultSet 是满足 SQL 语句条件的所有行的集合。您可以用 get 方法访问 ResultSet 中的数据,它可以使您遍历当前行中的所有列。您也可以使用 ResultSet.next移动到下一行。

应用程序可以执行多个语句并且随后处理任意数量的结果集。产生 ResultSet 的语句通过结束语句、再次执行该语句或者从多个结果序列中返回下一个结果的方法自动结束。

ResultSet 类似于 ADO.NET 的 DataSet。然而,ResultSet 更接近于 ADO RecordSet,以前的 .NET 数据库访问 API 对象。

有关 ResultSets 的更多信息,请参阅 Java Web 站点的“JDBC Guide: Getting Started”。有关使用 JDBC 的更多信息,请参阅 Java Web 站点上的“JDBC Data Access API”。

JDBC 连接到 SQL Server 2000

您可以在 Java 应用程序中使用众多 JDBC 驱动程序中的任何一种访问 SQL Server 2000,这些驱动程序也许是免费的,也许是需要付费的。例如,Microsoft 提供了 Microsoft SQL Server 2000 Driver for JDBC Service Pack 1。这是第 4 种类型的 JDBC 驱动程序,它为 J2EE 应用程序提供具有高度伸缩性和可靠性的连接。此驱动程序为任何支持 Java 的 applet、应用程序或者应用程序服务器提供到 SQL Server 2000 的 JDBC 访问。

有关 Microsoft SQL Server 2000 Driver for JDBC Service Pack 1 的更多信息(包含下载信息),请访问 Microsoft Download Center

当使用一个 JDBC 驱动程序连接到 SQL Server 2000 时,确保 SQL Server 上的安全设置使用 SQL Server 和 Windows 身份验证(混合模式身份验证)。同样,确保您为 sa 帐户设置一个复杂(混合大小写字母和数字)的密码。

有关使用 Microsoft JDBC 驱动程序连接 SQL Server 2000 的更多信息,请参阅 Microsoft 知识库文章 Q313100“HOW TO: Get Started with Microsoft JDBC”。

用 ADO.NET 连接

访问关系数据库中的数据始终是 Microsoft 平台的一个功能。在 .NET Framework 到来之前,ActiveX 数据对象 (ADO) API 是主要的数据库访问机制。.NET Framework 引入 ADO.NET 作为 Microsoft 平台上连接数据库的新 API。

ADO.NET 表现了抽象的设计概念,那就是您需要在 .NET Framework 内建立数据访问类。ADO.NET 允许您使用数据而不必顾及数据源、数据格式或者数据的物理位置。它包括了新的对象模型,并提出了新概念,如 DataSetDataReader 类。

ADO.NET 通过淡化以数据库为中心的特性及进一步结合现代的基于 Web 服务的编程,在 ADO 的基础上进行了改进。它在分布式环境中工作得很好并且使开发人员快速和可靠地链接数据源。

ADO.NET 有几个主要的设计目标:

  • 清楚的、可分解的对象模型 ADO.NET 提供了易用的对象模型,开发人员对如何控制数据源连接、命令执行和数据操作有完全的控制权。

  • 断开连接的数据缓存模型 N 层编程和 XML Web 服务体系结构要求应用程序可以以断开连接、松散耦合的方式工作。ADO.NET 为应用程序或服务间封送处理数据提供全面的缓存数据模型并且随后更新原始数据源。

  • 带有 数据组合功能的通用数据表示 ADO.NET 给予您组合来自多个数据源和不同数据源的数据的能力。

  • XML 支持 要构建可互用的应用程序和非常可靠的数据处理模型,XML 是个关键的组件。ADO.NET 通过用相关的方式或本机 XML 和 XML 交互的方法使用 .NET Framework 中的 XML 支持。

  • 使用现有的 ADO 知识 虽然 ADO.NET 对象模型不同于先前的 ADO 模型,但是基本的构造是一样的。ADO.NET 对象模型由提供程序、连接和命令对象构成,这使目前的 ADO 开发人员可轻松迁移到 ADO.NET。

从一个开发人员的角度看,ADO.NET 表现了 .NET Framework 内可用于数据访问的类的具体实现。这些类存在于 .NET Framework 的 System.Data 命名空间内。

System.Data.dll 中的 ADO.NET 类被集成在 System.Xml.dll 中的XML 类中。因此要编译使用 System.Data 命名空间的代码,您应该在您的 Visual Studio.NET 项目中添加对 System.Data.dllSystem.Xml.dll 的引用。

ADO.NET 引入了 DataSet 类提供的数据集的概念。您可以把数据集比喻成 JDBC 中的 ResultSet ,只不过数据集提供断开连接的数据视图。您可以使数据集脱机工作,修改它们,并且随后用已修改的数值更新数据库。

ADO.NET 也引入了类 SqlDataReaderOleDbDataReaderOracleDataReader 提供的数据读取器的概念。数据读取器对象从数据库中返回只读和只进的数据流。当在内存中一次只保留一行时,您可以使用此数据读取器对象改善应用程序性能和减少系统开销。

设计您的应用程序时要确定使用数据集还是数据读取器,请考虑您在应用程序中所需要的功能级别。

以下情况使用数据集:

  • 在结果的多个离散表之间进行导航。

  • 操作来自多个数据源(例如,来自多个数据库、一个 XML 文件和一个电子表格的混合数据)的数据。

  • 在各层之间交换数据或使用 XML Web 服务。与数据读取器不同,您可以将一个数据集传递到远程客户端。

  • 通过缓存重用同一个行集合,以得到性能上的改善(如当排序、搜索或者筛选数据时)。

  • 每行执行大量处理。对使用数据读取器返回的每行进行长期的处理将使用于数据读取器的连接不必要地长时间停顿,这将影响性能。

  • 使用 XML 操作对数据进行操作,例如可扩展样式表语言转换(XSLT 转换)或 XPath 查询。

下列理由成立时在您的应用程序中使用数据读取器:

  • 不需要缓存数据。

  • 要处理的结果集太大,内存中放不下。

  • 您只需要以只进和只读的方式快速和一次性访问数据。

ADO.NET 通过托管提供程序连接数据库。这些是数据库驱动程序,使用托管代码操作的类公开 API。您可以得到 SQL Server、Oracle 8i、MySQL 和 IBM 的 DB2 以及几个其他数据库的托管提供程序。

另外,托管提供程序可以访问基于 OLEDB 或者 ODBC 的驱动程序。OLEDB 和 ODBC 是两个较旧的独立于数据库的连接 API,您可以用它们连接任何兼容的数据存储区。如果您对这两个 API 使用 ADO.NET 托管提供程序,您可以用一套代码访问几乎任何数据库,然而,您增加了另一个 API 层的系统开销。

每个数据库的托管提供程序(如 SQL Server 7.0 或者 SQL Server 2000 的托管提供程序)在二进制层直接链接数据库,这提供了极大的性能优势。因为此原因,建议您使用正在连接的数据库的托管提供程序而不是更一般的基于 OLEDB 或者 ODBC 的驱动程序。

使用特定数据库的托管提供程序的确意味着随后您的应用程序和该数据库相绑定,切换到另一个数据库时需要重写数据库访问代码。然而,对一个组织来说改变它的数据库是很少见的,公司当然不会随便这样做。因此性能优势带给我们的好处足以抵消专用数据库访问代码所带来的小小不便。

本章中的技术涉及了如何使您的应用程序在无需大量代码重写的情况下使用不同的数据库。

使用 ADO.NET 连接 Microsoft SQL Server 2000

您可以通过 ADO.NET 的 SQL 托管提供程序从 .NET Framework 应用程序访问 SQL Server 2000。您可以在命名空间 System.Data.SqlClient 中找到您需要的访问 ADO.NET 的 SQL 托管提供程序的大多数 API。这是您在您的代码开始处引入的命名空间。

对象 ConnectionCommandDataReaderDataAdapter 提供 ADO.NET 数据提供程序模型的核心功能。每个托管提供程序对这些核心对象提供它自己的实现,并以各提供程序的名称作为前缀。例如,.NET Framework 的 SQL 托管提供程序包含如 SqlConnectionSqlCommand。以 Sql 为前缀的 ADO.NET 类处理 SQL Server 托管提供程序,它只处理 SQL Server。

使用这些 SQL Server 托管提供程序类和与其相对应的 OLE DB 提供程序相比,具有两个主要优点。第一,这些类使用本机表格式数据流接口 以发挥最高性能,而 OLE DB 类需要的额外的接口层不再存在,使数据库访问更快。第二,这些控件创建的 SQL 类具有额外的方法可利用特定于 SQL Server 的特性。这在用 SQL Server 设计和编程时为您提供了更大的灵活性。

在简单的连接场景中,您可以以下列方式使用对象。第一,您使用类 SqlConnection 定义一个数据库连接。此类建立一个包括计算机名称、数据库名和身份验证细节,如用户名和密码的连接字符串。然后您使用 Open 方法打开该数据库的连接。

为了从数据库得到数据,您构造一个包含相关的 select 语句的 SqlCommand 对象。对象 SqlCommand 上调用的 ExecuteReader 方法返回一个包含 select 语句的查询结果的 SqlDataReader 对象。最后,您从读取器中取出字段,用 GetValue 方法索引这些字段,并且在应用程序内任意使用它们。有关实现这些命令的更多信息,请参阅本章末尾的“参考”部分。

在 ADO.NET 和 JDBC 之间共享数据

您现在已经看到了 JDBC 和 ADO.NET 如何为 .NET Framework 和 J2EE 应用程序提供对若干数据库的数据库连接。现在您应该感谢两个环境可以指向单个数据源添加、读、更新和删除记录。现在是讨论实现数据库连接的一些最佳实践的时候了。

从您的应用程序的其余部分中抽象出数据库访问代码是 .NET Framework 和 J2EE 应用程序体系结构中的最佳实践。为了易于编码和实现一致性,您应该实现一个隔离层,该层从业务逻辑中抽象出数据库代码,如图 5.2 所示。

图 5.2:数据访问逻辑组件从业务层抽象数据库代码

此抽象模式根据平台有不同的名称。在 J2EE 中,这称为数据访问对象 (DAO) 模式。Application Architecture for .NET:Designing Applications and Services 指南将其称为数据访问逻辑组件或简称数据访问逻辑。接下来的一节讲述 .NET Framework 和 J2EE 应用程序中实现数据访问逻辑层的好处。

无论对 .NET 还是 Java 应用程序,本书将此抽象模式称为数据访问逻辑组件模式。

实现数据访问逻辑组件

不管您选择的是什么数据存储区,您的应用程序应该使用数据访问逻辑组件访问数据库。这些组件抽象了基础数据存储区和数据访问技术(如 ADO.NET 或者 JDBC)的语义并且为对存储的数据进行检索和执行操作提供了一个简单的可编程接口。

数据访问逻辑组件通常实现一个无状态的设计,将业务处理从数据访问逻辑中分离出来。每个数据访问逻辑组件通常提供对应用程序的某个特定的业务实体执行创建、读、更新和删除 (CRUD) 操作的方法。

例如,在一个电子商务应用程序中,您可以设计一个数据访问逻辑组件以处理和客户定单相关的数据的所有数据交互。此数据访问逻辑组件不必依靠数据库中的一个表,它可以访问与定单数据相关的任何表。通常,此数据访问逻辑组件返回复杂数据类型以表示一个业务实体,在这种情况下,就是一个 OrderData 对象。

有关实现数据访问逻辑的更多信息,请参阅本章末尾的“参考”部分。

进一步应用此概念,如果您有多个数据访问逻辑组件,实现一个数据库帮助器 类以处理常见的任务,如数据库连接、执行命令和缓存参数等等是一个不错的主意。数据访问逻辑组件提供访问特定业务数据的逻辑,而数据库帮助器类则集中处理特定数据库的数据访问 API 代码。这有助于减少代码的重复。

您已经认识到,如果您使用托管的提供程序类和一个数据库通讯,您可能需要写特定于该数据库的代码。当您实现一个数据库帮助器类时,您可在该类内保留所有特定于数据库的代码。数据库帮助器类使您可以保持数据访问逻辑组件数据库的独立性。更改数据库类型意味着只是用一个可以和新数据库通讯的类替换您的数据库帮助器类。此外,为了从不同的数据库访问数据,拥有多个数据库类型的环境可以使用多个数据库帮助器类。

Microsoft 为 .NET Framework 提供了数据访问应用块 (DAAB),可以使用它作为用于访问 SQL Server 的数据库帮助器。有关 DAAB 的更多信息(包括下载信息),请参阅 MSDN 上的“Data Access Application Block Overview”。

实现数据访问逻辑组件的好处

实现数据访问逻辑组件有以下互用性方面的好处:

  • 创建从任一环境访问数据的通用方法,这允许开发人员不必考虑底层的平台用统一的方式编写业务逻辑代码。

  • 提供抽象访问不同底层数据库的能力。

  • 允许进一步集成访问数据库的逻辑和处理,如:

    • 提供缓存以改善性能。

    • 用于用户连接的身份验证和授权。

    • 事务支持和锁定。

    • 为大型结果集提供的数据分页。

通用方法的优势是可进一步拓展互用性的使用方案,使一个平台上的业务层可调用另一个平台上的数据访问逻辑层。这发展了 .NET Framework 和 Java 应用程序间共享数据库的概念,不仅允许您共享数据库,还使您可共享与该数据库通讯的数据访问逻辑。本指南包含的 XBikes 示例应用程序通过它的一个配置选项提供实现此方案的能力。

5.3:在 .NET Framework 和 Java 应用程序间共享数据访问逻辑组件

实现异步互用性

迄今为止,您已经了解了在 .NET Framework 和 Java 应用程序间使用 .NET 远程处理和 Web 服务的同步调用。同步调用需要将结果返回给使用者的提供程序组件的响应,并且请求方要一直等到收到响应。对于高速、永久链接的 WAN 链路,这是首选的方法。甚至在滞后时间更长的 Internet 环境中,同步调用也绝对可以胜任。

然而,如果无法保证存在可用的提供者应用程序您怎么办呢?如果链接到的组件是非永久链接,或者其他因素(如加载级别和队列)阻止同步操作,该怎么办呢?在这种情况,您可以实现异步通讯。

使用异步通讯,提供者应用程序是否可用没有保证。因此,使用者应用程序将它的请求添加到消息队列,并且随后它等待提供者可以处理它时的响应。另一种情况可能是提供者在产生一个结果时需要耗费大量的处理资源,比如在能构成一个响应前可能要联系其他的提供者以获得信息。

在许多情况下使用异步处理十分理想,尤其在 Web 上,一个用户的请求将花费许多时间处理,但是您要立刻给用户提供一个响应。通过异步处理用户的请求,您的系统可以进行响应,而不管执行该请求可能实际上花了多少时间。

属于这种范畴的操作包括用信用卡在在线商店订货或者向清算中心发送一个请求。该应用程序使用户知道定单已经被成功地下好了,而不是当信用卡公司批准付款或者清算中心结算定单时,使用户一直等待。稍后的电子邮件通知可以确认款项已经到位或者定单应经被汇总了。

异步操作主要有两种类型:

  • 非阻塞式操作 这是客户端处理异步调用的位置。调用本身是同步的,但客户端将调用切换到另一个进程或者线程,并且允许其他的操作不受中断地继续进行直到该响应返回为止。

  • 单向操作 这是一个真正的异步操作,原因在于客户端的请求被一个单独的服务器组件处理。客户端随后可以在收到该事务结果之前通过查询状态信息审核请求的进展。

下一节讲述使用 Web 服务在 .NET Framework 和 Java 应用程序间使用非阻塞式异步调用。本章的剩余部分随后继续讲述在消息队列产品中可用的真正的单向异步操作支持。

使用异步调用连接 Web 服务

虽然 Web 服务本质上是同步的,但是您可以使用它们实现非阻塞异步连接。非阻塞式异步调用不是真正的异步,但它们允许客户端应用程序通过产生一个处理异步操作的单独的进程以继续运行。这一节讲述实现与 Web 服务的非阻塞式异步连接的技术。

从区分下列两种场景开始十分重要:

  • 实现到 Web 服务的异步调用。

  • 实现一个本身就是异步的 Web 服务。

在第一个场景中,客户端应用程序异步调用一个“slow”Web 服务以允许应用程序当“slow”Web 服务的调用在处理中时可以继续运行。第二个场景是 Web 服务在 Web 服务器上异步操作,以改善它的性能。然而,此第二种选择仍导致一个接受同步连接的 Web 服务。本指南只讨论第一种场景。

当您从 .NET Framework 客户端应用程序调用 Web 服务时,您既可以异步调用也可以同步调用该方法。在第 4 章, “互用性技术:点对点”,您看到了 Web 服务客户端如何使用自动产生的代理类中的方法调用 Web 服务。当您将一个 Web 引用添加到您的客户端项目时,您就为您的客户端创建了此代理类,或者当您使用 Web 服务 描述语言工具 (Wsdl.exe) 时,就自动创建了同步或异步调用 Web 服务方法的方法。即使只有 XML Web 服务方法的同步实现也是正确的。

例如,如果 Web 服务公开 GetProductsByCategory 方法,代理文件将包含三个名为 GetProductsByCategoryBeginGetProductsByCategoryEndGetProductsByCategory 的方法。第一个方法像往常一样同步调用 Web 服务。接下来俩个处理异步调用。方法 Begin 启动对 Web 服务的调用,而方法 End 返回结果。调用来自客户端的代理类的方法 Begin 启动一个第二级处理以同步调用 Web 服务,允许客户端在 Web 服务调用执行时继续运行。

显而易见的问题是客户端如何知道何时调用 End 方法?这里有四个主要的解决方法:

  • 传递一个回调函数到方法 Begin。当消息已经完成处理时,第二级处理随后调用该回调函数。因为当等待响应时该回调函数不阻塞线程,所以这是首选的方法。

  • 使用对象 IAsyncResult.AsyncWaitHandle 中的一种 WaitHandle 方法。当使用类 WaitHandle 中的方法时,客户端还可指定一个超时,超时后客户端将放弃等待该结果。

  • 轮询 IAsyncResult.IsCompleted 的值。当此属性返回 true 时,XML Web 服务响应可用。

  • 直接调用方法 End。此方法不返回直到异步操作完成,因为它使用 IAsyncResult.AsyncWaitHandle

使用异步通讯提高系统使用率并且避免出现这种情况,当 Web 服务提交操作结果时,客户端必须等待。您同步或者异步调用一个 Web 服务方法的决定应该根据性能要求而定。然而,来自客户端应用程序的通讯还是单向的,因此这不是真正的异步实现。

有关异步调用 Web 服务的更多信息,请参阅本章后面的“参考”部分。

在客户端应用程序中使用回调

在 .NET Framework 中的 Web 服务客户端应用程序中此“伪异步”操作是易于实现的。取决于您的 Java Web 服务工具包提供的功能,在 Java Web 服务的客户端也可实现此操作风格。

然而,使用此异步技术对 Web 服务的调用在客户端脱机并在一周后重新上线的情况下将失败。如果事务花费好几分钟(或者甚至几秒),用户是不可能保持连接的。因此只有下列因素满足的时候才能实现非阻塞异步操作。

  • 客户端和 Web 服务有持久的连接。

  • 对 Web 服务的调用不会花费太长时间完成。

  • 当 Web 服务调用时,客户端可以继续干其他的任务。

如果这些因素中的任意因素不满足,您应该考虑将使用 Web 服务的非阻塞式实现改进为使用消息或者队列基础结构的真正的异步操作。

使用消息队列实现异步互用性

您现在已经清楚了您如何才能调用 Web 服务仿真非阻塞异步调用。现在您将看到如何使用消息队列以完成真正的异步通讯及如何连接 .NET Framework 和 Java 应用程序。

消息队列是一种进程或者程序实例通过系统托管的消息队列的接口交换或者传递数据的技术。消息可以有不同的长度、类型和使用方法。您可以使进程创建多个进程可以通过读写消息进行交互的消息队列。例如,客户端进程可以写一个消息到消息队列而服务器进程稍后可以对该消息队列进行读或者写,反之亦然。

采用在队列中放置一个表示任务(例如,一个清算定单)的消息而不是同步处理该任务,那么应用程序只是必须传递该消息到队列。任意数量的不同应用程序(可能在不同的平台上)可以发送消息到消息队列,并且任意数量的应用程序可以被用来返回和处理那些同样的消息,为您的应用程序提供可伸缩性。

图 5.4 显示了一个消息队列如何在两个应用程序间工作的概述。使用一个消息 API,应用程序创建带有数据有效负载的消息。消息队列系统通过队列管理器负责用合适的格式封送数据并把消息放进队列中。队列管理器也负责定位目标队列(可能不止一个),无论它们在本地计算机或者在网络上的一台远程计算机上。

在图 5.4 上,发送和接收应用程序可能在不同的平台上。

图 5.4:一个消息队列应用程序的示例

这里有几个供应商生产的消息队列产品,包括:

  • Microsoft 消息队列(也称为 MSMQ)

  • IBM WebSphere MQ(正式名称是 MQSeries)

  • Sun ONE Message Queue

  • BEA Message Q

这些消息队列产品通常负责管理某个系统上的消息队列。应用程序通常用一个 API 从一个队列发送和接收消息。

因为讨论的是在 .NET Framework 和 Java 应用程序间的互用性,此指南着重讲述 Microsoft 消息队列和 IBM 的 WebSphere MQ 上。讨论 IBM 的 WebSphere MQ 是因为在企业平台中它很受欢迎,尤其是那些使用 Java 的平台。接下来的几节讲述使用 Microsoft 消息队列和 WebSphere MQ 这两个产品在 .NET Framework 和 Java 应用程序之间实现互用性。

使用 Microsoft 消息队列

Microsoft 消息队列 (MSMQ) 是 Windows 操作系统的一个功能。MSMQ 提供一个应用程序之间消息传递的基础结构,实现在断开连接的应用程序间发送消息的功能。这是在应用程序中使用业务层组件的至关重要的要求。

MSMQ 已经有几个版本。MSMQ 1.0 是作为 Windows NT 4.0 Options Pack 的一部分被引入的,并且也可以在 Windows 95 和 Windows 98 中使用。MSMQ 2.0 是 Windows 2000 的一部分。最新的版本,MSMQ 3.0 现在已经和 Windows XP Professional 和 Windows Server 2003 一起发行,也有一个 Windows CE 的 MSMQ 版本。

在 Windows NT 4.0 Workstation、Windows 2000 Professional 和 Windows XP Professional 中的 MSMQ 只能访问本地私有队列。

因为和 Windows 的高度集成,MSMQ 提供几个好处:如使用 COM+ 事务的能力、和 Windows 安全模型结合和群集。MSMQ 3.0 提供了一些额外的功能如使用 HTTP 传送能力、SOAP 可靠消息处理协议 (SRMP) 支持、多路广播选项、触发器和许多管理和部署升级。

MSMQ 满足了许多应用程序的要求:

  • 消息传递 MSMQ 打包消息并且跨越网络传递它到接收应用程序。它使用它本身的基于 IP 的协议和 HTTP 传输(仅 3.0 版本),以及当正文包含对象时使用用于对象序列化的 COM/DCOM。

  • 可还原队列 MSMQ 队列是在内存中或者永久存储区中等待发送的消息。应用程序可以从队列中不移除、筛选、和返回它们就能在队列中查看消息。

  • 容许断开连接 除非您另外指定,否则消息将呆在队列中等待直到一个应用程序来查询它。这意味着 MSMQ 支持断开连接的应用程序,计算机没有连接到同一物理网络。在计算机重新连接之后,它可以接收任何等待的消息。

  • 事务性消息 MSMQ 的可选事务功能保证消息只到达一次,多个消息以特定顺序出现,如果有任何地方出错了,整个消息集合将回滚到它的初始状态。MSMQ 是一个标准资源管理器,因此它可以协调和其他资源管理器的活动,如Microsoft SQL Server,所以允许在同一事务中读和写消息和数据。

  • 错误处理和审查 许多地方可能因为各种断开连接应用程序而出错,而 MSMQ 必须为错误和审核情况提供可靠性支持,如无法投递的消息或者消息审核和日志。

有关 MSMQ 的功能的更多信息,请参阅 Microsoft Message Queuing (MSMQ) Center Web site

MSMQ 不是 Windows Server 2003 默认安装的一部分。为了安装 MSMQ,使用控制面板中的 Add or Remove Programs 下的 Add/Remove Windows Components 添加它。到 Application Server 一节并且选择 Message Queuing 复选框。

有关如何安装 MSMQ 的详细指导,请参阅第 9 章,“实现异步互用性。”有关更多的一般信息,请参阅 Windows 帮助的“Installation Overview for Message Queuing”。

管理 MSMQ

您可以通过计算机管理控制台管理 MSMQ。您可以用此工具创建、查看和管理队列。在此工具中,您在“消息队列”对象下找到 MSMQ 项。此处有四个容器:

  • 待发队列 保存待发消息,通常用于传送。

  • 私有队列 使您创建一个您可以发送消息的私有队列。

  • 公共队列 支持您创建一个供 Active Directory 发布的队列。

  • 系统队列 包含系统级别的队列,如“死信”队列存储 MSMQ 无法发送的消息。

有关管理和配置 MSMQ 的更多信息,请参阅 Windows 帮助。

在私有和公共队列间选择

MSMQ 提供创建公共或者私有队列的选择。公共队列和私有队列的主要区别在下面列出:

  • 公共队列出现在 Active Directory 而私有队列不出现在那里,因此您只能通过知道队列地址访问私有队列。

  • 私有队列不会引起 Active Directory 的任何系统开销。

  • 公共队列仅适用于域环境。在工作组环境,您只能使用私有队列。

  • 当 Active Directory 目录服务不可用时,私有队列仍可以操作。

除非您的设计被紧紧绑定于 Active Directory 身份验证,否则可以使用私有队列。

现在您理解了 MSMQ 的基本原理,下一节将向您展示如何使用它在 .NET Framework 和 Java 应用程序间实现异步互用性。在第 3 章,“互用性基础原理”中,描述了如何使 .NET Framework 和 Java 应用程序在交换数据的公共格式上取得一致。假设您已经创建了一个公共数据格式,理论上只要您能使用 .NET Framework 及 Java 应用程序发送和接收来自 MSMQ 的消息,MSMQ 就可以作为两个平台间的异步连接,如图 5.5 显示的那样。

图 5.5:消息队列允许 .NET Framework 和 Java 应用程序间的异步互用性

.NET Framework 应用程序连接到 MSMQ

从 .NET Framework 应用程序编程访问 MSMQ 现在是相对容易的过程,虽然不总是这样。虽然 MSMQ 的概念非常简单,但是原始的 Win32 API 涉及了大量的底层编程。第一个改善之处是 COM 接口的开发。然而,在 .NET Framework 中,Microsoft 提供了一个命名空间和一套类支持 MSMQ。命名空间 System.Messaging 使 MSMQ 编程和编写 .NET Framework 兼容。

System.Messaging 包含包装底层 MSMQ 基础结构的类集合。在这些类中,您发现当设计 MSMQ 时您有三个最常使用的类:

  • MessageQueue

  • Message

  • MessageEnumerator

下面各节描述每个类。

MessageQueue

MessageQueue 是一个和本地或远程计算机上的消息队列交互的主要的类。您可以用它执行如枚举特定计算机上的队列,从队列中返回消息,发送消息到一个队列和创建和删除队列的任务。您用 MSMQ 在 .NET Framework 中做的几乎每件事都由 MessageQueue 类的一个实例开始。

Message

Message 让您访问和操作队列中的各个消息,及格式化和微调您加到队列中的消息。大多数情况下,当轮询一个消息集合时,您用 Message 对象接收一个特定消息的引用。

对象 Message 中的属性 Body 存储消息数据。用您指定的 Formatter 属性,发送序列化 Body 属性内容的消息。这类似于在第 3 章,“互用性基础原理”中讨论的序列化技术。MSMQ 提供二进制和 XML 格式程序两种方式。您可以在属性 BodyStream 中找到序列化后的内容。您也可以直接设置属性 BodyStream,以执行如将文件作为消息的数据内容发送这样的任务。您可以在发送该消息前的任一时刻改变属性 Body 或者 Formatter,当您调用对象 MessageQueue 的方法 Send 时,它将适当地序列化数据。

MessageEnumerator

MessageEnumerator 是无与伦比的,由于它可提供将队列中消息作为消息的动态集合,非常灵活地访问类。它是处理多个消息的最好方法,因为它使您可根据需要灵活地查看或者接收消息。对象 MessageEnumerator 是一个根据消息出现在队列中的顺序和消息优先级排列的引用消息的游标。您可以使用 MessageEnumerator 逐步通过队列并且检验或者按它们在队列中出现的顺序访问消息。然而,因为类 MessageEnumerator 提供一个只进的游标,所以您无法用 MessageEnumerator 逐步反向通过队列。

当枚举器查询该队列时,它不从队列中移除消息。它返回目前游标位置的消息的信息,但它把消息保留在队列中。

有关命名空间 System.Messaging 中的 MSMQ 相关的类和如何针对 MSMQ 编程的更多信息,请参阅 MSDN 上的“.NET Framework Class Library”。

使 MSMQ 队列

在您使用它之前您必须能指定一个消息队列。为了指定消息队列,您需要一个方法在您的应用程序中唯一不变地描述一个队列。 .NET 提供三个不同的访问特定队列的方法:

  • 通过它的路径指定一个队列 一个队列的路径看起来如 \private$\, netserver\private$\Orders,它指定了计算机名(或“.”是本地服务器)和队列的完整路径。

  • 通过格式名指定一个队列 此选项使用 FormatName,它是一个通过某些连接细节和队列路径描述队列的字符串, 例如,DIRECT=OS:netserver\private$\Orders 或者使用一个特殊的 GUID 唯一标识此消息队列。

  • 通过标签指定一个队列 此方法使用队列的标签(“My Orders”),一个您可以通过代码或者消息队列管理接口分配的值。

无论使用标签还是路径的方法都增加了系统开销,因为 MSMQ 必须将那些内部使用以描述各个队列的描述解析为 Format Name

直接使用 Format Name 可避免名称解析,这使其成为更有效的方法,当一个队列不在线时如果您希望您的客户端应用程序能工作,这是唯一可以引用队列的办法。然而,当创建一个新的队列的时候通过路径指定一个队列是唯一的选择,因为其他两个引用选择依赖的队列的属性只能在队列存在后设置。

发送队列消息

发送消息到 MSMQ 队列是一个相对简单的转发过程

发送一个消息到 MSMQ 队列

  • 通过创建一个 MessageQueue 对象实例以打开您要发送消息的队列并且作为构造函数的一个参数指定队列名。

  • 设置对象 MessageQueue 的属性 Formatter 以使用您要用作序列化队列上消息内容的格式化程序(二进制或者 XML)类型。如果您不指定属性 Formatter,将使用 XML 格式化程序。

  • 创建一个新的对象 Message 并且设置该对象的属性 Body 的值为您要发送到消息队列的对象。例如,一个对象 OrderData 包含一个定单的详细信息。

  • 通过调用对象 MessageQueue 的方法 Send 并且使用对象 Message 作为一个参数来发送消息到消息队列。

有关从 .NET Framework 客户端发送一个消息到 MSMQ 队列的详细示例,请参阅第 9 章,“实现异步互用性”。

返回队列消息

MessageQueue支持 MSMQ 查看或者接收消息。查看意味着您检查特定队列的第一个消息而不需要把它从消息队列中移除掉。这是一种查看消息队列和为以不同于消息出现在队列中的顺序处理消息而实现逻辑的便捷方法。然而,Peek 让您只看到该队列中的第一个消息。因为 peeking 不从队列中移除此消息,您无法查看到随后的消息。

如果您要看所有队列中的消息而不从队列中移除它们,您可以使用方法 GetAllMessages 或者方法 GetMessageEnumerator

在应用程序查看了队列中的一个消息之后,它可以选择接收该信息或者它可以直接接收消息而不查看。接收一个消息意味着该消息离开了队列,并且应用程序可以对此消息做可以进行的任何操作。当应用程序接收到一个消息,那条消息永久地离开了队列,除非某些进程返回它到该队列。

从MSMQ 队列找到一个消息也是一个简单的过程。

MSMQ 队列找到一个消息

  • 通过创建一个 MessageQueue 对象的实例并且指定该队列名称作为构造函数的一个参数以打开您要从那里接收消息的队列。

  • 用属性 MessageQueue.Formatter 或者 Message.Formatter 设置正确的格式化程序。发送方的格式必须和接收方相匹配。

  • 调用对象 MessageQueue 的方法 Receive 返回一个对象 Message

  • 强制转换对象 Message 的属性 Body 的值为您希望接收的对象类型。

应用程序可以异步或者同步查看或者接收消息。类MessageQueue 提供事件 PeekCompletedReceiveCompleted 让您可以用来异步接收事件。通常应用程序使用这些事件以指定一个超时时间以限制应用程序等待消息的持续时间。

有关在 .NET Framework 应用程序中从 MSMQ 队列中返回消息的详细示例,请参阅第 9 章,“实现异步互用性”。

J2EE 连接到 MSMQ

迄今为止,此指南已经描述了一个 .NET Framework 应用程序如何通过从 MSMQ 发送和接收消息实现异步连接。但 MSMQ 能为 J2EE 服务和 Java 客户端做什么呢?

通常,让 Java 应用程序实现和 MSMQ 的互用性不是容易做的事情。Microsoft 目前没有提供用于 Java 的 MSMQ 客户端。为了从 Java 应用程序访问 MSMQ,您需要实现其他的步骤。

目前,有三个方法可以做这件事:

  • 使用一个 Java 到 COM 的桥。

  • 使用一个 MSMQ 的 JMS 提供程序。

  • 创建一个 Web 服务接口。

以下部分描述这些技术。

使用一个 Java COM 的桥

虽然本机 Java 客户端无法直接和 MSMQ 对话,但是现有的 COM 客户端可以使用 COM API 直接和 MSMQ 对话。COM 客户端包含基于 Win32 平台的 Microsoft Visual Basic 和C/C++ 应用程序。第三方供应商提供产品让您从一个 Java 客户端调用 COM API,实际上通过 COM 连接 Java 客户端到 MSMQ,如图 5.6 所示。

图 5.6:通过 Java 到 COM 桥访问消息队列

此方法的好处是 MSMQ COM 库非常详尽并且为 MSMQ 提供一个丰富的接口而不需要您创建任何额外的包装或者接口。然而,此方法的一个不好之处在于 Java 客户端必须是基于 Windows 使用 Java 到 COM 桥,并且您必须为 MSMQ 安装 COM 库。这个要求拒绝考虑使用在不同于 Windows 的其他操作系统上运行的 Java 客户端。

第二个问题是网络连接必须使用一个自定义的 TCP 套接字 DCOM。DCOM 在基于 Internet 的分布式环境中不能工作得很好。.

Intrinsyc 提供一个叫做 J-Integra 的 Java 到 COM 桥您可以不必使用基于 Windows 的 Java 客户端或者为 MSMQ 安装 COM 库。有关详细信息,请参阅本文结尾处的“参考”部分。

使用用于 MSMQ JMS 提供程序

JMS 是 Java 消息服务 API 并且是 J2EE 规范的一部分。它为几个消息队列产品提供一个抽象层并且所有的 J2EE 供应商实现 JMS 的支持。为了使用 JMS 访问一个队列,您需要队列的该类型的 JMS 提供程序。虽然这是一个从 Java 访问 MSMQ 的好的解决方案,但是目前还没有 MSMQ 的 JMS 提供程序。

创建一个 Web 服务接口

一个更接近的连接 Java 到 MSMQ 的方法是使用 Web 服务接口。在该方法中,您创建了一个 .NET Framework Web 服务以公开 MSMQ 的功能。Java 客户端随后通过调用 Web 服务访问 MSMQ。图 5.7 显示了此方法。

图 5.7:使用一个 Web 服务接口访问MSMQ。

想要公开 MSMQ 到 Java 客户端的 Web 服务接口的示例,请参阅 Simon Guest 的书 Microsoft .NET and J2EE Interoperability Toolkit 的名为“Creating a Web Service Interface for MSMQ”的章节。

Web 服务接口提供一个连接 J2EE 到 MSMQ 的有趣方法。此外,由于业界对 Web 服务的兴趣日增,为各种组件开发 Web 服务接口有很大的动力。

然而,实现用于 MSMQ 的 Web 服务接口并不能解决所有的问题并且在某些方面可以看作是一种倒退。特别是某些 MSMQ 提供的功能将不使用该方法。

  • 可靠的消息处理。

  • 事务性支持。

  • 真正回调。

新的 Web 服务规范已对最先两个情况提供解决方案,如下一节所述。

可靠的消息处理

可靠消息处理和 Web 服务面临的问题是 Web 服务使用 HTTP 作为底层的传输协议。虽然 HTTP 包含允许重试连接的功能,但是您不能认为它是一个可靠的协议。例如,HTTP 不给 IIS 返回成功或者不成功的消息传输的报告。因此如果您使用 Web 服务连接到 MSMQ,您就丧失了 MSMQ 提供的传递保证。

Web 服务可靠消息处理协议 (WS-ReliableMessaging) 是一个在 Web 服务上提供可靠消息处理的新的规范。WS-ReliableMessaging 由一个可以标识、跟踪并且在两台机器间管理传送的协议构成。协议本身使用 SOAP 头和绑定以提供可靠性。有关 WS-Reliable 消息处理的更多信息,请参阅 MSDN 上的“Web Services Reliable Messaging Protocol (WS-ReliableMessaging)”。

事务性支持

Web services Basic Profile 1.0 规范不实现对事务的支持。事务支持包括的保证是:一套操作或者事务不是成功完成就是回滚到操作开始之前的状态。

标准示例是把钱从一个银行帐户转到另一个银行帐户中去。此过程包括从一个帐户减少余额并且向另一个帐户增加余额。如果一个操作完成而第二个操作没有完成,结果将会导致一个帐户的钱消失而另一个帐户的钱并没有增加。把这两个操作合成一个事务,您可以确保两个操作都完成或者回滚到开始位置,因而不做任何改动。

在一个 Web 服务内实现事务支持是困难的,但不是不可能。先前的示例中的事务处理需要一些步骤:

  1. 创建事务。

  2. 发送向帐户 1 要钱的消息

  3. 发送添加钱到帐户 2 的消息。

  4. 提交或者取消此事务。

一个 Web 服务一次只能处理一个动作。而且, Web 服务调用是无状态的,因此在客户端和服务间没有关系。例如,Web 服务可发送一个消息到队列以便向第一个帐户要钱,但完成此任务之后,它就关闭了。如果客户端再次调用,服务器没有内在的方法知道这是同一个客户端。

在 Web 服务上实现事务性支持的一个方法是在 Web 应用程序中存储会话状态信息。在先前的示例中,Web 服务可以为会话状态中的四个任务中的每一个保持客户端请求,并且仅在接收到提交的请求后处理它们。图 5.8 显示了此场景的一个示例。

图 5.8:使用 Web 服务处理事务

在 Web 服务 中实现会话状态不是没有损失的。存储会话状态使用许多内存资源。此资源使用率可能引发可伸缩性的限制。这还可能让您容易拒绝服务攻击或者当 Web 服务器由于创建多个状态对象而耗尽内存时拒绝无足轻重的负载。

Web 服务事务 (WS-Transaction) 是一个新的将事务性支持应用于 Web 服务的事务规范。它涵盖了原子事务和业务行为。原子事务是不连续的、独立的、生命周期很短的事务,而业务行为涵盖花费大量时间执行的事务,并且您无法简单地回滚到前一个状态。有关 WS-Transaction 的更多信息,请参阅 MSDN 上的“Web Services Transaction (WS-Transaction)”。

真正回调

MSMQ 的真正回调支持让消息服务器可以通知客户端队列或其他事件的消息的到达。为了这样做,当连接到队列或者发送一个消息时,您向队列提供一个回调位置。此队列记录回调位置并且根据所选择的条件发送通知。其他方法是使用 UDP 多路广播立刻通知多个客户端。MSMQ 版本 3.0 实现了实用通用多路广播 (PGM),一个可靠的多路广播协议。

这不同于伪回调支持,客户端必须轮询队列看里面究竟是什么。AsyncCallBack 是此伪回调函数的示例。命名空间 System.Messaging 通过类 MessageQueue 内的方法 BeginReceiveEndReceive 支持 AsyncCallBack

AsyncCa llBack 不是一个真正回调函数,因为虽然该操作产生一个辅助的非阻塞线程,此机制还是具有请求响应的性质。

目前的 Web 服务只能提供一个伪回调支持,因为目前的实现方案依靠 HTTP 作为传输协议。HTTP 只支持请求响应类型交互,这让通知非常困难。如果 Web 服务真正的独立于协议(像在 Web 服务中定义的),它可能使用 Web 服务实现真正的回调函数。

使用 IBM WebSphere MQ

WebSphere MQ(从前的 MQ 系列)是 IBM 的和 MSMQ 等价的产品,它是从 IBM 的大型机时代发展来的。WebSphere MQ 提供确定的、只一次的消息传递。如果接收的应用程序或者接收应用程序的通讯通道不可用,WebSphere MQ 自动存储此消息并且在稍后转发它。您也可以配置 WebSphere MQ 提供确认消息。

在 MSMQ 和 WebSphere MQ 之间的主要区别是 WebSphere MQ 可运行在多个操作系统上,包括 Linux、UNIX、AIX、HP-UX、Sun Solaris 和 Windows。它也支持超过 35 个不同平台的消息处理。您通过使用一个叫做 MQI(消息队列接口)的编程接口以允许应用程序使用消息队列。这是一个跨平台的 API,因此一个平台上的应用程序调用容易移植到另一个平台。WebSphere MQ 提供 MQI 功能的 Java 和 .NET Framework 实现,外加 J2EE JMS 支持。

在 WebSphere MQ中,队列管理器管理队列。队列管理器向应用程序提供消息处理服务并处理来自应用程序的消息队列接口 (MQI) 调用。队列管理器负责在队列中放置消息或者传送一个消息到另一个队列管理器。

在您可以用 WebSphere MQ 做事之前,队列管理器和队列都必须已经创建,并且能让运行应用程序的计算机访问。

应用程序要发送或者接收一个消息,它必须首先连接到队列管理器。队列管理器提供一个连接句柄,应用程序在会话期间为 MQI 调用使用此连接句柄。

在队列管理器创建了此连接句柄之后,下一个任务是打开队列。您可以打开队列以得到(读)或者放置(写)一个消息。此队列管理器负责打开一个队列并且如果成功的话返回一个对象句柄。无论何时在队列中得到或者放置消息,您的应用程序都要使用此对象句柄和连接句柄。

当发送一个消息时,您必须打开队列准备放置消息。发送消息包括打包您要发送给数据缓冲区的数据,并且提供其他的信息,如目标和消息类型。为了接收一个消息,此队列必须为得到数据而打开。

WebSphere MQ 支持的最大消息大小是 4 MB,但是不是所有的操作系统都支持此范围。例如,Windows 和 Dos 应用程序的消息大小是32 K。

管理 WebSphere MQ

WebSphere MQ 的 Windows 版提供一个 Microsoft 管理控制台 (MMC) 管理单元以管理队列管理器和队列定义。当您安装 WebSphere MQ 时,它创建默认队列管理器,随后您可以配置它。您可以添加不同的队列管理器,甚至用 MMC 工具改变默认设置。

队列管理器的部分功能是提供对队列的访问。您可以使用 MMC 管理单元创建四种队列:

  • 本地队列 一个属于本地队列管理器的队列。

  • 别名队列 一个队列定义用其他队列实现,让客户端连接别名但传递队列请求到另一个本地队列。

  • 模型队列 允许您定义一个模型或者模板,应用程序可以用来动态创建队列。

  • 远程队列定义 使您可提供到不同机器上配置的队列中的挂钩。

您只可以发送消息到远程队列,不能接收它们。

有关管理 WebSphere MQ 的更多信息,请参阅 IBM WebSphere MQ Web page

从远程计算机上访问 WebSphere MQ

WebSphere MQ 有一个客户端组件您可以安装在一台独立的计算机上。客户端允许应用程序和驻留在不同计算机上的队列管理器通讯,这甚至能运行在一个不同的平台上。

理解 JMS 的角色

在第 2 章,“理解企业平台”中,您看到 Java 消息服务 (JMS) 是一个 API,当访问消息队列时,它提供应用程序抽象。您也看到 JMS 不是一个产品而是一个服务定义。JMS 规范和 API 是 J2EE 的一部分,但它是让第三方供应商实现此标准。有关 JMS 标准的更多信息,请参阅 Java Web 站点上的“Java Message Service API”。

几个有 Java 背景的消息队列供应商已经为他们的产品实现了 JMS 提供程序。此提供程序用作在消息产品和 JMS API 间的一个联编程序。理想的情况,它让您在不影响 JMS 组件操作的情况下切换操作系统供应商,这支持移植。

用 JMS,您可以实现两种消息支持或消息域:

  • 基于队列或者点对点。

  • 发布/订阅。

基于队列的消息处理和 MSMQ 中的那个相似。发送者和接收者在一个预定义的队列上达成一致,使用 JMS 类型 javax.jms.Queue 处理异步消息。一个客户端可以发送一个消息到 MyPrivateQueue,并且接收者从同一队列接收消息。随后接收者确认成功处理了该信息。

用点对点消息处理,每个消息只有一个使用者。

JMS 通过使用类 javax.jms.Topic 按主题对队列分类也支持发布/订阅模型。发布应用程序发布新的消息到主题(或者队列),而任何订户随后可以接收到发布的消息。您可以在订户和主题间创建一对多、多对一和多对多的关系。

JMS 规范让您控制主题消息存活多长时间和在发布后它们在主题队列中保存多久。图 5.9 显示了一个发布/订阅模型的示例。输入提供一个持续的信息流,队列管理器把它们推给订户。应用程序,比如一个股票交易程序可以使用此消息,交易者随后用它作为一个依据买卖股票。

图 5.9:JMS 规范中的发布/订阅域

 

在点对点和发布/订阅之间的主要区别是定时。即使客户端脱机工作,点对点消息处理仍可以工作。而发布/订阅,客户端需要主动使用消息。持久订阅 提供一个替代方案,当订户脱机工作时接收消息。

主题管理可能是一个有趣的挑战因为客户端可以动态创建和修改主题,这意味着修复的队列无法被担保。然而,消息供应商通常为主题管理实现机制。例如,用于 WebSphere 的 SupportPac MA0C 使用预定义的系统队列和通道。

JMS 支持五种消息类型:

  • javax.jms.TextMessage 用于简单字符串消息。

  • javax.jms.BytesMessage 用于将原始字节作为消息发送。

  • javax.jms.ObjectMessage 作为消息发送一个可序列化的 Java 对象。

  • javax.jms.MapMessage 发送一个支持名称/值对的消息,就如哈希表。

  • javax.jms.StreamMessage 支持 MapMessage 的类型,但是消息的内容必须按顺序排列。

这些消息类型都实现接口 javax.jms.Message

J2EE 应用程序连接到 WebSphere MQ

有三个从 J2EE 应用程序连接到 WebSphere MQ 的方法:

  • 使用用于 Java 的 WebSphere。

  • 使用用于 JMS 的 WebSphere MQ 类以实现点对点消息处理。

  • 使用用于 JMS 的 WebSphere MQ 类实现发布/订阅的消息处理。

以下部分讨论每种技术。

使用用于 Java WebSph ere MQ 类。

用于 Java 的专用 WebSphere MQ 类允许您连接 WebSphere MQ 服务器,或者直接或者通过 WebSphere MQ 客户端。这些类允许 Java 应用程序、applet、和 servlet 与 WebSphere MQ 通讯。用于 Java 的 WebSphere MQ 类是名为 com.ibm.mq 的软件包的一部分。您必须导入此软件包以在您的 Java 代码中使用这些类。

用用于 Java 的 WebSphere MQ 类发送和接收消息是一个小任务。您创建一个到队列管理器的连接、打开队列、创建一个消息并且把它放进队列中。以下代码用一个简单的 “Hello World”消息证明了这一点。

// Create a connection to the QueueManager
MQQueueManager queueManager = new MQQueueManager("QM_MYQM");
// Open the desired queue
MQQueue queue = queueManager.accessQueue("myQ", MQC.MQOO_OUTPUT,
"QM_MYQM", "myQ", "");
// Create a new message
MQMessage myMessage = new MQMessage();
// Specify the message format
myMessage.format = MQC.MQFMT_STRING;
// Populate the message data buffer with the "Hello World" string
myMessage.writeString("Hello World");
// Create the default message options
MQPutMessageOptions pmo = new MQPutMessageOptions();
// Put the message into the queue
queue.put(myMessage,pmo);

除了放置原始数据类型或者字符串,您也可以写 Java 对象到队列中。这使用标准 Java 序列化机制写您对象的内容到消息缓冲区中。

虽然对 Java 到 Java 应用程序来说这很棒,但是其他的平台,包括 .NET Framework,不理解序列化消息的格式。

如果您要使用用于 Java 的 WebSphere MQ 类来实现互用性,您要面对几个挑战。第一,您必须了解用于 Java 的 MQ 类不是 J2EE 规范的一部分,因此只有 WebSphere MQ 实现了这些类。如果您使用一种不同的消息队列产品,您无法使用软件包 com.ibm.mq

如果您很乐意使用 WebSphere MQ,您的下一个问题是如何处理复杂数据。.NET Framework 和 Java 的序列化程序的不同之处意味着您无法把来自一个平台的对象放到一个队列中然后从另一个平台中拿走对象。因此在对象级别的互用性不可能实现。

然而,您可以把您的数据序列化成一个 XML 字符串,像第 4 章的关于 Web 服务的部分中讨论的那样,“互用性技术:点对点”。Java、.NET Framework 和 WebSphere MQ 都可以处理字符串,因此您可以打包一个客户端对象作为一个 XML 格式字符串并且然后把它放在队列中。

为点对点消息处理使用 JMS WebSphere MQ

JMS 的类 WebSphere MQ 实现 Sun 的 Java 消息服务 (JMS) 接口,允许 Java 程序访问 WebSphere MQ。JMS 的 WebSphere MQ 类支持点对点和 JMS 的发布/订阅模型。

这部分描述点对点的 JMS 消息处理模型。接下来的部分描述发布/订阅 JMS 消息处理模型。

如果您使用 JMS 类实现 WebSphere MQ,这儿有几个主要的不同之处。最重要的是您无法直接创建一个连接,而是创建一个连接工厂。这些厂对象存在于 JNDI 命名空间,允许应用程序不必考虑供应商的特殊细节。为了得到连接工厂,您需要从 JNDI 命名空间中返回对象。

如果您没有一个 JNDI 命名空间可用,在运行时创建此厂是可以的。

在您拥有连接工厂之后,使用该厂创建一个随后可以启动的连接。下列代码显示了如何得到连接工厂和创建连接。

InitialContext ic = new InitialContext();
QueueConnectionFactory factory =
(QueueConnectionFactory) ic.lookup(connectionName);
QueueConnection connection = factory.createQueueConnection();
connection.start();

在您创建连接之后,接下来的任务是创建一个会话。此会话为创建和使用消息提供上下文,并提供方法以创建对象 MessageProducer(用于发送消息)和对象 MessageConsumer(用于接收消息)。使用下面的代码可以创建一个简单的、非事务性的、自动确认的会话。

QueueSession session =
connection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);

在应用程序得到一个会话之后,它可以用一个 MessageProducer 创建一个队列并且发送一条消息。队列的定义可以被存储在一个 JNDI 命名空间或者在运行时创建。用 JNDI 定义此队列是最佳实践。使用下面的代码应用程序可以得到一个队列。

Queue queue = (Queue) ic.lookup(queueName);

使用此队列作为一个参数,您可以使用 QueueSession 创建一个 MessageProducer。在点对点消息处理模型中,如下列代码显示的那样 MessageProducer 将是一个 QueueSender

QueueSender sender = session.createSender(queue);

最后,您需要创建一个正确类型的消息。对象 QueueSession 上的方法允许您创建五种 JMS 消息中的任何一种。然后您可以像下列代码显示的那样用您要发送的数据填充此消息。

ObjectMessage message = session.createObjectMessage(myObject);
sender.send(message);

您可以使用 QueueReceiver 接收一个使用 MessageConsumer 的消息。您可以从此会话中以和 QueueSender 同样的方式创建它。然后您可以用阻塞或者非阻塞的调用从此队列接收消息。下列代码显示了如何从此队列接收消息。此代码一直阻塞直到一个消息到达或者超时。

QueueReceiver receiver = session.createReceiver(queue);
Message message = receiver.receive(1000);

接收消息的类型是五种支持的 JMS 消息中的一种。为了提取正确的消息有效负载,您必须强制转换返回的消息为正确的消息类型。

它也可能异步接收消息。

WebSphere MQ 上的 JMS 消息有一种不同于标准的 WebSphere MQ 消息的结构,并且 JMS 消息需要映射为 WebSphere MQ 格式。然而,如果您通过 JMS 发送一个消息并且接收的应用程序是非 JMS 的,此映射不重要,因为您随后可以配置此队列的目标客户端为 MQ。

使用用于 JMS WebSphere MQ 类以进行发布 / 订阅消息处理

前面的部分描述了如何使用用于 JMS 的WebSphere MQ 类完成发布/订阅消息处理。这一部分描述如何完成发布/订阅消息处理。

当您使用发布/订阅消息处理时,您需要先决定您要使用哪个中间装置,并且配置它为运行用于 JMS 的 WebSphere MQ 类。此中间装置有一个所有注册一个主题的订户的记录。当一个应用程序发布一个消息到一个主题,此中间装置把该消息转发给订户。

您通过一个 SupportPac 添加了到 WebSphere MQ 的发布/订阅支持。有关如何做这些任务的详细信息,请参阅这章后面的“参考”部分。

WebSphere MQ 提供三类中间装置:

  • MQSeries 发布/订阅

  • WebSphere MQ 综合中间装置

  • WebSphere MQ 事件中间装置

中间装置的安装不仅依赖您选择哪个中间装置而且依赖您要如何使用它。每个中间装置有它自己的配置和安装文档。

在选出中间装置之后,您必须创建类似那些在点对点消息处理中使用的那些对象的 JMS 对象。具体来说,您必须得到或者创建下面的对象:

  • TopicConnectionFactory

  • TopicConnection

  • TopicSession

  • Topic

  • TopicPublisherTopicSubscriber

步骤和点对点技术的步骤相似,就如下面代码示例显示的那样。

// Create a connection
InitialContext context = new InitialContext();
TopicConnectionFactory factory = (TopicConnectionFactory)
context.lookup(tcfName);
TopicConnection connection = factory.createTopicConnection();
connection.start();
// Create a session
TopicSession session =
connection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
// Create a topic
Topic topic = (Topic) context.lookup(topicName);
// Create a publisher...
TopicPublisher publisher = session.createPublisher(topic);
// ...or create a subscriber
TopicSubscriber subscriber = session.createSubscriber(topic);

最后,您用早先章节中的点对点消息处理同样的方法发布消息或者接收消息。

.NET Framework 应用程序中连接到 WebSphere MQ

有两个方法从 .NET Framework 应用程序连接到 WebSphere MQ:

  • 使用用于 Microsoft .NET 的 WebSphere MQ 类

  • 使用 JMS 和第三方桥接产品

下面的部分讨论每种技术并且描述了每种技术的优点和缺点。

使用用于 Microsoft .NET WebSphere MQ

用于 Microsoft .NET 的类 WebSphere MQ 提供对 WebSphere MQ 的访问,这和用于 Java 的 WebSphere MQ 是一样的方法。然而,虽然它们使用同样的对象模型,.NET Framework 版本不支持连接池或者发送消息到多个队列或者主题。图 5.10 显示了一个 .NET Framework 客户端如何才能使用用于 .NET 的 WebSphere MQ 类连接 WebSphere MQ。

图 5.10:一个 .NET Framework 客户端使用用于 .NET 的 WebSphere MQ 类连接 WebSphere MQ

作为 MQ v5.3 CSD05 的一部分您可以从 IBM 得到 .NET Framework 类,这代表纠正服务发行版 #5(等同于一个服务包)此补丁包安装库 Amqmdnet.dllWebSphere/bin 目录。此 DLL 提供一套您可以用在任何 .NET Framework 应用程序中的类。

CSD05 受 IBM 支持。您可以从 IBM 站点得到 CSD05

虽然 Amqmdnet.dll 公开托管类,您应该清楚这些类对其他 MQ 客户端库调用 PInvoke。因此如果您的应用程序调用了 Amqmdnet.dll 中的类,如果运行应用程序的计算机还没有安装 WebSphere MQ 客户端,您需要安装它。

PInvoke 允许托管代码调用 Win32 DLL 文件上的方法和函数。这避免了为了互用性使用 COM,但是 .NET Framework 不对这些调用提供托管代码功能,如垃圾回收。

Amqmdnet.dll 公开的类和 Java 环境中的那些类非常相似,这帮助开发人员在两个系统间移植代码。Java 和 .NET Framework 客户端的数据传输使用原始格式,而不用任何打包或者序列化。

您可以使用像 Java 类一样的对象和方法调用从队列中发送和接收消息,如下列代码示例所示。

// Create a connection to the QueueManger
MQQueueManager queueManager = new MQQueueManager("QM_pagdal");
// Open the desired queue
MQQueue queue = queueManager.AccessQueue("XBikesQ",MQC.MQOO_OUTPUT,
"QM_pagdal", "XBikesQ", "");
// Create a new message
MQMessage myMessage = new MQMessage();
// Specify the message format
myMessage.Format = MQC.MQFMT_STRING;
// Populate the message data buffer with the "Hello World" string
myMessage.WriteString("Hello World");
// Create the default message options
MQPutMessageOptions pmo = new MQPutMessageOptions();
// Put the message into the queue
queue.Put(myMessage,pmo);

除了方法的大写问题(Java 中小写,.NET 中大写)以外,这些代码示例和 Java 版本一样。这是 MQI API 的一个设计目标。

使用JMS和第三方桥接产品

您可以使用第三方桥接产品如 Ja.NET 或者 JNBridgePro 从 .NET Framework 应用程序中访问 WebSphere MQ JMS 功能。您可以就像从一个 Java 客户端访问 JMS 功能一样,用您的 .NET 客户端直接调用 JMS API。要这样做,创建您需要的所有 Java 类的 .NET 代理,以使用 JMS 发送消息并且从 .NET 调用这些代理。代理管理在 .NET 客户端和 WebSphere MQ 间的通讯。通过桥接访问 JMS 功能的好处是:您可以用类似的 JMS API 实现来自 .NET 的消息处理。同时,它使 JMS API 看上去像一个常规的 .NET Framework API。

图 5.11 显示一个运行时桥如何允许 .NET Framework 客户端使用 JMS 连接到 WebSphere MQ。

图 5.11:使用一个运行时桥从 .NET Framework 客户端访问WebSphereMQJMS的功能

第 9 章,“实现异步互用性”,显示了如何从一个 .NET 客户端使用 JNBridge 和 JaNET 访问 WebSphere MQ 的 JMS 功能的详细示例。

从.NET Framework 客户端访问JMS消息

您已经看到 .NET Framework 客户端如何用用于 Microsoft .NET 的 WebSphere MQ 的类或者通过第三方桥产品使用 JMS,以使用来自 WebSphere MQ 的消息。然而,当在 .NET Framework 客户端使用用 JMS 放置在 WebSphere MQ 队列中的消息时有几个您需要明白的问题。

从 WebSphere MQ 访问 JMS 消息的主要问题是 JMS 消息有非 JMS 应用程序不能理解的额外的消息头。例如,用于 .NET 的 WebSphere MQ 类无法解开一个 JMS 格式的消息。然而,如果您使用一个第三方桥接产品通过 JMS 连接 WebSphere MQ,桥接产品处理和转换 JMS 消息头就没有问题。

为了允许一个 .NET Framework 客户端使用用于 .NET 的 WebSphere MQ 的类使用来自 WebSphere MQ JMS 消息,要确保发送消息的 Java 应用程序设置 JMS 中的目标客户端为 MQ。这允许 Java 应用程序发送 JMS 消息而省略麻烦的消息头。虽然用于 .NET 的 WebSphere MQ 类无法解开一个 JMS 格式的消息,但是它们解开一个 MQ 消息是没问题的。

.NET Framework 客户端无法重构从 Java 序列化的对象因此任何消息必须被作为基本数据类型发送。

JMS 发布/订阅模型的一个主要的互用性问题是将此模型与使用用于 .NET 的 WebSphere MQ 的类的 .NET Framework 客户端连接是不可能的。从 .NET 访问发布/订阅模型的唯一方法是用一个包装 JMS 调用的桥接产品。这是因为客户端用动态的方式创建主题。

WebSphere MQ 并不在队列和主题之间实现一对一的关系,因为这限制所允许的主题的数量。用于 .NET 的 WebSphere MQ 类不支持访问主题。而且,因为 WebSphere MQ 把主题队列当作系统对象处理,所以 .NET Framework 客户端无法访问此队列。即使类 MQQueueManager 也不支持您用一个主题联系一个队列。因此只有 JMS 客户端可访问 JMS 主题或者担当发布者或者订户。这使直接使用用于 .NET 的 WebSphere MQ 类的 .NET Framework 客户端通讯的互用性很难完成。

您可以使用一个桥接产品,如 JNBridgePro 或者 Ja.NET 完成此互用性。

下一部分中,您继续了解您如何在 Host Integration Server 上使用桥接功能连接 .NET 和 Java 应用程序。

使用 Host Integration Server 2000

这一章已经描述了 MSMQ 和 IBM WebSphere MQ 如何在 .NET Framework 和 Java 客户端间实现异步互用性和如何连接 Java 客户端到 MSMQ 或者 .NET Framework 客户端到 WebSphere MQ。然而,每种技术都有一些缺点,如可靠操作的降低或者事务性支持的减少。

一个在 .NET Framework 和 Java 应用程序间实现异步连接的可选方法是通过桥的使用连接 MSMQ 和 WebSphere MQ。在此方法中,.NET Framework 应用程序连接到 MSMQ 而 Java 应用程序连接到 WebSphere MQ。然后,您使用一个桥连接两个队列。图 5.12 显示了使用 MSMQ-MQSerise Bridge(Microsoft Host Integration Server (HIS) 的一部分)的此方法的一个高层视图。

图 5.12:在 HIS 2000 中使用 MSMQ-MQSeries Bridge 支持异步互用性

 

HIS 是从 Microsoft SNA Server 发展而来的,它支持各个组织将 Windows 和基于局域网的网络连接到基于主机的大型机设备。从互用性的观点看最重要的是,HIS 提供了一个 MSMQ-MQSeries Bridge。通过使用本机消息队列实现,此桥保证了可靠性和事务性消息队列的质量。

有关 HIS 的更多信息,请参阅 Host Information Server Web site

用 HIS 2000 桥接 MSMQ 和 WebSphere MQ

MSMQ-MQSeries Bridge 给 HIS 在 MSMQ 和 WebSphere MQ 组件之间双向交换消息的能力。HIS 可以从 MSMQ 队列接收消息并且发送它们到 WebSphere 队列和再发送回来。

MSMQ-MQSeries Bridge 使用的是 IBM WebSphere MQ,即使桥产品的名称是 MQSeries。

MSMQ-MQSeries Bridge 系统包含两个主要的组件:

  • MSMQ-MQSeries Bridge 在 MSMQ 和 MQSeries 环境间转换和传递消息。

  • MSMQ-MQSeries Bridge Manager 使您可通过 MSMQ-MQSeries Bridge 配置、监视和控制消息流量。

MSMQ-MQSeries Bridge 映射一个消息的字段或属性为目标消息队列系统的对应字段或者属性。例如,如果您从 WebSphere MQ 发送一个消息到 MSMQ,MSMQ-MQSeries Bridge 分析 WebSphere MQ 消息的字段并且映射每个值到它的 MSMQ 对应字段。

在一个系统需要另一个系统中不存在的额外字段时,MSMQ-MQSeries Bridge 在转换过程中提供此字段。例如假设一个 MSMQ 消息包含一个具有特定数值的属性 PROPID_M_TIME_TO_BE_RECEIVED。MSMQ-MQSeries Bridge 映射此属性为 MQMD.Expiry WebSphere MQ 属性并且把此值乘以 10 以便把单位从数秒更改为数十秒。

MSMQ-MQSeries Bridge 不限制消息的内容。此消息的正文可以包含它自己的内部结构,只有发送和接收应用程序可以识别此消息结构。MSMQ-MQSeries Bridge 不用任何方法解释此结构。

有关 MSMQ-MQSeries Bridge 如何从消息队列映射和转换属性为 WebSphere MQ 及从 WebSphere MQ 映射和转换属性为消息队列的详细信息,请参阅 MSDN 上的“Microsoft Host Integration Server 2000 Developer's Guide”。

格式化消息

HIS 中的 MSMQ-MQSeries Bridge 支持您在 MSMQ 和 WebSphere MQ 间交换消息。然而,在第 3 章,“互用性基础原理”中深入论述了仅仅消息交换并不能保证互用性。

现在您知道 MSMQ-MQSeries Bridge 当在两个队列系统间传递消息时不操作消息的内容。因此它要由您确保此消息使用的是 .NET Framework 和 Java 应用程序都理解的公共格式。

为了确保通过 MSMQ-MQSeries Bridge 交换的消息使用的是公共格式,您需要理解 .NET Framework 和 Java 应用程序如何发送和接收消息到它们各自的队列,消息是从 .NET Framework 端发送的。

当一个 .NET Framework 客户端发送一个对象到 MSMQ 队列时,二进制或者 XML 格式化程序序列化此对象的内容。同样,当 .NET Framework 客户端接收一个消息时,它希望消息被序列化成二进制或者 XML 格式。

Java 处理从一个不同于 .NET Framework 的队列发送和接收消息。一个 Java 客户端可以使用本机 WebSphere MQ API 或者 JMS 发送消息到 WebSpere MQ 队列。如果客户端使用 WebSphere MQ API,此对象以一个简单字节流而不是序列化的格式传输。

JMS 也把对象作为字节流发送,但是包装有额外的 JMS 头信息。

.NET Framework 发送消息到 Java 应用程序

当发送消息到 MSMQ 时,您可以选择 .NET Framework 客户端使用二进制还是 XML 序列化程序。然而,在第 3 章,“互用性基础原理”中描述了在 .NET Framework 和 Java 中的二进制序列化程序如何不兼容。因此,当为传递到 WebSphere MQ 和 Java 客户端而发送一个复杂数据类型对象到 MSMQ 时,.NET Framework 客户端只应该使用 XML 格式化程序。

Java 客户端从 WebSphere MQ 接收到的消息由包含原始 .NET Framework 对象的序列化XML 表现形式的字符串对象构成。使用第 3 章,“互用性基础原理”描述的技术,Java 客户端必须随后把此字符串解释成 XML,并且将它反序列化成 Java 中相匹配的对象。此过程假设 .NET?Framework 客户端传递的数据类型对象派生自像 Java 中的同样的公共 XML 架构。它要由您在 Java 客户端中正确地反序列化接收对象,如第 3 章“互用性基础原理”所述。

Java 发送消息到 .NET Framework 应用程序

像早先讨论的那样,使用 JMS 发送到 WebSphere MQ 队列的消息包括额外的头信息。不幸的是,.NET Framework 不理解此信息。因此,如果您要发送消息到一个 .NET Framework 应用程序,您的 Java 客户端应该使用本机 WebSphere MQ API,或者如果使用 JMS,设置目标客户端为 MQ。

另外,因为 WebSphere API 不序列化 Java 客户端放到队列中的消息,因此在发送它之前,Java 客户端需要序列化此对象为 XML 格式。您可以使用第 3 章“互用性基础原理”中的技术完成它。这确保 .NET Framework 客户端可以将它收到的 XML 格式化消息反序列化为一个对象。

实现 MSMQ-MQSeries Bridge

这里有几个实现 MSMQ-MQSeries Bridge 的要求。这部分提供这些要求的一个概述,和安装此桥所需的体系结构。

有关安装和配置此桥的详细指导,请参考 HIS 2000 的产品文档。

MSMQ-MQSeries Bridge 要求一个适当的 Microsoft Active Directory 实例以正常使用。此依赖性源于 MSMQ-MQSeries Bridge 的工作方式。

从 MSMQ 到 WebSphere MQ,MSMQ-MQSeries Bridge 从 Active Directory 中发布的公共队列挑选消息。这些队列存在于一个已经定义的外部站点。此桥然后发送消息到一个 WebSphere MQ 上的命名队列。

反向路径包括从命名的 WebSphere MQ 队列中选择消息及把它们发送到公共的 MSMQ 队列的桥。因为在 Active Directory 中只能定义外部站点和公共队列,桥的操作要求您已经安装了Active Directory并且已经配置好了。

您在一台运行 Windows 2000 或者 Windows Server 2003 的计算机上安装 MSMQ-MQSeries Bridge,将此计算机在网络间作为一个连接点。您必须在 MSMQ-MQSeries Bridge 所在的同一计算机上安装 MSMQ 路由服务器,并且这台计算机必须能通过 TCP/IP 或者 LU 6.2 链路连接到一个 MQSeries 队列管理器。

您必须在 Windows Server 上安装 WebSphere MQ 以便使用桥连接到 MSMQ。如果您现有的 WebSphere MQ 实现是在其他操作系统上这会被看成一个复杂因素。此要求的一个理由是通过支持承载 WebSphere MQ 的计算机加入同一 Active Directory 森林来确保身份验证工作。然而,您可以通过提供一台运行 Windows 和 WebSphere MQ 并安装桥组件的计算机,并且配置该计算机以自动连接到您现有的非 Windows 环境的队列,从而解决此问题。

在一个测试环境中,您可在 WebSphere MQ 所在的同一台计算机上运行 MSMQ-MQSeries Bridge。然而,在产品中这不被推荐。运行桥的计算机必须是一个 Active Directory 域(产品环境)的成员服务器或者域控制器(仅测试环境)。

小结

这一章首先描述了如何通过在两个平台间共享数据库完成互用性。它涵盖了访问数据存储区(包括保护代码不被改变)的当前最佳实践。本章的第二部分讲述了基于消息的互用性机制,它为事务和长时间运行操作提供支持。它描述了如何用来自 Microsoft 或者 J2EE 供应商的消息队列产品连接到在 .NET Framework 或者在 J2EE 平台上承载的数据层组件。有了此认识,您现在可以查看 XBike Web 站点的应用程序体系结构并且了解开发人员如何应用第 4 和第 5 章的技术。

参考资料

有关结果集的更多信息,请参阅“JDBC Guide: Getting Started”

http://java./j2se/1.4.2/docs/guide/jdbc/getstart/resultset.html

有关使用 JDBC 的更多信息,请参阅“JDBC Data Access API”

http://java./products/jdbc/

有关 Microsoft SQL Server 2000 Driver for JDBC Service?Pack?1 的更多信息,包括下载信息,请参阅

http://www.microsoft.com/downloads/details.aspx?FamilyID=4f8f2f01-1ed7-4c4d-8f7b-3d47969e66ae&DisplayLang=en

有关用 Microsoft JDBC 驱动程序连接 SQL Server 2000 的更多信息,请参阅Microsoft 知识库文章 Q313100,“HOW TO:Get Started with Microsoft JDBC”

http://support.microsoft.com/default.aspx?scid=kb;en-us;313100

有关 MSMQ 功能的更多信息,请参阅

http://www.microsoft.com/windows2000/technologies/communications/msmq/default.asp

有关 System.Messaging 命名空间中 MSMQ 相关的类和如何编写 MSMQ 程序的更多信息,请参阅“.NET Framework Class Library”

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfSystemMessaging.asp?frame=true

有关公开 MSMQ 到 Java 客户端的 Web 服务接口的示例,请参阅 Microsoft .NET and J2EE Interoperability Toolkit作者 Simon Guest,Microsoft Press, ISBN 0-7356-1922-0©中的关于 Creating a Web Service Interface for MSMQ 的部分。

有关 J-Integra 的更多信息,请参阅

http://j-integra./

有关实现 J-Integra 的详细信息,请参阅“Introducing J-Integra 1.5.5”

http://www./support/j-integra/doc/

- 和-

“Java Servlet to MSMQ Example”

http://www./support/j-integra/doc/servlet_com/ServletToMsmqExample.html

有关 WS-Reliable 消息处理的更多信息,请参阅“Web Services Reliable Messaging Protocol (WS-ReliableMessaging)”

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnglobspec/html/ws-reliablemessaging.asp

有关 WS-Transaction 的更多信息,请参阅“Web Services Transaction (WS-Transaction)”

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnglobspec/html/ws-transaction.asp

有关管理 WebSphere MQ 的更多信息,请参阅

http://www-3.ibm.com/software/ts/mqseries/messaging

有关 JMS 标准的更多信息,请参阅“Java Message Service API”

http://java./products/jms/index.html

您可以从

http://www-3.ibm.com/software/integration/mqfamily/support/summary/wnt.html 获得 CSD05

有关 HIS 的更多信息,请参阅

http://www.microsoft.com/hiserver/

有关 MSMQ-MQSeries Bridge 如何从消息队列映射和转换属性到 WebSphere MQ,以及如何从 WebSphere MQ 到消息队列映射和转换属性的详细信息,请参阅“Microsoft Host Integration Server 2000 Developer's Guide”

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/his/htm/his_dg_devguide_intro_libd.asp

有关如何使用 SQL Server 的托管提供程序连接到一个 SQL Server 数据库的示例,请参阅“Connecting to SQL Server Using ADO.NET”

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconconnectingtosqlserverusingadonet.asp

有关如何使用一个数据读取器对象从一个数据库检索数据的示例,请参阅“Retrieving Data Using the DataReader”

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpcontheadonetdatareader.asp?frame=true

有关在 .NET Framework 中设计数据访问逻辑组件的更多信息,请参阅 Application Architecture for .NET: 的第 2 章,“Designing the Components of an Application or Service”

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnbda/html/distapp.asp

有关在 .NET Framework 中实现数据访问逻辑组件的更多信息,请参阅 .NET Data Access Architecture Guide

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnbda/html/daag.asp

有关在 J2EE 中实现 DAO 模式的详细信息,请参阅 Core J2EE Patterns Best Practices and Design Strategies,作者 Deepak Alur、Dan Malks 和 John Crupi (ISBN 0-13-064884-1)。

有关异步调用 .NET Framework 中的一个 Web 服务的示例,请参阅“Communicating with XML Web Services Asynchronously”

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconinvokingwebservicesasynchronously.asp

要安装 MQSeries 发布/订阅支持,从 IBM Web 站点上的 Business Integration Web 页面下载 SupportPac MA0C。

http://www.ibm.com/software/ts/mqseries/txppacs

转到原英文页面

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多