至此,已经介绍了面向消息的中间件的元素和使用 JMS 作为增加 MOM 应用程序可移植性的方法。接下来介绍 Message Queue 如何实现 JMS 规范,并介绍它用来提供可靠、安全且可伸缩的消息传送服务的功能和工具。
首先,与很多 JMS 提供者类似,Message Queue 可以用作独立产品或用作启用技术嵌入到 J2EE 应用服务器中提供异步消息传送。第 5 章,Message Queue 和 J2EE将更详细地介绍 Message Queue 在 J2EE 中所起的作用。与其他 JMS 提供者不同的是,Message Queue 已被指定为 JMS 引用实现。这一指定证明了这样一个事实:Message Queue 是正确而又完整的 JMS 实现。它还保证了 Message Queue 产品将与以后推出的任何 JMS 修订和扩展保持同步。
作为一个 JMS 提供者, Message Queue 提供一个实现 JMS 接口并提供管理服务和控制的消息传送服务。至此,我们已在说明 JMS 提供者时重点介绍了代理在消息转发过程中扮演的角色。但实际上,除了代理外,JMS 提供者中还必须包括许多元素才能提供可靠、安全且可伸缩的消息传送。图 1–6 展示了构成 Message Queue 消息服务的元素。这些元素包括各种连接服务(支持不同的协议)、管理工具以及数据存储库,它们用于执行消息传送、监视以及用户信息存储。Message Queue 服务本身包含图中标记为灰色的所有元素。
如图所示,功能完善的 JMS 提供者比基本 JMS 模型复杂令人感到很疑惑。以下各节将介绍上面显示的 Message Queue 服务元素。这些元素可以分成三类:代理、客户端运行时环境支持和管理。
如图 1–6 所示,应用程序客户端和管理客户端都可以连接到代理。JMS 规范未规定提供者实现任何特定的线路协议。应用程序客户端和管理客户端用于连接到代理的 Message Queue 服务,这些服务当前位于 TCP、TLS、HTTP 或 HTTPS 协议的顶层。(位于 HTTP 顶层的服务使消息可以穿过防火墙。)
提供 JMS 支持并允许客户端连接到代理的服务(jms、ssljms、http 或 https)的服务类型是 NORMAL,这些服务位于 TCP、TLS、HTTP 或 HTTPS 协议的顶层。
使管理员可以连接到代理的服务(admin 和 ssladmin)的服务类型为 ADMIN,这些服务位于 TCP 或 TLS 协议的顶层。
默认情况下,当启动代理时,会启动并运行 jms 和 admin 服务。此外,还可以将代理配置为运行上述任一或全部连接服务。每个服务都支持特定的验证和授权(访问控制)功能,每个服务都是多线程的并且支持多个连接。
当连接失败时, Message Queue 服务能够自动重新尝试将客户端连接到同一代理或另一代理(如果启用了此功能)。有关详细信息,请参见附录 B,Message Queue 功能 中自动重新连接功能的介绍。
创建从中获得其连接的连接工厂时,客户端可以配置连接运行时环境支持。可以通过选项来指定要连接到的代理、重新连接的处理方式、消息流控制等。有关如何配置连接的其他信息,请参见连接工厂和连接。
代理是消息服务的核心,它以可靠的方式路由和传送消息,对用户进行验证并收集用来监视性能的数据。
要路由和传送消息,代理需将传入消息置于各自的目的地并管理消息流在这些目的地中的进出。
要提供可靠的传送,代理需使用持久性存储库保存状态信息和持久性消息,直到使用方收到消息。如果代理发生故障或连接失败,所保存的信息使代理可以恢复代理的状态并重试操作。
要为所交换的数据提供安全性,代理需要使用经过验证的连接。可以通过运行安全协议(如 SSL)对数据进行加密(可选)。代理还使用并管理一个系统信息库,该系统信息库保存有关用户以及他们可以访问的数据或操作的信息。代理对请求服务的用户进行验证,并通过在该系统信息库中查找信息来授予他们执行相应操作的权限。
要监视系统,代理需要生成度量和诊断信息,以便管理员可以通过访问这些信息来度量性能并调整代理。度量信息还可以通过编程方式来使用,这使应用程序可以调整消息流和模式,从而提高性能。
Message Queue 服务提供各种管理工具,管理员可以使用这些工具来配置代理支持。有关详细信息,请参见管理。
客户端运行时环境支持在构建 Message Queue 客户端时所链接到的库中提供。可以将客户端运行时环境视为已成为客户端一部分的 Message Queue 服务的代码。例如,当客户端代码进行 API 调用以发送消息时,将调用这些库中的代码,以便根据用来将消息转发到代理上的物理目的地的协议来相应地包装消息位。
只有当需要支持 Java 客户端时,才需要 JMS 提供者。但是,如图 1–6 所示,Message Queue 客户端可以使用 Java 或特定于提供者的 C API 来发送或接收消息。这些接口是在 Java 或 C 运行时环境库中实现的,这些库的实际作用是建立与代理的连接并根据所请求的连接服务来相应地包装位。
Java 客户端运行时环境为 Java 客户端提供与代理交互所需的对象。这些对象包括连接、会话、消息、消息生成方和消息使用方。
C 客户端运行时环境为 C 客户端提供与代理交互所需的功能和结构。它支持 JMS 编程模型的程序化版本。C 客户端不能使用 JNDI 来访问受管理对象,但是可以通过编程方式来创建连接工厂和目的地。
Message Queue 服务提供一个 C API,使传统 C 和 C++ 应用程序能够参与基于 JMS 的消息传送。这两个 API 所提供的功能有许多不同,Java 客户端与 C 客户端对此进行了说明。
一定要记住 JMS 规范是只适用于 Java 客户端的标准。而 C 支持则是特定于 Message Queue 提供者,因此在计划移植到其他提供者的客户端应用程序中不应该使用该支持。
Message Queue Java 客户端还能够发送和接收包装为 JMS 消息的 SOAP 消息。使用 SOAP(Simple Object Access Protocol,简单对象访问协议)可以实现在分布式环境中的两个对等方之间交换结构化数据。所交换的数据由 XML 方案指定。
Sun SOAP 处理当前仅限于使用点对点模型,并且不保证可靠性。通过将 SOAP 消息包装到 JMS 消息中,并使用代理来传送该消息,从而可以使用功能完善的 Message Queue 消息传送,这样会保证传送的可靠性且可以使用主题和点对点域。Message Queue 提供实用程序例程,使用这些例程,消息生成方可以将 SOAP 消息包装到 JMS 消息中,消息使用方可以从 JMS 消息中提取 SOAP 消息。
通过使用 SOAP 消息,可以更详细地了解 SOAP 消息处理。
Message Queue 服务提供可用来执行以下操作的命令行工具:
启动和配置代理。
创建和管理目的地、管理代理连接以及管理代理资源。
添加、列出、更新和删除 JNDI 对象存储库中的受管理对象。
填充和管理基于文件的用户系统信息库。
为持久性存储库创建和管理符合 JDBC 的数据库。
还可以使用基于 GUI 的管理控制台执行以下命令行功能:
连接到代理并对它进行管理。
创建和管理物理目的地。
连接到对象存储库、向存储库添加对象并管理这些对象。
由于客户端数量和连接数量的增长,可能会需要扩展消息服务来消除瓶颈或增强性能。Message Queue 消息服务根据您的需要提供许多扩展选项。可以很容易地将这些选项归为以下几类:
垂直扩展是通过添加处理能力和扩展可用资源来实现的。这可以通过添加更多处理器或内存,切换到共享线程模型或者在 64 位模式下运行 Java VM 来完成。
如果使用的是点对点域,则可以通过允许多个使用方访问队列来扩展使用方一端。使用此方法,可以指定活动使用方和备份使用方的最大数量。负载平衡机制还将使用方的当前容量和消息处理速率考虑在内。这是 Message Queue 功能。(如果只有一个使用方访问队列,则 JMS 规范定义消息传送行为;允许多个使用方的队列行为是特定于提供者的。Message Queue 开发者指南提供了有关此扩展选项的详细信息。)
无状态水平扩展是通过使用其他代理并将现有的客户端重新分配给这些代理来实现的。此方法易于实现,但是只有当消息传送操作可以分成多个独立的工作组时,此方法才适用。
有状态水平扩展是通过将代理连接成群集来实现的。在代理群集中,每个代理不仅连接到群集内的其他每个代理,而且还连接到本地应用程序客户端。这些代理可以位于同一个主机上,也可以分布在网络中。有关目的地和使用方的信息会在群集内的所有代理中复制。目的地和订户的更新也会进行传播。因此,每个代理都可以将消息从与它直接相连的生成方路由到与群集内的其他代理连接的使用方。当使用备份使用方时,如果某个代理发生故障或连接失败,则发送到不可访问的使用方的消息可以转发到另一个代理上的备份使用方。
如果代理发生故障或连接失败,则有关持久性实体(目的地和长期订阅)的状态信息可能会失去同步。例如,如果当某个群集代理停机时,在群集内的另一个代理上创建了一个目的地,则当前者重新启动时,将不会知道有这个新目的地。要防止出现此问题,可以将群集内的某个代理指定为主代理。此代理负责跟踪主配置文件中目的地和长期订阅的所有更改,还负责更新群集内临时脱机的代理。有关其他信息,请参见第 4 章,代理群集。
即使在使用主代理时,当代理发生故障或连接失败时,Message Queue 也只是提供服务可用性,而不提供数据可用性。例如,如果群集代理变得不可用,则在该代理恢复之前,由该代理保存的任何持久性消息都将不可用。目前,只能通过使用 SunCluster Message Queue 代理来确保数据可用性。在这种情况下,持久性存储库保留在共享文件系统上。如果某个代理发生故障,则第二个节点上的 Message Queue 代理会启动一个接管共享存储库的代理。客户端会重新连接到该代理,从而既可以获得不间断的服务,又可以访问持久性数据。