下载第 20章 ASP和消息队列服务器上一章讨论了如何使用 C O M +添加应用程序和组件的事务处理能力。本章研究另一种增加应用程序可扩展性的方法。
迄今为止,我们假设一个服务器是一个始终有效的完美世界,但是如果没有这个前提,
整个的系统会崩溃吗?显然不会。不过有必要采用一个异步通信系统,通常称为消息或者消息队列。
在消息方案中,应用程序不再是执行一般的方法调用和等待一个响应,取而代之的是,
调用者简单地发一个“消息”给服务器,然后按正常程序进行处理,因此消息不仅允许客户处理其他工作,而且由于利用了 Microsorft 消息队列 ( M S M Q ),服务器甚至可以是不可用的,
因为消息可以被排队并在以后处理。
本章将讨论消息排队的以下几个方面内容:
消息排队的定义。
MSMQ及其结构。
MSMQ的管理。
如何使用 C O M对象与 M S M Q交互。
在 A S P应用程序中 M S M Q组件的使用。
MSMQ消息的异步响应。
如何将 M S M Q合并到事务中。
首先,介绍消息排队的背景知识。
20.1 消息排队的定义消息排队是允许不同的应用程序使用“存储和传送”过程进行彼此交流的系统。
这些应用程序可以在相同或不同的硬件平台上。这些平台可以位于同一场所、同一 L A N
或者是由电子装置相连的任何地方,这种连接甚至不需要是永久的或可靠的,除此之外,这些平台甚至可在不同的操作系统中运行。
这听起来好像是一个非常复杂的系统。当今 I n t e r n e t世界的特点是各种各样的应用程序、
各种不同的地理位置、各种各样的连接类型和操作系统同时存在。能在这些系统之间传送数据已经成为主张互连的人们的共同目的。
在复杂的系统环境中,S Q L,O D B C,F T P和 H T T P等技术都为数据在系统之间传送提供了不同的机制,这些技术的主要缺点是面向特定的应用程序类型。当数据需要在复杂的平台间有效转换时,非常需要一种中间的应用程序。交换数据的格式和平台到平台的交互规则应当留给特定的应用程序去完成。这种技术只是一个通信信道。利用这些系统已经创建出大量系统的事实,并不意味着不存在更为有效的通信方法。
消息中间件系统在大型计算机领域中是众所周知的,多年来已经成为大容量的事务处理应用程序的模式。在个人计算机中也有许多消息技术,但我们主要考虑 M S M Q,因为 M S M Q
与 A S P和其他微软开发工具紧密相关。
20.1.1 MSMQ的定义
M S M Q的基本概念非常简单,就是应用程序的电子邮件。
与电子邮件一样,M S M Q消息也有发送者和接收者。然而接收者有些不同,M S M Q中消息接收者定义为访问队列者 (这是由 Wi n d o w s域安全性设置的 )。这样在单一的队列中多个接收者能够响应单一的消息。在大多数使用 M S M Q的网络应用程序中,消息的发送者是 We b服务器 ( I I S ),消息的接收者是自定义的应用程序。
当 M S M Q消息形成后,即被打包到一个“容器”中,并发送到一个队列中,等待接收者读取。这些队列不管网络连接的状态和可靠性如何,都能够保证消息传送 (存储和传送 )。
自定义应用程序不一定在不同的机器上,但是放在另一台机器上可提供更好的可扩展性。
在大多数使用 M S M Q的 A S P应用程序中,消息从 A S P脚本或从 C O M组件中传送到同一个服务器或另外一个机器中的队列中。一旦消息发送,A S P可以继续进行处理。在后台,另一个自定义服务器端应用程序 (通常用 C O M相容的工具创建,如 Visual Basic或 Visual C++)响应消息并开始着手处理。另外的一个响应并处理 M S M Q消息的可能途径是建立一个使用
V B S c r i p t来打开队列的 S Q L 7,0服务器作业。
M S M Q也可以和其他的消息系统相互通信。 Level 8系统正在开发第三方解决方案用于与其他平台上的 M S M Q通信,例如 Sun Solaris,H P _ U N I X,O S / 2,V M S和
A S / 4 0 0平台等。
1,消息前面已经提到 M S M Q中的消息与电子邮件消息相类似,然而,它们不是发送给单个用户或一组用户,而是从一个应用程序发送到一个计算机的一个队列中。
M S M Q消息主要由三部分构成:
标签。
正文。
目标队列。
标签与电子邮件消息中的主题非常相似,大多数情况下标签用来把各种类型的消息分组,
使自定义的应用程序能够区分消息所包含的内容。
M S M Q消息的正文是各种各样的,能够保存从字符串、数组到 C O M对象的任何内容。消息排队系统本身不检查实际内容,并且消息内容的格式也没有明确的标准。这意味着内容格式由传递消息的两个应用程序自行决定。
例如,以创建一个 E x c e l应用程序对象为例,载入一个电子表格,并设置 M S M Q消息的正文为 E x c e l的实例。读取这条消息时,E x c e l对象的实例就会被取出来。唯一的需要是消息的发送者和接收者都必须将此组件注册到系统上。
消息也可包括实现专有的消息,例如谁是发送者和接收者、发送的时间标识、
甚至是截止日期,即如果超过这一时间不进行读取将删除消息。
588计计 ASP 3 高级编程 下载
M S M Q消息也包括决定消息读取顺序的优先级属性,它与电子邮件中的优先级非常类似。
消息中的优先级可以是 0 ~ 7的任何整数,决定消息存放到队列中的顺序。新添加的消息不一定就存放在队列的底部。例如一个优先级为 6的消息将放在优先级为 5的前面。数目越小,优先级越低。 M S M Q消息的缺省优先级为 3。但是发送到事务处理消息队列中的消息会将优先级自动设置为 0,这是因为事务忽略优先级。
2,队列消息队列是指消息被目标应用程序取走之前所存放的地方。与电子邮件比较,队列类似于收件信箱。消息在期满或被读取前存放在队列中 (除非清除队列 )。
系统中可以有多个队列,但 M S M Q支持大量连接的系统的分层结构。然而,在任何具体的机器中,队列管理器管理着本机的所有队列,通常包含在此机器上预定接收消息的所有队列,但也不总是这样。如果网络管理员对远程队列管理器进行适当的配置,大多数的消息产品允许直接确定远程机器中队列的位置。队列管理器决定这个消息的最终目标是否是本地。
如果是本地,就把消息放在目标队列中。如果不是本地,通过目录服务器找出目标队列所在的机器。一旦目标队列服务器收到消息,就将其存放在目标队列中。
每个队列属于单个服务器,但一个服务器可以有多个队列。
队列的主要属性有:
标签:通常用来定义队列的简单字符串。
ID:用来定义队列的唯一的 G U I D。
Ty p e I D:用来定义队列类型或组的唯一的 G U I D。
Ty p e I d很有可能在多个队列中是相同的,这些队列组合在一起执行共同的任务。
另外,在 MSMQ 2.0中有四种类型的队列:
输出队列 (outgoing queue):当远程 M S M Q服务器不起作用时保存消息。它们为 M S M Q
提供了操作灵活性,即使在另外一个服务器不工作时也一样不会丢失消息。不能通过应用程序使用输出队列,它只能由 M S M Q内部用于存储和传送消息。
系统队列 (system queue):也是由 M S M Q内部使用的,对自定义应用程序不起作用的。
这种队列的例子是无法投递的邮件的队列、报告队列和报纸队列。
公共队列 (public queue):它是 M S M Q中最常用的一种队列,自定义应用程序用这个队列完成业务需要。公共队列存储在 Active Directory服务中,因此,对于企业范围内的所有其他 M S M Q服务器都是可知的。
个人队列 (private queue):可在自定义应用程序中使用。然而在 Active Directory中没有个人队列。因而它们对本地计算机以外的应用程序来说是不可用的。
虽然消息队列可以通过编程建立,但是多数情况下,消息队列是通过 Computer Management
插件的 M S M Q部分建立的,管理 M S M Q的有关信息可参考下面的 2 0,3节“管理 M S M Q”的内容。
20.1.2 使用 M S M Q和 A S P的原因为什么使用 M S M Q?为什么不通过 D C O M开发使 A S P能获得所需功能的简单 C O M组件?
为了回答这个问题,我们提出以下几个问题:
如果正在运行 C O M对象的服务器不可用怎么办?
第 2 0章 A S P和消息队列服务器 计计 589下载
如果运行时间太长,A S P页超时而且用户放弃怎么办?
如果由于在正常时间内因为表格锁定或处理器紧张而不能进行处理怎么办?
这些问题是开发 M S M Q服务的原因。通过使用 M S M Q,这些问题可以通过相对比较简单的方法来解决。
( 1 )如果正在运行 C O M对象的服务器不可用该怎么办?
如果客户不是直接和 C O M对象对话而是发给 M S M Q一个消息,则在客户和服务 ( C O M )对象之间提供另一抽象层。这就是所谓的异步通信的松散连接。
当然,通常 C O M对象不能自己运行,但可以开发响应消息和调用 C O M对象功能的服务器端可执行程序。由于客户与后台分离,只要 We b服务器 ( I I S )安装了 M S M Q客户,客户可以仅仅发出消息并继续运行。
( 2 )如果运行时间太长怎么办?
这个问题的解决方法和上面的情况一样。通过把处理工作移到后台服务器上进行,客户就不必等到任务完成。
( 3 )如果由于在正常时间内不能进行处理该怎么办?
如果处理工作在正常的高峰时间内不能完成,这个任务可以存放在消息队列中直到预定的服务器端可执行程序准备处理此项任务 (队列中的消息 ),这允许任何数量的消息或任务同时存储或运行。
这就是所谓的批处理。
1,速度与可用性的比较通常消息中间件被认为是一种提高可用性和可扩展性的技术。这不应该与速度混淆。消息总是比低层的内部处理通信的方法要慢,如套接字 ( S o c k e t )或命名管道 (named pipe)。毕竟消息最终要利用这些方法来传递。中间件技术向通信协议基本性能增加了协商 ( n e g o t i a t i o n )和通告 ( n o t i f i c a t i o n )的开销。
消息中间件认为不论技术怎么快,都达不到足够快的速度。这不仅包括处理器也包括通信。除非机器能在零时间内无限装载,否则总有可能过载,这就是消息中间件的设计原因。
首先,通过将异步通信引入到处理中,在等待一个消息的响应时,客户可以去处理别的任务。因为队列管理器把输入的消息存放在一个缓冲区中,即队列中。接收服务器没有必要具有足以处理峰值通信量的速度,仅仅需要满足系统中通信量的平均值的处理需求。在峰值过程中,进入的额外消息将退到队列中去,当通信量减少时再发送,然后从队列中清除。在有额外消息退到队列中去时,对于必须同步处理消息的系统会失败,即可用性差。但是异步消息系统的服务仍然可用。
因而,消息是一个可扩展的解决方法,异步消息系统的优点在于可以成功地处理更多的通信量,而不在于处理速度。
这也说明了低层协议中增加的附加特性的作用。消息中间件对企业级系统提供一系列重要的特性以降低额外开销:
它改善了可用性。
它考虑了偶然断开计算机连接这种可能出现的情况,这在基本协议中是不允许的。
它允许传送者和接收者知道发出的消息已收到,并且一旦收到就能知道。
590计计 ASP 3 高级编程 下载当我们继续学习本章内容时,请记住速度在创建可扩展的企业级系统时并不是最重要的因素。
2,消息与同步通信的比较应用程序之间的通信不一定必须使用消息队列来进行,如果业务环境需要同步完成一些工作,那么像 D C O M这样的通信方法更适合执行这种类型的处理。如果每个应用程序都连接到 L A N,并且所有应用程序的服务器是在快速的、本地的、可靠的链路上进行连接的,也可以不用消息。另外,对许多开发人员来说,消息队列是新的和不熟悉的技术。他们可能不愿意在这方面花费精力。
下面的准则可以帮助你决定使用消息队列:
如果与你通信的应用程序不能保证与你的应用程序在同一时间运行。
如果消息很重要,丢失将会导致严重后果。
如果应用程序不是总和接收者的应用程序相连接。
如果异步执行许多与其他应用程序的通信任务,并且可能不关心它们的响应。
20.2 MSMQ结构
M S M Q系统结构的基本部分是消息、队列、队列管理器和允许程序访问信息的接口。系统在物理位置方面工作是透明的。这意味着应用程序将消息发送到另一应用程序中时,可以不必关心消息实际上是如何到达对方的。 M S M Q为在系统中查找可用的队列提供设施。一旦应用程序发现感兴趣的队列,就可以发送消息给它而不必关心消息是如何到达那里的。
M S M Q控制消息所走的路径,并可以 (如果有必要 )保证消息到达最终目的地。
M S M Q结构由一对多服务器和工作站构成,它们负责路由、发送和接收消息。
每个计算机可以包含多个消息队列,并且在每个队列内可以包含多个消息。
20.2.1 服务器类型
M S M Q可以安装在各种各样的服务器和客户上。 M S M Q有四种不同的服务器安装:
主企业控制器。
主站点控制器。
备用站点控制器。
路由器。
1,主企业控制器主企业控制器 ( P E C )是 M S M Q结构的根层,为使 M S M Q实现正常的功能,每个企业网络必须包含一个 P E C。在 MSMQ 1.0中,P E C需要 SQL Server 6.5或更高版本。在 MSMQ 2.0中,由于消息和队列存储在 Active Directory服务 ( A D S )中,因此,不需要 SQL Server。
A D S是 Windows 2000的一部分。在 NT 4上,在 MSMQ 2.0安装前,必须安装
A D S。任一版本 A D S只能在 Windows NT 4 Server上或 Windows 2000 Server上安装。
P E C是大多数的队列存储的地方,尤其是在较小的网络中。随着网络规模的扩大,对远程站点来说,在主站点控制器中保留自己的队列可能更为高效。
P E C常常位于公司总部或主要分部,这是因为所有其他服务器必须能够访问 P E C并向其注第 2 0章 A S P和消息队列服务器 计计 591下载册 (存储在 A D S中 )。如果公司的网络仅包含一个小的 L A N,需要的服务器仅是 P E C,并且它可以与 I I S合并在同一个服务器中。在大型企业中,P E C用于存储其他 M S M Q服务器的位置和队列的信息,并在它们之间路由消息,通常在此服务器上仅有 B a c k O ff i c e服务。
2,主站点控制器公司 WA N的远程分支或站点中通常存在一个主站点控制器 ( P S C ),P S C能与远程 L A N上的本地客户通信,并将消息反馈给 P E C。每个分支都有一个 P S C,提供返回 P E C的单点通信。这有助于节省资源,例如网络通信,这对远程站点是重要的,特别是在较慢网络链路上。
如上所述,在小的 L A N中,并不总是需要 P S C,其工作可由 P E C来完成。
3,备用站点控制器备用站点控制器 ( B S C )用于存储 P S C中信息的只读副本。通常每个站点安装一个 B S C,就像 P S C一样。如果 P S C失败,它提供故障屏蔽支持。
4,路由器随着企业中 M S M Q结构的不断扩大,M S M Q路由器将会变得非常有用。路由器不仅能够将消息传递到目标队列,而且也能使服务器使用不同的网络协议互相通信,例如 T C P / I P和
I P X。
M S M Q路由服务器没有存储消息的本地队列,它仅能够确定传送消息的最佳路由。当网络部分关闭时,M S M Q路由服务器非常有用。路由器会试着寻找消息到达目的地的其它路径。
在 P E C和 P S C服务器中也包含 M S M Q路由器的功能。由于每个站点都要求包含 P E C或 P S C,
这意味着每个站点都包含某种路由器。
20.2.2 客户类型客户安装比较容易掌握,因为只包含两种安装选项:
从属客户
独立客户
1,独立客户
M S M Q的独立客户可以安装在运行 Windows 9x,Windows NT 4或 Windows 2000的计算机上。独立客户具有发送消息给其他 M S M Q服务器队列和从其他 M S M Q服务器中读取消息的能力,还可以在本地队列中存储消息。
M S M Q的独立客户常安装在应用程序服务器和网络服务器上。由于独立客户可以存储消息,它们不依赖于运行在目标计算机上的 M S M Q服务。对 C O M组件或 A S P脚本来说,在想发送消息但 M S M Q服务器不可用时,这是非常有用的。这时,独立客户在本地队列中存储消息,
等到 M S M Q服务器变为可用,才传送消息 (存储和传送 )。
尽管独立客户可以具有本地队列,但它们不需要安装 A D S或 SQL Server,而是把消息和队列信息存放在文件和注册表中。这允许客户在本地具有许多 M S M Q功能。独立客户也具有通过使用 M S M Q E v e n t对象异步响应消息的能力。
安装 M S M Q独立客户时,安装向导将会对 P E C给出相应地提示信息,这样客户机可以向 P E C注册。
2,从属客户
M S M Q从属客户是 Windows 9X,Windows NT 4和 Windows 2000客户的另一选择。独立
592计计 ASP 3 高级编程 下载和从属安装之间的主要区别是从属客户不能在本地存储消息,从属客户也不能在其他服务器上建立队列或从队列中异步读取消息。
从属客户访问 M S M Q服务器时,只能发送和读取消息。由于没有本地队列,所以也不能接收消息。
由于终端用户响应消息的需求不大,从属客户通常安装在终端用户工作站上。
20.2.3 站点布局图图 2 0 - 1是跨越 WA N并具有中心 L A N的 M S M Q安装布局图。
图 20-1 SMQ安装布局图多路径配置企业级的 M S M Q安装时,必须确定两个路由器之间链路的费用。这种费用由相关因素决定。链路速度、链路有效带宽和实际链路货币花费等,这些都可算入计算机链路费用。
当执行动态路由时,M S M Q会计算出发送者和接收者间的最“廉价”的链路,并以此路径发送信息。由于不必明确创建静态路径,这使 M S M Q的配置更简单。这允许 M S M Q绕过网络柘扑的断点发送消息,因此提高了消息服务的可用性。
20.2.4 投递选项微软消息队列服务器有三种可供选择的消息投递方式,每种投递消息的方式具有不同的优点和缺点,这三种投递类型是:
内存式。
磁盘式。
事务式。
1,内存式的投递在这种投递类型中,当消息通过消息队列系统从一个队列管理器传送到另一个队列管理器时,消息依然存储在系统内存中。如果在网络和队列管理器中存在消息不能与网络中的下一个队列处理器联系的问题,那么这条消息将会被保存直到连接能恢复。内存式的投递非常第 2 0章 A S P和消息队列服务器 计计 593下载站点 A
MSMQ
客户
MSMQ
客户
PEC
PEC
MSMQ
客户
MSMQ
客户主企业控制器主站点控制器备用站点控制器路由服务器独立的或非独立的客户
MSMQ
客户
MSMQ
客户
MSMQ
客户
MSMQ
客户站点 B
站点 D站点 C
迅速,这是由于消息从来不会从系统内存中传送到磁盘。虽然这种类型的消息可以在两个队列管理器之间网络连接失败的情况下继续存在,但是当所在的机器出现故障时将会丢失。这是获得内存式投递的速度优势所必须付出的代价。
2,磁盘式的投递当消息从一个队列处理器传送到另一个队列处理器时,消息存储在每个机器的硬盘上。
当消息传到下一个机器时,随着发送机器完成传送,从前一个机器的硬盘上删除消息。由于消息必须写入所通过的所有机器的磁盘,所以会比内存式的投递花费更长的时间才能到达目的地。毕竟磁盘输入输出要比内存慢几个数量级。好处是系统出现故障时能够恢复消息,这种投递方法意味着消息通过队列管理器时,将每个消息写入磁盘,系统出现故障时不会破坏消息。此方式要求 M S M Q服务器使用可恢复文件系统,如 N T F S。
3,事务式投递最后,从传送者到接收者的所有消息的处理可被认为是一个事务。由于事务支持 A C I D特性,这意味着事务式投递的消息具有原子性、一致性、隔离性和持久性。
持久性意味着当消息在系统中传输时,事务性消息利用磁盘式投递方法将每个消息写入永久性的存储器中。原子性意味着消息只投递一次,并以发送的次序投递。
事务性消息利用 C O M +事务控制特性来提供消息投递的事务特性。这种投递方法的好处是 M S M Q
消息可以参与使用数据库操作的事务。这允许在使用 M S M Q的应用程序中建立复杂的业务规则。
20.3 管理 M S M Q
MSMQ 2.0像 Windows 2000中的许多服务一样,通过 M M C插件来进行管理。 M S M Q插件位于 Computer Mangement插件之下,如图 2 0 - 2所示。
图 20-2 MSMQ插件
M S M Q的 M M C插件完成的任务一般是增加一个新的队列,向 M S M Q服务器增加新的队列非常容易。
20.3.1 增加队列打开 Computer Management插件,然后打开 Message Queuing的下一级列表,如图 2 0 - 3所示。
594计计 ASP 3 高级编程 下载图 20-3 增加队列的窗口下一步,右击 Public Queues文件夹选择 N e w,然后选择 Public Queue。现在 M M C将显示一个提示对话框,询问队列名称和队列是否为事务性的,如图 2 0 - 4所示。
名称一般是一个用户友好的字符串,可用来识别队列 (标签 )。事务性设置决定了队列传送和接收消息时是否需要事务。本章后面将进一步介绍事务。现在只是简单地命名此队列为
A S P Tr a n s并设置为事务性的。
在本章的最后将在 M S M Q的示例中使用这个队列。
M S M Q将创建一个新的名为 A S P Tr a n s的公共队列,如图 2 0 - 5所示。
图 20-5 创建一个公共队列后的窗口第 2 0章 A S P和消息队列服务器 计计 595下载图 20-4 确定队列名称的对话框现在此队列设置为用来接收消息。首先来看一下队列的设置和 M S M Q缺省值。
20.3.2 消息队列的属性为了查看 M S M Q队列的属性,右击左边目录树中或者右边的 M M C插件中的队列,并选择
P r o p e r t i e s。将出现一个 P r o p e r t i e s对话框,此 P r o p e r t i e s对话框包含此消息队列的所有属性设置,
如图 2 0 - 6所示。
图 20-6 设置队列属性的对话框在 P r o p e r t i e s对话框中主要有两部分,G e n e r a l和 S e c u r i t y。 G e n e r a l由以下几部分组成:
Label:描述队列的字符串 (队列名称 )。
Type ID:可用于把多个队列组合在一起的 G U I D。
ID:当队列建立时由 M S M Q服务器分配的 G U I D。
Limit message storage:管理员为防止队列不断扩大而设置的队列限额。
Authenticated:决定队列是否接受客户证书。
Tr a n s a c t i o n a l:指定队列是否需要事务。
Privacy level:确定队列是否使用加密和在消息的哪一部分加密。
Base Priority:确定队列接受的最低优先级。缺省值是 0,设置值可以是从 0到 7之间的整数。
Journal:决定日志是否有效和大小的限制,日志在读取后保留消息而不进行删除。
队列属性的第二部分是 S e c u r i t y。在这里决定谁有权读取、发送和管理队列,如图 2 0 - 7所示。
在 P e r m i s s i o n s区域中有两个项要注意。这个队列对每个用户都提供了 Write Message访问,
而不是 Receive Message访问。这意味着 We b站点的客户可以发送消息而不能读取消息 (除非
We b应用程序需要用户被验证,这是正常的需要 )。权限应该是比较严格的,E v e r y o n e组应被
596计计 ASP 3 高级编程 下载撤消对队列的访问,并且只允许合适的帐户进行访问。
图 20-7 设置队列安全性属性的选项卡一旦队列接收消息,则消息位于主队列文件夹下的 Queue messages文件夹中。 M M C插件将显示队列中的所有消息。在如图 2 0 - 8所示的窗口中,有一条名为 Sample Message的消息。
图 20-8 显示队列消息的窗口
20.3.3 消息属性和队列一样,消息也有一个 P r o p e r t i e s对话框。为了查看消息的属性,右击所要查看的消第 2 0章 A S P和消息队列服务器 计计 597下载息,选择 P r o p e r t i e s。 P r o p e r t i e s对话框将显示四个选项卡,即 G e n e r a l,Q u e u e s,S e n d e r和
B o d y,如图 2 0 - 9所示。
图 20-9 General选项卡
G e n e r a l选项卡包含队列的主要只读信息,L a b e l,I D和 P r i o r i t y通常用于识别消息和其重要性。 C l a s s,S e n t日期,A r r i v e d日期和 Tr a c k e d属性通常用来审计,也可用来调试。
Q u e u e s选项卡如图 2 0 - 1 0所示,显示了具有格式名称 ( G U I D )和普通名称的三个队列。目标
( D e s t i n a t i o n )队列是消息要去的地方。大多数时候,消息在 M M C插件中显示之前就已经在目标队列中了。
响应 ( R e s p o n s e )队列指响应发送者的队列,它用来向发送者发送一个消息,使他们知道消息已经接收到。
最后,管理 ( A d m i n i s t r a t i o n )队列和响应队列的用途一样,但收到消息时会自动地由 M S M Q响应。
图 20-10 Queue选项卡 图 2 0 - 11 Sender选项卡
598计计 ASP 3 高级编程 下载
S e n d e r选项卡如图 2 0 - 11所示,由消息发送者的信息组成,包含了发送者的计算机的
I D ( G U I D )和 P a t h n a m e (计算机名称 )。此选项卡还包括发送消息的用户的登录信息,例如登录名、安全 I D ( S I D ),是否需要客户证书和所用的算法。
为了增加安全性,算法用来对消息加密。
S e n d e r选项卡所包含最后一个消息是安全性 ( S e c u r i t y )信息,描述是否加密和所用的加密算法,如图 2 0 - 11所示。
消息的 P r o p e r t i e s对话框中最后一个选项卡是 B o d y。这个选项卡是最基本的,也是非常有用的。它显示十六进制形式的消息正文。虽然很难读取,但在窗口的右侧可看到消息包含的内容的 A S C I I码,如图 2 0 - 1 2所示,,T.h.i.s.,i.s.
.a.,s.a.m.p.l.e.,m.e.s.s.a.g.e...” 。
20.4 MSMQ对象模型和大多数 B a c k O ff i c e服务一样,M S M Q有一组 COM API(MQOA.DLL),开发人员可以用来编程。 M S M Q的对象模型包括九个对象,如图 2 0 - 1 3所示。
图 20-13 MSMQ的对象模型然而,大多数的 A S P应用程序只需使用以下三个对象:
MSMQQueueInfo对象。
MSMQQueue对象。
MSMQMessage对象。
虽然如此,在开发响应和处理消息的服务器端应用程序时,能够全部理解这些对象是非常重要的。
第 2 0章 A S P和消息队列服务器 计计 599下载图 20-12 Body选项卡
20.4.1 MSMQApplication对象
M S M Q A p p l i c a t i o n对象是使用 M S M Q开发时一般不常用到的一个较小的对象。它有两个方法,M a c h i n e I d O f M a c h i n e N a m e和 R e g i s t e r C e r t i f i c a t e。 M a c h i n e I d O f M a c h i n e N a m e用来查询传递给它的服务器名对应的 G U I D。这个 G U I D可以用来指定服务器。 R e g i s t e r C e r t i f i c a t e在服务器 Active Directory中注册用户证书。
20.4.2 MSMQQuery对象
M S M Q Q u e r y对象用来在各种各样的信息中查找队列。这个对象实际只包括一个方法
L o o k u p Q u e u e,它根据传递给它的查找条件,返回一个 M S M Q Q u e u e I n f o s对象,其中包含
M S M Q Q u e u e I n f o对象的集合,这个方法的句法如下:
前面五个参数指定要查找的可用队列的属性,参数的类型和值如表 2 0 - 1所示。
表 20-1 LookupQueue方法的参数的类型和值参数 (可选 ) 类 型 作 用
Q u e u e G u i d S t r i n g 队列标别符
S e r v i c e Ty p e G u i d S t r i n g 由队列提供的服务类型
L a b e l S t r i n g 队列标签
C r e a t e Ti m e Variant Date 队列建立的时间
M o d i f y Ti m e Variant Date 上次设置队列属性的时间 (包括队列建立时间和上次更新时间 )
也可为每个参数设置布尔运算符 (除了 Q u e u e G u i d以外 ),这些运算符的缺省值是 R e l _ E Q,
意味着查询将返回一个队列集合,其中的属性正好与指定的参数匹配。这些运算符可以通过
L o o k u pQu e u e方法的最后四个参数选择,它们的名称是 R e l加上相应的属性名称,如表 2 0 - 2所示。
表 20-2 关系参数与条件参数的对应关系关系参数 相应的条件参数 关系参数 相应的条件参数
R e l S e r v i c e Ty p e S e r v i c e Ty p e G u i d R e l C r e a t e Ti m e C r e a t e Ti m e
R e l L a b e l L a b e l R e l M o d i f y Ti m e M o d i f y Ti m e
这些参数的可能值及意义如表 2 0 - 3所示。
表 20-3 关系参数的可能值及意义关 系 参 数 意 义 关 系 参 数 意 义
R E L _ E Q 相等 R E L _ L E 小于等于
R E L _ N E Q 不等 R E L _ G E 大于等于
R E L _ LT 少于 R E L _ N O P 忽视这个参数
R E L _ G T 大于为了调用 L o o k u p Q u e u e方法,应该如下编码:
600计计 ASP 3 高级编程 下载这将返回一个队列集合,这些队列的 L a b l e值都是 My Queue。
为了了解标签 ( L a b l e )相同的队列之间的区别,可在每个 M S M Q Q u e u e I n f o对象中查看 p a t h N a m e属性。
20.4.3 MSMQQueueInfos集合
M S M Q Q u e u e I n f o s是一个在 M S M Q Q u e r y对象中从 L o o k u p Q u e u e方法返回的对象。
M S M Q Q u e u e I n f o s对象是一个有限的集合 (缺少 A d d,R e m o v e,C o u n t方法 ),这个集合包含
M S M Q Q u e u e I n f o对象。它只有两个方法,N e x t使指针移到集合中的下一个对象,R e s e t使指针返回到第一个对象。
20.4.4 MSMQQueueInfo对象
M S M Q Q u e u e I n f o对象可以创建、删除和打开位于给定服务器上 M S M Q中的队列。通常使用 M S M Q对象模型做任何工作都从这一个对象开始。
1,打开队列为了使用一个队列,首先必须设置 P a t h N a m e。 P a t h N a m e属性告诉 M S M Q需要什么队列和此队列位于哪台机器上:
上面的代码打开位于本地计算机中名为 M y Q u e u e队列。定义一个本地变量后,就可创建一个 M S M QQ u e u e I n f o对象的实例。下面一行代码用于队列名称和位置的设置:
最后一行利用 O p e n方法来打开队列:
如果所需的队列位于不同的计算机中,用服务器名称来代替,objQueue,Path
Name = "SomeOtherComputer\MyQueue"
打开一个队列时,必须传递两个参数 A c c e s s和 S h a r e M o d e。 A c c e s s决定可对队列做些什么。
这个参数的可能值如下:
MQ_RECEIVE_ACCESS(1):当队列中的消息被读取后即删除。
MQ_SEND_ACCESS(2):用来向队列发送消息。
MQ_PEEK_ACCESS(32):用来在特定的队列中查找消息,而不进行删除。
第 2 0章 A S P和消息队列服务器 计计 601下载打开队列时,也需要设置其他人与队列如何交互,这由 S h a r e M o d e控制。这个参数的设置取决于在第一个参数中指定 A c c e s s方式:
如果已打开队列来用发送或查找,那么这个参数唯一有效的设置是 M Q _ D E N Y _ N O N E,
它允许其他人与队列充分交互。
如果已打开队列用来接收,可允许其他人充分访问队列 ( M Q _ D E N Y _ N O N E ),或者阻止其他人从队列中接收消息 ( M Q _ D E N Y _ R E C E I V E _ S H A R E )。
即使将这个标志设置为这些值之一,其他应用程序仍然可以把消息发送到队列中和在队列中查找消息。
O p e n例程返回 M S M Q Q u e u e对象的一个引用,该对象是消息发送和接收的地方,下面对
M S M Q Q u e u e对象做进一步的讨论。
2,创建队列创建消息队列很像打开队列,先设置 P a t h N a m e再调用 C r e a t e:
这就创建了一个公共队列。要创建个人队列,必须在队列 P a t h N a m e前面加上 P R I VAT E $:
如果想要创建用于事务处理的队列,必须将此方法的第一个参数设置为 Tr u e:
3,删除队列删除队列更简单:
20.4.5 MSMQQueue对象
M S M Q Q u e u e对象代表通过 M S M Q Q u e u e I n f o对象打开的队列。这个对象能够以类似于前移指针的方式在队列中遍历消息。
使用 M S M Q的 A S P应用程序大多数是用它来发送消息的。然而,A S P页经常需要打开队列和显示消息,例如管理页面。当消息被接收和做相应处理时,大多数启用 M S M Q的应用程序需要服务器端的程序来响应消息。这个服务器端程序,像以前描述的一样,常常是一个标准的可执行文件或用 V B或 V C + +开发的服务。
消息可以从队列中被同步或异步检索。异步读取消息允许可执行文件通过使用事件来响应消息。当消息到达所需队列时,M S M Q获得可执行文件中的代码的引用并引发事件。同步
602计计 ASP 3 高级编程 下载读取消息需要可执行文件周期地打开队列并在其中查找消息。这不仅需要占据不必要的系统资源,而且编写程序更为困难。
在 A S P页内,消息只能同步检索,因为 A S P页不能声明服务器端的变量 Wi t h E v e n t s。
关键字 Wi t h E v e n t s是 M S M Q中调用代码并在一个消息到来时引发事件的一种机制。
由于 A S P页中的变量的存在时间相对短暂,这就很有意义。然而,异步检索消息的能力对处理消息的服务器应用程序来说是非常有用的。异步访问 M S M Q消息允许应用程序等待一个表示消息到达队列的事件的发生。这样,在检索消息前服务器端应用程序不必经常占据着资源。
异步检索消息的相关内容可参考 2 0,4,7节 。
在同步检索消息时,代码执行一直等待,直到消息可用或者超时。下面的代码说明如何打开队列并显示消息:
上面的代码从使用 M S M Q Q u e u e对象开始,并且进入 Do While? L o o p循环,一直循环到
M S M Q Q u e u e对象的 P e e k例程返回 N o t h i n g。当这个例程返回 N o t h i n g时,就意味着超时或者队列中没有更多的消息。在本例中,时间期限设置为 1 0 0 0 m s。
在进入 Do loop循环前,必须使用 P e e k C u r r e n t方法将指针设置在队列的第一条消息上。
20.4.6 MSMQMessage对象
M S M Q M e s s a g e对象是 M S M Q的重要部分。它使所有启用 M S M Q的应用程序能够发送和读第 2 0章 A S P和消息队列服务器 计计 603下载取消息。
M S M Q M e s s a g e对象用于保持各种各样的信息。实际上,消息的正文能够保持字符串、字节数组甚至是可永久的 C O M对象的实例。
消息的标签 ( L a b l e )是一个简单描述消息的字符串,与电子邮件的标题相类似。
可以通过打开或查找消息对其进行检索。当打开消息时,一旦读取消息,就会在队列中删除此消息。然而,当查找消息时,在消息到期之前,它会一直存在于队列中。打开和查找消息,可在 M S M Q Q u e u e对象中通过 O p e n和 P e e k例程执行,它们将返回消息的一个引用。
下列的代码表明怎样打开消息和显示消息的正文和标签:
以上的示例是从打开队列开始的,然后在 1 0 0 m s的时间内调用 R e c e i v e例程在队列内查找消息。时间期限用来告诉 M S M Q什么时候停止等待消息。
当时间期限设置得很短时,不是等待接收消息而是检查已存在的消息。
为了查看是否有消息,检测 R e c e i v e函数返回的 M S M Q M e s s a g e对象是否为 N o t h i n g。如果
R e c e i v e返回一个有效消息,代码将显示 L a b e l和 B o d y属性。
发送消息是 A S P中的 M S M Q完成的最普通的任务。为了传送消息,队列以发送访问方式
( M Q _ S E N D _ A C C E S S )打开,并且在调用 M S M Q M e s s a g e对象中的 S e n d例程前准备好消息:
604计计 ASP 3 高级编程 下载上面的代码的开始部分与其他的示例代码类似,打开一个队列,这个队列是以发送访问方式打开的。下一步,通过创建 MSMQMessage 对象的实例和设置 L a b e l和 B o d y属性完成消息的建立。最后,通过调用消息的 S e n d方法发送消息,并将目标队列的引用作为一个参数传递给它。
20.4.7 MSMQEvent对象对于用 V B和 V C + +语言创建的服务器端应用程序来说,M S M Q E v e n t对象是非常有用的。
因为这个对象为 M S M Q提供调用代码和在队列接收到消息时引发事件的一个机制 (异步读取 )。 M S M Q E v e n t对象是比较小的对象,实际上它没有属性或方法,只包括两个事件,如表
2 0 - 4所示。
表 20-4 MSMQEvent对象的事件及说明事 件 说 明
A r r i v e d 用来从队列中异步检索消息,每次指定的队列接收消息,在代码中激活这个事件
A r r i v e d E r r o r 用来从队列中异步检索消息,如果在试图监听指定队列中的消息时发生错误的话,
在代码中引发这个事件本章后面将介绍怎样在服务器端可执行文件中使用这些事件。
20.4.8 MSMQTr a n s a c t i o n对象
M S M Q Tr a n s a c t i o n对象用来告知 M S M Q终止或提交一个事务,它由 M S M Q Tr a n s a c t i o n
D i s p e n s e r或 M S M Q C o o r d i n a t e n Tr a n s a c t i o n D i s p e n s e r对象通过使用 A b o r t或 C o m m i t方法来进行。
M S M Q Tr a n s a c t i o n对象的实例不能用 N e w关键字或 C r e a t e O b j e c t函数创建。它是通过使用 M S M Q Tr a n s a c t i o n D i s p e n s e r和 M S M Q C o o r d i n a t e d Tr a n s a c t i o n D i s p e n s e r对象中的 B e g i n Tr a n s a c t i o n方法创建的。
20.4.9 MSMQTr a n s a c t i o n D i s p e n s e r对象
M S M Q Tr a n s a c t i o n D i s p e n s e r对象提供了在一个事务中将多个消息打包发送或接收 M S M Q
第 2 0章 A S P和消息队列服务器 计计 605下载中多个队列中的消息的能力。对内部的 M S M Q事务,使用这个对象非常有用,但不能包括
SQL Server数据库更新或添加等其他任何事情。当需要事务时,只能包括在 M S M Q中使用
M S M Q Tr a n s a c t i o n D i s p e n s e r对象事务的操作。由于不必处理分布式事务协调器 ( D T C )带来的额外开销,所以它比 M S M Q C o o r d i n a t e d Transaction Dispenser事务快。
20.4.10 MSMQCoordinatedTr a n s a c t i o n D i s p e n s e r对象
M S M Q C o o r d i n a t e d Tr a n s a c t i o n D i s p e n s e r对象完成与 M S M Q Tr a n s a c t i o n D i s p e n s e r对象相似的功能。然而这个对象提供了使用 Microsoft DTC强大功能的方式,因此能够在事务中协调任何 D T C支持的数据源。
2 0,4,11 访问 M S M Q的其他方式
COM API中有另外一个提供给 C和 C + +开发人员使用的 A P I。它为有经验的 C / C + +开发人员提供了能够获取端口通信和基本指针的一种方式。
在 A P I层中获得 M S M Q功能超出了本书的范围。有关方面的信息可参考微软的 M S D N站点
( w w w,m s d n,M i c r o s o f t,c o m )或 M S M Q运行期的帮助文件。
20.5 用于 M S M Q的 MS DTC事务通过使用 D T C,事务不仅能完成从队列中读写消息,还可包含其他任何支持 D T C的服务。
这使开发人员能够编写方法来修改像 SQL Server(6.5或 7,0 )这样的数据库中的数据,并在单个事务中从一个队列中发送或读取消息。
包括多个 D T C相容服务的事务也可通过 C O M +放入一个事务中,这使开发人员可以将代码封装到 COM DLL中,并将其置于 C O M +控制之下。
虽然 M S M Q的 M S M Q C o o r d i n a t e d Tr a n s a c t i o n D i s p e n s e r对象提供使用 D T C的功能的途径,
开发人员也可通过 C O M +使用事务来完成相同工作。
C O M +的运行期与 M S M Q的 M S M Q C o o r d i n a t e d Tr a n s a c t i o n D i s p e n s e r对象提供的能力相同。
实际上幕后也是相同的。然而,通过 C O M +开发事务具有更大的灵活性和更多的功能。
20.6 高级 M S M Q消息到目前为止,代码示例使用的消息正文仅包括简单字符串值。下面看一下更有趣的情况。
M S M QMe s s a g e对象的 B o d y属性实际上定义为接收 Va r i a n t数据类型的值。这就是说,消息的正文可包括字符串、日期、货币、数字、字节数组或甚至是实现 (支持 ) I D i s p a t c h和
I P e r s i s t ( I P e r s i s t S t r e a m或 I P e r s i s t S t o r a g e )接口的 C O M对象。
这说明在 M S M Q消息中发送字符串、日期和数组是非常容易的,只是简单地把消息的正文设置为变量即可:
606计计 ASP 3 高级编程 下载这是非常简单的。现在研究在消息中保存的 C O M对象实例。
消息中的 C O M对象使用 VB 6,开发人员可以开发一些用 V C + +需要很长时间才能开发的程序。可以通过
I P e r s i s t接口产生出能够保持的 C O M对象。尽管这是由 V B运行期在幕后完成的,但仍为使用 V B
的开发人员创建业务逻辑提供了新的途径。
I P e r s i s t接口提供一个 M S M Q可以查找和调用的一般接口,可以使对象串行化自身。当 V B对象对自己串行化时,它会取出内部信息 (变量和相应的值 )并将其放入 P r o p e r t y b a g。然后 V B运行期从 P r o p e r t y b a g中读取数据并通过 I P e r s i s t接口将这些数据串行化。这个串行化的二进制数据实际存放在 M S M Q消息的正文中。
为了创建支持 I P e r s i s t接口的组件,设置类属性 P e r s i s t a b l e为 1 - P e r s i s t a b l e,如图 2 0 - 1 4所示。
一旦设置了 P e r s i s t a b l e标志,三个事件会添加到 C l a s s事件中:
InitProperties。
ReadProperties。
Wr i t e P r o p e r t i e s。
I n i t P r o p e r t i e s事件用来在 R e a d P r o p e r t i e s事件引发前设置任何缺省值或设置任何其他东西。
R e a d P r o p e r t i e s和 Wr i t e P r o p e r t i e s事件非常简单。它们提供对 P r o p e r t y B a g读写状态 (内部数据 )的事件,这个 P r o p e r t y B a g将存放在 M S M Q M e s s a g e对象中。
下面的代码展示了类是如何支持持续特性的,注意事件处理器 C l a s s _ R e a d P r o p e r t i e s和
C l a s s _ Wr i t e P r o p e r t i e s。当 M S M Q查找 I P e r s i s t接口时,V B运行期将要调用这些事件。注意,
V B类并不真的支持 I P e r s i s t接口。 V B运行期对开发人员隐藏这一事实,作为类事件来传递这个调用:
第 2 0章 A S P和消息队列服务器 计计 607下载图 20-14 类属性设置窗口现在,已经创建了 C O M组件,下面调用这个类,并把内部状态 ( P r o p e r t y B a g中的
m s t r F i r s t N a m e和 m s t r L a s t N a m e )放在消息的正文中。 V B中此代码比较容易。
由创建一个类实例开始并设置 F i r s t N a m e和 L a s t N a m e属性。下一步为发送访问打开队列。
最后一步是通过创建 M S M Q M e s s a g e对象的实例,设置 L a b e l为一个字符串,设置 B o d y的值为已定义的类实例。所有这些工作对对象使用者隐藏:
608计计 ASP 3 高级编程 下载看上去这些代码 (对于 V B S c r i p t稍做改变 )可用于 A S P页面中。但事实上不是这样的。所有代码都会正常工作,但将对象放在消息正文中的那一行代码将会出错。导致的错误描述为:
,Cannot save an uninitialized class,You must use the global InitProperties method to
initialize the class,or load the class from a PropertyBag before trying save it.”
(“不能保存一个未初始化的类。必须使用全局 I n i t P r o p e r t i e s方法来初始化这个类,或在保存前从 P r o p e r t y B a g中装载这个类。,)
这是一个非常讨厌的错误 (或限制 ),即使将保存消息正文到组件的逻辑移到组件本身,
仍然存在相同的问题。因此如果想在队列中保持 C O M对象,那么必须创建一个组件来完成。
20.7 COM+队列化组件考虑 C O M +的附加特性,C O M组件现在可以配置为作为队列化组件运行。
队列化组件允许 C O M对象的用户 ( c o n s u m e r )通过 M S M Q与对象进行通信,且不需要修改 C O M对象或用户的任何代码。
队列化组件使用了四个代码块,分别称为
r e c o r d e r,q u e u e,l i s t e n e r和 p l a y e r,允许客户与队列化 C O M对象通信。 r e c o r d e r记录了客户与对象的交互,将信息绑定到 M S M Q消息中,并发送到 M S M Q中的队列。这个服务器上的 l i s t e n e r
响应来自客户的 r e c o r d e r的消息,并把消息发送到 p l a y e r,然后 p l a y e r读取此消息并调用客户使用的方法。它们之间的关系如图 2 0 - 1 5所示。
第 2 0章 A S P和消息队列服务器 计计 609下载图 20-15 四个代码块与客户及服务器之间的关系图 20-16 设置队列化组件客户服务器
player
listener
queuerecorder
队列化组件非常有用,但它们也有局限性。由于客户不能与 C O M对象直接交互,不能使用通过引用传递的参数或有返回值的函数。但是,队列化组件对于调用 C O M对象的子程序是非常有用的。
要作为队列化组件来设置 C O M对象,只需在 COM+ MMC插件中简单看一下包含此 C O M
对象的包的属性,选择 Q u e u i n g选项卡,选择 Q u e u e d和 L i s t e n选项,如图 2 0 - 1 6所示。
关于队列化组件特点的信息可参考 M i c r o s o r f t的 M S D N网站,网址为 w w w,m s d n,
m i c r o s o f t,c o m或 M S M Q运行期的帮助文件。
20.8 扩展联机订货的示例我们已经看到了如何使用 M S M Q的相关内容,下面将扩展前一章中的示例程序,让它利用 M S M Q I作。这里将以两种不同的方式来示范 M S M Q的使用。
首先,修改订单放置组件,将订单发送到队列中,而不是直接更新数据库。
其次,创建一个服务器端可执行程序,这个程序等待和处理发到队列的消息,把订单实际存放在数据库中。
首先我们需要在组件中添加相应的一些代码。
20.8.1 在组件中添加 M S M Q
我们将使用本章前面创建的 A S P Tr a n s队列。你现在应该认识到为什么将其设置为事务性的。因为我们想使其与这个组件包含在同一事务中。
打开 A S P Tr a n s项目,在加入任何新代码前,必须加入对 MSMQ 2.0类型库的引用,如图
2 0 - 1 7所示。
图 20-17 添加对 MSMQ 2.0类型库的引用下一步,加入代码把消息发送到 M S M Q中的 A S P Tr a n s队列里。我们将改变这个程序的功能,以使这个订单放在队列中而不是立刻发生作用。
610计计 ASP 3 高级编程 下载把这个代码放在 O r d e r组件的 P l a c e O r d e r子程序中,其中没有我们没见过的代码:
第 2 0章 A S P和消息队列服务器 计计 611下载现在如果重新编译并加入一个新的订单,会发现订单已存放在 A S P Tr a n s队列中,如图 2 0 -
1 8所示。
图 20-18 添加订单后的 A S P Tr a n s队列然而,这个订单任务仅完成了一半,需要将订单从队列取出并放入数据库中。
20.8.2 处理队列化订单我们将使用 M S M Q E v e n t对象“监听”订单被放入队列这一事件,完成这个工作的是一个非常简单的服务器端的标准可执行程序。当消息放置好后,仍使原来的 I N S E RT语句存储订单。
创建一个新的 Visual Basic Standard EXE项目,并增加对 MSMQ 2.0 Object Library和
ActiveX Data Objects 2.5 Library的引用现在,在 V B项目的窗体中加入一个列表框。下一步,进入代码窗口并加入下列的代码:
612计计 ASP 3 高级编程 下载上面的程序是由 F o r m _ L o a d事件开始的,然后打开 A S P Tr a n s队列。下一步,代码设置
m o b j M S M Q E v e n t对象并把它链接到队列中。这由调用 M S M Q Q u e u e对象的 E n a b l e N o t i f i c a t i o n方法来完成。一旦 M S M Q E u e n t对象链接上了,剩下的事情就是处理 A r r i v e d和 A r r i n e d E r r o r事件。
每当在队列中接收到新的消息时才引发 A r r i v e d事件,这时把消息正文中的订单细节取出来,并把它放到的数据库中。
一旦接收了消息,必须再次调用 E n a b l e N o t i f i c a t i o n方法使 M S M Q在下一个消息到来时通第 2 0章 A S P和消息队列服务器 计计 613下载知代码。如果代码调用 E n a b l e N o t i f i c a t i o n失败,将永远不会见到下一个消息。
现在可以试验代码了。从编译可执行文件或在 V B开发环境中运行代码开始。注意当窗体的 L o a d事件引发时,队列为接收访问而打开,并且 M S M Q E u e n t对象会用来查找消息。
如果在队列中存在任何消息,V B应用程序会立刻响应,如图 2 0 - 1 9所示。
现在回到浏览器,再加入一些新的订单。注意,V B应用程序已经处理了它们。现在停止执行 V B应用程序并加入更多的订单。直到 V B应用程序重新启动之前,这些订单作为队列中的消息在等待着。 V B应用程序开始执行,这时消息 (订单 )将被处理并且队列重新变空。
20.9 小结
M S M Q提供了一个中间层。使用这个中间层,
应用程序之间可以在松散配合的情况下以异步方式互相交流。在一个设计较好的 C O M对象模型中,各种各样的程序语言都可以使用 M S M Q。
本 章 讨 论 了 微 软 消 息 队 列 服 务 器 系 统,
M S M Q允许应用程序之间异步通信,即使这些应用程序不在同一时间内运行或应用程序之间的连接是不可靠的。理解它的最简单的方式是,
把它当作供应用程序使用的电子邮件。对一个系统的互连网络来说,M S M Q系统允许消息在网络之间来回传送。系统指出了消息传输的目的地,并确证消息到达。 M S M Q可从 A S P或者
A S P组件通过 C O M接口直接起作用。
本章主要讨论了以下几个方面的问题:
消息排队的定义。
MSMQ及其结构。
MSMQ能做什么。
如何管理 M S M Q。
如何使用 C O M对象与 M S M Q交互。
创建与 M S M Q交互的组件。
在 A S P应用程序中使用 M S M Q组件。
MSMQ消息的异步响应。
如何将 M S M Q合并到事务中。
614计计 ASP 3 高级编程 下载图 20-19 响应窗体
迄今为止,我们假设一个服务器是一个始终有效的完美世界,但是如果没有这个前提,
整个的系统会崩溃吗?显然不会。不过有必要采用一个异步通信系统,通常称为消息或者消息队列。
在消息方案中,应用程序不再是执行一般的方法调用和等待一个响应,取而代之的是,
调用者简单地发一个“消息”给服务器,然后按正常程序进行处理,因此消息不仅允许客户处理其他工作,而且由于利用了 Microsorft 消息队列 ( M S M Q ),服务器甚至可以是不可用的,
因为消息可以被排队并在以后处理。
本章将讨论消息排队的以下几个方面内容:
消息排队的定义。
MSMQ及其结构。
MSMQ的管理。
如何使用 C O M对象与 M S M Q交互。
在 A S P应用程序中 M S M Q组件的使用。
MSMQ消息的异步响应。
如何将 M S M Q合并到事务中。
首先,介绍消息排队的背景知识。
20.1 消息排队的定义消息排队是允许不同的应用程序使用“存储和传送”过程进行彼此交流的系统。
这些应用程序可以在相同或不同的硬件平台上。这些平台可以位于同一场所、同一 L A N
或者是由电子装置相连的任何地方,这种连接甚至不需要是永久的或可靠的,除此之外,这些平台甚至可在不同的操作系统中运行。
这听起来好像是一个非常复杂的系统。当今 I n t e r n e t世界的特点是各种各样的应用程序、
各种不同的地理位置、各种各样的连接类型和操作系统同时存在。能在这些系统之间传送数据已经成为主张互连的人们的共同目的。
在复杂的系统环境中,S Q L,O D B C,F T P和 H T T P等技术都为数据在系统之间传送提供了不同的机制,这些技术的主要缺点是面向特定的应用程序类型。当数据需要在复杂的平台间有效转换时,非常需要一种中间的应用程序。交换数据的格式和平台到平台的交互规则应当留给特定的应用程序去完成。这种技术只是一个通信信道。利用这些系统已经创建出大量系统的事实,并不意味着不存在更为有效的通信方法。
消息中间件系统在大型计算机领域中是众所周知的,多年来已经成为大容量的事务处理应用程序的模式。在个人计算机中也有许多消息技术,但我们主要考虑 M S M Q,因为 M S M Q
与 A S P和其他微软开发工具紧密相关。
20.1.1 MSMQ的定义
M S M Q的基本概念非常简单,就是应用程序的电子邮件。
与电子邮件一样,M S M Q消息也有发送者和接收者。然而接收者有些不同,M S M Q中消息接收者定义为访问队列者 (这是由 Wi n d o w s域安全性设置的 )。这样在单一的队列中多个接收者能够响应单一的消息。在大多数使用 M S M Q的网络应用程序中,消息的发送者是 We b服务器 ( I I S ),消息的接收者是自定义的应用程序。
当 M S M Q消息形成后,即被打包到一个“容器”中,并发送到一个队列中,等待接收者读取。这些队列不管网络连接的状态和可靠性如何,都能够保证消息传送 (存储和传送 )。
自定义应用程序不一定在不同的机器上,但是放在另一台机器上可提供更好的可扩展性。
在大多数使用 M S M Q的 A S P应用程序中,消息从 A S P脚本或从 C O M组件中传送到同一个服务器或另外一个机器中的队列中。一旦消息发送,A S P可以继续进行处理。在后台,另一个自定义服务器端应用程序 (通常用 C O M相容的工具创建,如 Visual Basic或 Visual C++)响应消息并开始着手处理。另外的一个响应并处理 M S M Q消息的可能途径是建立一个使用
V B S c r i p t来打开队列的 S Q L 7,0服务器作业。
M S M Q也可以和其他的消息系统相互通信。 Level 8系统正在开发第三方解决方案用于与其他平台上的 M S M Q通信,例如 Sun Solaris,H P _ U N I X,O S / 2,V M S和
A S / 4 0 0平台等。
1,消息前面已经提到 M S M Q中的消息与电子邮件消息相类似,然而,它们不是发送给单个用户或一组用户,而是从一个应用程序发送到一个计算机的一个队列中。
M S M Q消息主要由三部分构成:
标签。
正文。
目标队列。
标签与电子邮件消息中的主题非常相似,大多数情况下标签用来把各种类型的消息分组,
使自定义的应用程序能够区分消息所包含的内容。
M S M Q消息的正文是各种各样的,能够保存从字符串、数组到 C O M对象的任何内容。消息排队系统本身不检查实际内容,并且消息内容的格式也没有明确的标准。这意味着内容格式由传递消息的两个应用程序自行决定。
例如,以创建一个 E x c e l应用程序对象为例,载入一个电子表格,并设置 M S M Q消息的正文为 E x c e l的实例。读取这条消息时,E x c e l对象的实例就会被取出来。唯一的需要是消息的发送者和接收者都必须将此组件注册到系统上。
消息也可包括实现专有的消息,例如谁是发送者和接收者、发送的时间标识、
甚至是截止日期,即如果超过这一时间不进行读取将删除消息。
588计计 ASP 3 高级编程 下载
M S M Q消息也包括决定消息读取顺序的优先级属性,它与电子邮件中的优先级非常类似。
消息中的优先级可以是 0 ~ 7的任何整数,决定消息存放到队列中的顺序。新添加的消息不一定就存放在队列的底部。例如一个优先级为 6的消息将放在优先级为 5的前面。数目越小,优先级越低。 M S M Q消息的缺省优先级为 3。但是发送到事务处理消息队列中的消息会将优先级自动设置为 0,这是因为事务忽略优先级。
2,队列消息队列是指消息被目标应用程序取走之前所存放的地方。与电子邮件比较,队列类似于收件信箱。消息在期满或被读取前存放在队列中 (除非清除队列 )。
系统中可以有多个队列,但 M S M Q支持大量连接的系统的分层结构。然而,在任何具体的机器中,队列管理器管理着本机的所有队列,通常包含在此机器上预定接收消息的所有队列,但也不总是这样。如果网络管理员对远程队列管理器进行适当的配置,大多数的消息产品允许直接确定远程机器中队列的位置。队列管理器决定这个消息的最终目标是否是本地。
如果是本地,就把消息放在目标队列中。如果不是本地,通过目录服务器找出目标队列所在的机器。一旦目标队列服务器收到消息,就将其存放在目标队列中。
每个队列属于单个服务器,但一个服务器可以有多个队列。
队列的主要属性有:
标签:通常用来定义队列的简单字符串。
ID:用来定义队列的唯一的 G U I D。
Ty p e I D:用来定义队列类型或组的唯一的 G U I D。
Ty p e I d很有可能在多个队列中是相同的,这些队列组合在一起执行共同的任务。
另外,在 MSMQ 2.0中有四种类型的队列:
输出队列 (outgoing queue):当远程 M S M Q服务器不起作用时保存消息。它们为 M S M Q
提供了操作灵活性,即使在另外一个服务器不工作时也一样不会丢失消息。不能通过应用程序使用输出队列,它只能由 M S M Q内部用于存储和传送消息。
系统队列 (system queue):也是由 M S M Q内部使用的,对自定义应用程序不起作用的。
这种队列的例子是无法投递的邮件的队列、报告队列和报纸队列。
公共队列 (public queue):它是 M S M Q中最常用的一种队列,自定义应用程序用这个队列完成业务需要。公共队列存储在 Active Directory服务中,因此,对于企业范围内的所有其他 M S M Q服务器都是可知的。
个人队列 (private queue):可在自定义应用程序中使用。然而在 Active Directory中没有个人队列。因而它们对本地计算机以外的应用程序来说是不可用的。
虽然消息队列可以通过编程建立,但是多数情况下,消息队列是通过 Computer Management
插件的 M S M Q部分建立的,管理 M S M Q的有关信息可参考下面的 2 0,3节“管理 M S M Q”的内容。
20.1.2 使用 M S M Q和 A S P的原因为什么使用 M S M Q?为什么不通过 D C O M开发使 A S P能获得所需功能的简单 C O M组件?
为了回答这个问题,我们提出以下几个问题:
如果正在运行 C O M对象的服务器不可用怎么办?
第 2 0章 A S P和消息队列服务器 计计 589下载
如果运行时间太长,A S P页超时而且用户放弃怎么办?
如果由于在正常时间内因为表格锁定或处理器紧张而不能进行处理怎么办?
这些问题是开发 M S M Q服务的原因。通过使用 M S M Q,这些问题可以通过相对比较简单的方法来解决。
( 1 )如果正在运行 C O M对象的服务器不可用该怎么办?
如果客户不是直接和 C O M对象对话而是发给 M S M Q一个消息,则在客户和服务 ( C O M )对象之间提供另一抽象层。这就是所谓的异步通信的松散连接。
当然,通常 C O M对象不能自己运行,但可以开发响应消息和调用 C O M对象功能的服务器端可执行程序。由于客户与后台分离,只要 We b服务器 ( I I S )安装了 M S M Q客户,客户可以仅仅发出消息并继续运行。
( 2 )如果运行时间太长怎么办?
这个问题的解决方法和上面的情况一样。通过把处理工作移到后台服务器上进行,客户就不必等到任务完成。
( 3 )如果由于在正常时间内不能进行处理该怎么办?
如果处理工作在正常的高峰时间内不能完成,这个任务可以存放在消息队列中直到预定的服务器端可执行程序准备处理此项任务 (队列中的消息 ),这允许任何数量的消息或任务同时存储或运行。
这就是所谓的批处理。
1,速度与可用性的比较通常消息中间件被认为是一种提高可用性和可扩展性的技术。这不应该与速度混淆。消息总是比低层的内部处理通信的方法要慢,如套接字 ( S o c k e t )或命名管道 (named pipe)。毕竟消息最终要利用这些方法来传递。中间件技术向通信协议基本性能增加了协商 ( n e g o t i a t i o n )和通告 ( n o t i f i c a t i o n )的开销。
消息中间件认为不论技术怎么快,都达不到足够快的速度。这不仅包括处理器也包括通信。除非机器能在零时间内无限装载,否则总有可能过载,这就是消息中间件的设计原因。
首先,通过将异步通信引入到处理中,在等待一个消息的响应时,客户可以去处理别的任务。因为队列管理器把输入的消息存放在一个缓冲区中,即队列中。接收服务器没有必要具有足以处理峰值通信量的速度,仅仅需要满足系统中通信量的平均值的处理需求。在峰值过程中,进入的额外消息将退到队列中去,当通信量减少时再发送,然后从队列中清除。在有额外消息退到队列中去时,对于必须同步处理消息的系统会失败,即可用性差。但是异步消息系统的服务仍然可用。
因而,消息是一个可扩展的解决方法,异步消息系统的优点在于可以成功地处理更多的通信量,而不在于处理速度。
这也说明了低层协议中增加的附加特性的作用。消息中间件对企业级系统提供一系列重要的特性以降低额外开销:
它改善了可用性。
它考虑了偶然断开计算机连接这种可能出现的情况,这在基本协议中是不允许的。
它允许传送者和接收者知道发出的消息已收到,并且一旦收到就能知道。
590计计 ASP 3 高级编程 下载当我们继续学习本章内容时,请记住速度在创建可扩展的企业级系统时并不是最重要的因素。
2,消息与同步通信的比较应用程序之间的通信不一定必须使用消息队列来进行,如果业务环境需要同步完成一些工作,那么像 D C O M这样的通信方法更适合执行这种类型的处理。如果每个应用程序都连接到 L A N,并且所有应用程序的服务器是在快速的、本地的、可靠的链路上进行连接的,也可以不用消息。另外,对许多开发人员来说,消息队列是新的和不熟悉的技术。他们可能不愿意在这方面花费精力。
下面的准则可以帮助你决定使用消息队列:
如果与你通信的应用程序不能保证与你的应用程序在同一时间运行。
如果消息很重要,丢失将会导致严重后果。
如果应用程序不是总和接收者的应用程序相连接。
如果异步执行许多与其他应用程序的通信任务,并且可能不关心它们的响应。
20.2 MSMQ结构
M S M Q系统结构的基本部分是消息、队列、队列管理器和允许程序访问信息的接口。系统在物理位置方面工作是透明的。这意味着应用程序将消息发送到另一应用程序中时,可以不必关心消息实际上是如何到达对方的。 M S M Q为在系统中查找可用的队列提供设施。一旦应用程序发现感兴趣的队列,就可以发送消息给它而不必关心消息是如何到达那里的。
M S M Q控制消息所走的路径,并可以 (如果有必要 )保证消息到达最终目的地。
M S M Q结构由一对多服务器和工作站构成,它们负责路由、发送和接收消息。
每个计算机可以包含多个消息队列,并且在每个队列内可以包含多个消息。
20.2.1 服务器类型
M S M Q可以安装在各种各样的服务器和客户上。 M S M Q有四种不同的服务器安装:
主企业控制器。
主站点控制器。
备用站点控制器。
路由器。
1,主企业控制器主企业控制器 ( P E C )是 M S M Q结构的根层,为使 M S M Q实现正常的功能,每个企业网络必须包含一个 P E C。在 MSMQ 1.0中,P E C需要 SQL Server 6.5或更高版本。在 MSMQ 2.0中,由于消息和队列存储在 Active Directory服务 ( A D S )中,因此,不需要 SQL Server。
A D S是 Windows 2000的一部分。在 NT 4上,在 MSMQ 2.0安装前,必须安装
A D S。任一版本 A D S只能在 Windows NT 4 Server上或 Windows 2000 Server上安装。
P E C是大多数的队列存储的地方,尤其是在较小的网络中。随着网络规模的扩大,对远程站点来说,在主站点控制器中保留自己的队列可能更为高效。
P E C常常位于公司总部或主要分部,这是因为所有其他服务器必须能够访问 P E C并向其注第 2 0章 A S P和消息队列服务器 计计 591下载册 (存储在 A D S中 )。如果公司的网络仅包含一个小的 L A N,需要的服务器仅是 P E C,并且它可以与 I I S合并在同一个服务器中。在大型企业中,P E C用于存储其他 M S M Q服务器的位置和队列的信息,并在它们之间路由消息,通常在此服务器上仅有 B a c k O ff i c e服务。
2,主站点控制器公司 WA N的远程分支或站点中通常存在一个主站点控制器 ( P S C ),P S C能与远程 L A N上的本地客户通信,并将消息反馈给 P E C。每个分支都有一个 P S C,提供返回 P E C的单点通信。这有助于节省资源,例如网络通信,这对远程站点是重要的,特别是在较慢网络链路上。
如上所述,在小的 L A N中,并不总是需要 P S C,其工作可由 P E C来完成。
3,备用站点控制器备用站点控制器 ( B S C )用于存储 P S C中信息的只读副本。通常每个站点安装一个 B S C,就像 P S C一样。如果 P S C失败,它提供故障屏蔽支持。
4,路由器随着企业中 M S M Q结构的不断扩大,M S M Q路由器将会变得非常有用。路由器不仅能够将消息传递到目标队列,而且也能使服务器使用不同的网络协议互相通信,例如 T C P / I P和
I P X。
M S M Q路由服务器没有存储消息的本地队列,它仅能够确定传送消息的最佳路由。当网络部分关闭时,M S M Q路由服务器非常有用。路由器会试着寻找消息到达目的地的其它路径。
在 P E C和 P S C服务器中也包含 M S M Q路由器的功能。由于每个站点都要求包含 P E C或 P S C,
这意味着每个站点都包含某种路由器。
20.2.2 客户类型客户安装比较容易掌握,因为只包含两种安装选项:
从属客户
独立客户
1,独立客户
M S M Q的独立客户可以安装在运行 Windows 9x,Windows NT 4或 Windows 2000的计算机上。独立客户具有发送消息给其他 M S M Q服务器队列和从其他 M S M Q服务器中读取消息的能力,还可以在本地队列中存储消息。
M S M Q的独立客户常安装在应用程序服务器和网络服务器上。由于独立客户可以存储消息,它们不依赖于运行在目标计算机上的 M S M Q服务。对 C O M组件或 A S P脚本来说,在想发送消息但 M S M Q服务器不可用时,这是非常有用的。这时,独立客户在本地队列中存储消息,
等到 M S M Q服务器变为可用,才传送消息 (存储和传送 )。
尽管独立客户可以具有本地队列,但它们不需要安装 A D S或 SQL Server,而是把消息和队列信息存放在文件和注册表中。这允许客户在本地具有许多 M S M Q功能。独立客户也具有通过使用 M S M Q E v e n t对象异步响应消息的能力。
安装 M S M Q独立客户时,安装向导将会对 P E C给出相应地提示信息,这样客户机可以向 P E C注册。
2,从属客户
M S M Q从属客户是 Windows 9X,Windows NT 4和 Windows 2000客户的另一选择。独立
592计计 ASP 3 高级编程 下载和从属安装之间的主要区别是从属客户不能在本地存储消息,从属客户也不能在其他服务器上建立队列或从队列中异步读取消息。
从属客户访问 M S M Q服务器时,只能发送和读取消息。由于没有本地队列,所以也不能接收消息。
由于终端用户响应消息的需求不大,从属客户通常安装在终端用户工作站上。
20.2.3 站点布局图图 2 0 - 1是跨越 WA N并具有中心 L A N的 M S M Q安装布局图。
图 20-1 SMQ安装布局图多路径配置企业级的 M S M Q安装时,必须确定两个路由器之间链路的费用。这种费用由相关因素决定。链路速度、链路有效带宽和实际链路货币花费等,这些都可算入计算机链路费用。
当执行动态路由时,M S M Q会计算出发送者和接收者间的最“廉价”的链路,并以此路径发送信息。由于不必明确创建静态路径,这使 M S M Q的配置更简单。这允许 M S M Q绕过网络柘扑的断点发送消息,因此提高了消息服务的可用性。
20.2.4 投递选项微软消息队列服务器有三种可供选择的消息投递方式,每种投递消息的方式具有不同的优点和缺点,这三种投递类型是:
内存式。
磁盘式。
事务式。
1,内存式的投递在这种投递类型中,当消息通过消息队列系统从一个队列管理器传送到另一个队列管理器时,消息依然存储在系统内存中。如果在网络和队列管理器中存在消息不能与网络中的下一个队列处理器联系的问题,那么这条消息将会被保存直到连接能恢复。内存式的投递非常第 2 0章 A S P和消息队列服务器 计计 593下载站点 A
MSMQ
客户
MSMQ
客户
PEC
PEC
MSMQ
客户
MSMQ
客户主企业控制器主站点控制器备用站点控制器路由服务器独立的或非独立的客户
MSMQ
客户
MSMQ
客户
MSMQ
客户
MSMQ
客户站点 B
站点 D站点 C
迅速,这是由于消息从来不会从系统内存中传送到磁盘。虽然这种类型的消息可以在两个队列管理器之间网络连接失败的情况下继续存在,但是当所在的机器出现故障时将会丢失。这是获得内存式投递的速度优势所必须付出的代价。
2,磁盘式的投递当消息从一个队列处理器传送到另一个队列处理器时,消息存储在每个机器的硬盘上。
当消息传到下一个机器时,随着发送机器完成传送,从前一个机器的硬盘上删除消息。由于消息必须写入所通过的所有机器的磁盘,所以会比内存式的投递花费更长的时间才能到达目的地。毕竟磁盘输入输出要比内存慢几个数量级。好处是系统出现故障时能够恢复消息,这种投递方法意味着消息通过队列管理器时,将每个消息写入磁盘,系统出现故障时不会破坏消息。此方式要求 M S M Q服务器使用可恢复文件系统,如 N T F S。
3,事务式投递最后,从传送者到接收者的所有消息的处理可被认为是一个事务。由于事务支持 A C I D特性,这意味着事务式投递的消息具有原子性、一致性、隔离性和持久性。
持久性意味着当消息在系统中传输时,事务性消息利用磁盘式投递方法将每个消息写入永久性的存储器中。原子性意味着消息只投递一次,并以发送的次序投递。
事务性消息利用 C O M +事务控制特性来提供消息投递的事务特性。这种投递方法的好处是 M S M Q
消息可以参与使用数据库操作的事务。这允许在使用 M S M Q的应用程序中建立复杂的业务规则。
20.3 管理 M S M Q
MSMQ 2.0像 Windows 2000中的许多服务一样,通过 M M C插件来进行管理。 M S M Q插件位于 Computer Mangement插件之下,如图 2 0 - 2所示。
图 20-2 MSMQ插件
M S M Q的 M M C插件完成的任务一般是增加一个新的队列,向 M S M Q服务器增加新的队列非常容易。
20.3.1 增加队列打开 Computer Management插件,然后打开 Message Queuing的下一级列表,如图 2 0 - 3所示。
594计计 ASP 3 高级编程 下载图 20-3 增加队列的窗口下一步,右击 Public Queues文件夹选择 N e w,然后选择 Public Queue。现在 M M C将显示一个提示对话框,询问队列名称和队列是否为事务性的,如图 2 0 - 4所示。
名称一般是一个用户友好的字符串,可用来识别队列 (标签 )。事务性设置决定了队列传送和接收消息时是否需要事务。本章后面将进一步介绍事务。现在只是简单地命名此队列为
A S P Tr a n s并设置为事务性的。
在本章的最后将在 M S M Q的示例中使用这个队列。
M S M Q将创建一个新的名为 A S P Tr a n s的公共队列,如图 2 0 - 5所示。
图 20-5 创建一个公共队列后的窗口第 2 0章 A S P和消息队列服务器 计计 595下载图 20-4 确定队列名称的对话框现在此队列设置为用来接收消息。首先来看一下队列的设置和 M S M Q缺省值。
20.3.2 消息队列的属性为了查看 M S M Q队列的属性,右击左边目录树中或者右边的 M M C插件中的队列,并选择
P r o p e r t i e s。将出现一个 P r o p e r t i e s对话框,此 P r o p e r t i e s对话框包含此消息队列的所有属性设置,
如图 2 0 - 6所示。
图 20-6 设置队列属性的对话框在 P r o p e r t i e s对话框中主要有两部分,G e n e r a l和 S e c u r i t y。 G e n e r a l由以下几部分组成:
Label:描述队列的字符串 (队列名称 )。
Type ID:可用于把多个队列组合在一起的 G U I D。
ID:当队列建立时由 M S M Q服务器分配的 G U I D。
Limit message storage:管理员为防止队列不断扩大而设置的队列限额。
Authenticated:决定队列是否接受客户证书。
Tr a n s a c t i o n a l:指定队列是否需要事务。
Privacy level:确定队列是否使用加密和在消息的哪一部分加密。
Base Priority:确定队列接受的最低优先级。缺省值是 0,设置值可以是从 0到 7之间的整数。
Journal:决定日志是否有效和大小的限制,日志在读取后保留消息而不进行删除。
队列属性的第二部分是 S e c u r i t y。在这里决定谁有权读取、发送和管理队列,如图 2 0 - 7所示。
在 P e r m i s s i o n s区域中有两个项要注意。这个队列对每个用户都提供了 Write Message访问,
而不是 Receive Message访问。这意味着 We b站点的客户可以发送消息而不能读取消息 (除非
We b应用程序需要用户被验证,这是正常的需要 )。权限应该是比较严格的,E v e r y o n e组应被
596计计 ASP 3 高级编程 下载撤消对队列的访问,并且只允许合适的帐户进行访问。
图 20-7 设置队列安全性属性的选项卡一旦队列接收消息,则消息位于主队列文件夹下的 Queue messages文件夹中。 M M C插件将显示队列中的所有消息。在如图 2 0 - 8所示的窗口中,有一条名为 Sample Message的消息。
图 20-8 显示队列消息的窗口
20.3.3 消息属性和队列一样,消息也有一个 P r o p e r t i e s对话框。为了查看消息的属性,右击所要查看的消第 2 0章 A S P和消息队列服务器 计计 597下载息,选择 P r o p e r t i e s。 P r o p e r t i e s对话框将显示四个选项卡,即 G e n e r a l,Q u e u e s,S e n d e r和
B o d y,如图 2 0 - 9所示。
图 20-9 General选项卡
G e n e r a l选项卡包含队列的主要只读信息,L a b e l,I D和 P r i o r i t y通常用于识别消息和其重要性。 C l a s s,S e n t日期,A r r i v e d日期和 Tr a c k e d属性通常用来审计,也可用来调试。
Q u e u e s选项卡如图 2 0 - 1 0所示,显示了具有格式名称 ( G U I D )和普通名称的三个队列。目标
( D e s t i n a t i o n )队列是消息要去的地方。大多数时候,消息在 M M C插件中显示之前就已经在目标队列中了。
响应 ( R e s p o n s e )队列指响应发送者的队列,它用来向发送者发送一个消息,使他们知道消息已经接收到。
最后,管理 ( A d m i n i s t r a t i o n )队列和响应队列的用途一样,但收到消息时会自动地由 M S M Q响应。
图 20-10 Queue选项卡 图 2 0 - 11 Sender选项卡
598计计 ASP 3 高级编程 下载
S e n d e r选项卡如图 2 0 - 11所示,由消息发送者的信息组成,包含了发送者的计算机的
I D ( G U I D )和 P a t h n a m e (计算机名称 )。此选项卡还包括发送消息的用户的登录信息,例如登录名、安全 I D ( S I D ),是否需要客户证书和所用的算法。
为了增加安全性,算法用来对消息加密。
S e n d e r选项卡所包含最后一个消息是安全性 ( S e c u r i t y )信息,描述是否加密和所用的加密算法,如图 2 0 - 11所示。
消息的 P r o p e r t i e s对话框中最后一个选项卡是 B o d y。这个选项卡是最基本的,也是非常有用的。它显示十六进制形式的消息正文。虽然很难读取,但在窗口的右侧可看到消息包含的内容的 A S C I I码,如图 2 0 - 1 2所示,,T.h.i.s.,i.s.
.a.,s.a.m.p.l.e.,m.e.s.s.a.g.e...” 。
20.4 MSMQ对象模型和大多数 B a c k O ff i c e服务一样,M S M Q有一组 COM API(MQOA.DLL),开发人员可以用来编程。 M S M Q的对象模型包括九个对象,如图 2 0 - 1 3所示。
图 20-13 MSMQ的对象模型然而,大多数的 A S P应用程序只需使用以下三个对象:
MSMQQueueInfo对象。
MSMQQueue对象。
MSMQMessage对象。
虽然如此,在开发响应和处理消息的服务器端应用程序时,能够全部理解这些对象是非常重要的。
第 2 0章 A S P和消息队列服务器 计计 599下载图 20-12 Body选项卡
20.4.1 MSMQApplication对象
M S M Q A p p l i c a t i o n对象是使用 M S M Q开发时一般不常用到的一个较小的对象。它有两个方法,M a c h i n e I d O f M a c h i n e N a m e和 R e g i s t e r C e r t i f i c a t e。 M a c h i n e I d O f M a c h i n e N a m e用来查询传递给它的服务器名对应的 G U I D。这个 G U I D可以用来指定服务器。 R e g i s t e r C e r t i f i c a t e在服务器 Active Directory中注册用户证书。
20.4.2 MSMQQuery对象
M S M Q Q u e r y对象用来在各种各样的信息中查找队列。这个对象实际只包括一个方法
L o o k u p Q u e u e,它根据传递给它的查找条件,返回一个 M S M Q Q u e u e I n f o s对象,其中包含
M S M Q Q u e u e I n f o对象的集合,这个方法的句法如下:
前面五个参数指定要查找的可用队列的属性,参数的类型和值如表 2 0 - 1所示。
表 20-1 LookupQueue方法的参数的类型和值参数 (可选 ) 类 型 作 用
Q u e u e G u i d S t r i n g 队列标别符
S e r v i c e Ty p e G u i d S t r i n g 由队列提供的服务类型
L a b e l S t r i n g 队列标签
C r e a t e Ti m e Variant Date 队列建立的时间
M o d i f y Ti m e Variant Date 上次设置队列属性的时间 (包括队列建立时间和上次更新时间 )
也可为每个参数设置布尔运算符 (除了 Q u e u e G u i d以外 ),这些运算符的缺省值是 R e l _ E Q,
意味着查询将返回一个队列集合,其中的属性正好与指定的参数匹配。这些运算符可以通过
L o o k u pQu e u e方法的最后四个参数选择,它们的名称是 R e l加上相应的属性名称,如表 2 0 - 2所示。
表 20-2 关系参数与条件参数的对应关系关系参数 相应的条件参数 关系参数 相应的条件参数
R e l S e r v i c e Ty p e S e r v i c e Ty p e G u i d R e l C r e a t e Ti m e C r e a t e Ti m e
R e l L a b e l L a b e l R e l M o d i f y Ti m e M o d i f y Ti m e
这些参数的可能值及意义如表 2 0 - 3所示。
表 20-3 关系参数的可能值及意义关 系 参 数 意 义 关 系 参 数 意 义
R E L _ E Q 相等 R E L _ L E 小于等于
R E L _ N E Q 不等 R E L _ G E 大于等于
R E L _ LT 少于 R E L _ N O P 忽视这个参数
R E L _ G T 大于为了调用 L o o k u p Q u e u e方法,应该如下编码:
600计计 ASP 3 高级编程 下载这将返回一个队列集合,这些队列的 L a b l e值都是 My Queue。
为了了解标签 ( L a b l e )相同的队列之间的区别,可在每个 M S M Q Q u e u e I n f o对象中查看 p a t h N a m e属性。
20.4.3 MSMQQueueInfos集合
M S M Q Q u e u e I n f o s是一个在 M S M Q Q u e r y对象中从 L o o k u p Q u e u e方法返回的对象。
M S M Q Q u e u e I n f o s对象是一个有限的集合 (缺少 A d d,R e m o v e,C o u n t方法 ),这个集合包含
M S M Q Q u e u e I n f o对象。它只有两个方法,N e x t使指针移到集合中的下一个对象,R e s e t使指针返回到第一个对象。
20.4.4 MSMQQueueInfo对象
M S M Q Q u e u e I n f o对象可以创建、删除和打开位于给定服务器上 M S M Q中的队列。通常使用 M S M Q对象模型做任何工作都从这一个对象开始。
1,打开队列为了使用一个队列,首先必须设置 P a t h N a m e。 P a t h N a m e属性告诉 M S M Q需要什么队列和此队列位于哪台机器上:
上面的代码打开位于本地计算机中名为 M y Q u e u e队列。定义一个本地变量后,就可创建一个 M S M QQ u e u e I n f o对象的实例。下面一行代码用于队列名称和位置的设置:
最后一行利用 O p e n方法来打开队列:
如果所需的队列位于不同的计算机中,用服务器名称来代替,objQueue,Path
Name = "SomeOtherComputer\MyQueue"
打开一个队列时,必须传递两个参数 A c c e s s和 S h a r e M o d e。 A c c e s s决定可对队列做些什么。
这个参数的可能值如下:
MQ_RECEIVE_ACCESS(1):当队列中的消息被读取后即删除。
MQ_SEND_ACCESS(2):用来向队列发送消息。
MQ_PEEK_ACCESS(32):用来在特定的队列中查找消息,而不进行删除。
第 2 0章 A S P和消息队列服务器 计计 601下载打开队列时,也需要设置其他人与队列如何交互,这由 S h a r e M o d e控制。这个参数的设置取决于在第一个参数中指定 A c c e s s方式:
如果已打开队列来用发送或查找,那么这个参数唯一有效的设置是 M Q _ D E N Y _ N O N E,
它允许其他人与队列充分交互。
如果已打开队列用来接收,可允许其他人充分访问队列 ( M Q _ D E N Y _ N O N E ),或者阻止其他人从队列中接收消息 ( M Q _ D E N Y _ R E C E I V E _ S H A R E )。
即使将这个标志设置为这些值之一,其他应用程序仍然可以把消息发送到队列中和在队列中查找消息。
O p e n例程返回 M S M Q Q u e u e对象的一个引用,该对象是消息发送和接收的地方,下面对
M S M Q Q u e u e对象做进一步的讨论。
2,创建队列创建消息队列很像打开队列,先设置 P a t h N a m e再调用 C r e a t e:
这就创建了一个公共队列。要创建个人队列,必须在队列 P a t h N a m e前面加上 P R I VAT E $:
如果想要创建用于事务处理的队列,必须将此方法的第一个参数设置为 Tr u e:
3,删除队列删除队列更简单:
20.4.5 MSMQQueue对象
M S M Q Q u e u e对象代表通过 M S M Q Q u e u e I n f o对象打开的队列。这个对象能够以类似于前移指针的方式在队列中遍历消息。
使用 M S M Q的 A S P应用程序大多数是用它来发送消息的。然而,A S P页经常需要打开队列和显示消息,例如管理页面。当消息被接收和做相应处理时,大多数启用 M S M Q的应用程序需要服务器端的程序来响应消息。这个服务器端程序,像以前描述的一样,常常是一个标准的可执行文件或用 V B或 V C + +开发的服务。
消息可以从队列中被同步或异步检索。异步读取消息允许可执行文件通过使用事件来响应消息。当消息到达所需队列时,M S M Q获得可执行文件中的代码的引用并引发事件。同步
602计计 ASP 3 高级编程 下载读取消息需要可执行文件周期地打开队列并在其中查找消息。这不仅需要占据不必要的系统资源,而且编写程序更为困难。
在 A S P页内,消息只能同步检索,因为 A S P页不能声明服务器端的变量 Wi t h E v e n t s。
关键字 Wi t h E v e n t s是 M S M Q中调用代码并在一个消息到来时引发事件的一种机制。
由于 A S P页中的变量的存在时间相对短暂,这就很有意义。然而,异步检索消息的能力对处理消息的服务器应用程序来说是非常有用的。异步访问 M S M Q消息允许应用程序等待一个表示消息到达队列的事件的发生。这样,在检索消息前服务器端应用程序不必经常占据着资源。
异步检索消息的相关内容可参考 2 0,4,7节 。
在同步检索消息时,代码执行一直等待,直到消息可用或者超时。下面的代码说明如何打开队列并显示消息:
上面的代码从使用 M S M Q Q u e u e对象开始,并且进入 Do While? L o o p循环,一直循环到
M S M Q Q u e u e对象的 P e e k例程返回 N o t h i n g。当这个例程返回 N o t h i n g时,就意味着超时或者队列中没有更多的消息。在本例中,时间期限设置为 1 0 0 0 m s。
在进入 Do loop循环前,必须使用 P e e k C u r r e n t方法将指针设置在队列的第一条消息上。
20.4.6 MSMQMessage对象
M S M Q M e s s a g e对象是 M S M Q的重要部分。它使所有启用 M S M Q的应用程序能够发送和读第 2 0章 A S P和消息队列服务器 计计 603下载取消息。
M S M Q M e s s a g e对象用于保持各种各样的信息。实际上,消息的正文能够保持字符串、字节数组甚至是可永久的 C O M对象的实例。
消息的标签 ( L a b l e )是一个简单描述消息的字符串,与电子邮件的标题相类似。
可以通过打开或查找消息对其进行检索。当打开消息时,一旦读取消息,就会在队列中删除此消息。然而,当查找消息时,在消息到期之前,它会一直存在于队列中。打开和查找消息,可在 M S M Q Q u e u e对象中通过 O p e n和 P e e k例程执行,它们将返回消息的一个引用。
下列的代码表明怎样打开消息和显示消息的正文和标签:
以上的示例是从打开队列开始的,然后在 1 0 0 m s的时间内调用 R e c e i v e例程在队列内查找消息。时间期限用来告诉 M S M Q什么时候停止等待消息。
当时间期限设置得很短时,不是等待接收消息而是检查已存在的消息。
为了查看是否有消息,检测 R e c e i v e函数返回的 M S M Q M e s s a g e对象是否为 N o t h i n g。如果
R e c e i v e返回一个有效消息,代码将显示 L a b e l和 B o d y属性。
发送消息是 A S P中的 M S M Q完成的最普通的任务。为了传送消息,队列以发送访问方式
( M Q _ S E N D _ A C C E S S )打开,并且在调用 M S M Q M e s s a g e对象中的 S e n d例程前准备好消息:
604计计 ASP 3 高级编程 下载上面的代码的开始部分与其他的示例代码类似,打开一个队列,这个队列是以发送访问方式打开的。下一步,通过创建 MSMQMessage 对象的实例和设置 L a b e l和 B o d y属性完成消息的建立。最后,通过调用消息的 S e n d方法发送消息,并将目标队列的引用作为一个参数传递给它。
20.4.7 MSMQEvent对象对于用 V B和 V C + +语言创建的服务器端应用程序来说,M S M Q E v e n t对象是非常有用的。
因为这个对象为 M S M Q提供调用代码和在队列接收到消息时引发事件的一个机制 (异步读取 )。 M S M Q E v e n t对象是比较小的对象,实际上它没有属性或方法,只包括两个事件,如表
2 0 - 4所示。
表 20-4 MSMQEvent对象的事件及说明事 件 说 明
A r r i v e d 用来从队列中异步检索消息,每次指定的队列接收消息,在代码中激活这个事件
A r r i v e d E r r o r 用来从队列中异步检索消息,如果在试图监听指定队列中的消息时发生错误的话,
在代码中引发这个事件本章后面将介绍怎样在服务器端可执行文件中使用这些事件。
20.4.8 MSMQTr a n s a c t i o n对象
M S M Q Tr a n s a c t i o n对象用来告知 M S M Q终止或提交一个事务,它由 M S M Q Tr a n s a c t i o n
D i s p e n s e r或 M S M Q C o o r d i n a t e n Tr a n s a c t i o n D i s p e n s e r对象通过使用 A b o r t或 C o m m i t方法来进行。
M S M Q Tr a n s a c t i o n对象的实例不能用 N e w关键字或 C r e a t e O b j e c t函数创建。它是通过使用 M S M Q Tr a n s a c t i o n D i s p e n s e r和 M S M Q C o o r d i n a t e d Tr a n s a c t i o n D i s p e n s e r对象中的 B e g i n Tr a n s a c t i o n方法创建的。
20.4.9 MSMQTr a n s a c t i o n D i s p e n s e r对象
M S M Q Tr a n s a c t i o n D i s p e n s e r对象提供了在一个事务中将多个消息打包发送或接收 M S M Q
第 2 0章 A S P和消息队列服务器 计计 605下载中多个队列中的消息的能力。对内部的 M S M Q事务,使用这个对象非常有用,但不能包括
SQL Server数据库更新或添加等其他任何事情。当需要事务时,只能包括在 M S M Q中使用
M S M Q Tr a n s a c t i o n D i s p e n s e r对象事务的操作。由于不必处理分布式事务协调器 ( D T C )带来的额外开销,所以它比 M S M Q C o o r d i n a t e d Transaction Dispenser事务快。
20.4.10 MSMQCoordinatedTr a n s a c t i o n D i s p e n s e r对象
M S M Q C o o r d i n a t e d Tr a n s a c t i o n D i s p e n s e r对象完成与 M S M Q Tr a n s a c t i o n D i s p e n s e r对象相似的功能。然而这个对象提供了使用 Microsoft DTC强大功能的方式,因此能够在事务中协调任何 D T C支持的数据源。
2 0,4,11 访问 M S M Q的其他方式
COM API中有另外一个提供给 C和 C + +开发人员使用的 A P I。它为有经验的 C / C + +开发人员提供了能够获取端口通信和基本指针的一种方式。
在 A P I层中获得 M S M Q功能超出了本书的范围。有关方面的信息可参考微软的 M S D N站点
( w w w,m s d n,M i c r o s o f t,c o m )或 M S M Q运行期的帮助文件。
20.5 用于 M S M Q的 MS DTC事务通过使用 D T C,事务不仅能完成从队列中读写消息,还可包含其他任何支持 D T C的服务。
这使开发人员能够编写方法来修改像 SQL Server(6.5或 7,0 )这样的数据库中的数据,并在单个事务中从一个队列中发送或读取消息。
包括多个 D T C相容服务的事务也可通过 C O M +放入一个事务中,这使开发人员可以将代码封装到 COM DLL中,并将其置于 C O M +控制之下。
虽然 M S M Q的 M S M Q C o o r d i n a t e d Tr a n s a c t i o n D i s p e n s e r对象提供使用 D T C的功能的途径,
开发人员也可通过 C O M +使用事务来完成相同工作。
C O M +的运行期与 M S M Q的 M S M Q C o o r d i n a t e d Tr a n s a c t i o n D i s p e n s e r对象提供的能力相同。
实际上幕后也是相同的。然而,通过 C O M +开发事务具有更大的灵活性和更多的功能。
20.6 高级 M S M Q消息到目前为止,代码示例使用的消息正文仅包括简单字符串值。下面看一下更有趣的情况。
M S M QMe s s a g e对象的 B o d y属性实际上定义为接收 Va r i a n t数据类型的值。这就是说,消息的正文可包括字符串、日期、货币、数字、字节数组或甚至是实现 (支持 ) I D i s p a t c h和
I P e r s i s t ( I P e r s i s t S t r e a m或 I P e r s i s t S t o r a g e )接口的 C O M对象。
这说明在 M S M Q消息中发送字符串、日期和数组是非常容易的,只是简单地把消息的正文设置为变量即可:
606计计 ASP 3 高级编程 下载这是非常简单的。现在研究在消息中保存的 C O M对象实例。
消息中的 C O M对象使用 VB 6,开发人员可以开发一些用 V C + +需要很长时间才能开发的程序。可以通过
I P e r s i s t接口产生出能够保持的 C O M对象。尽管这是由 V B运行期在幕后完成的,但仍为使用 V B
的开发人员创建业务逻辑提供了新的途径。
I P e r s i s t接口提供一个 M S M Q可以查找和调用的一般接口,可以使对象串行化自身。当 V B对象对自己串行化时,它会取出内部信息 (变量和相应的值 )并将其放入 P r o p e r t y b a g。然后 V B运行期从 P r o p e r t y b a g中读取数据并通过 I P e r s i s t接口将这些数据串行化。这个串行化的二进制数据实际存放在 M S M Q消息的正文中。
为了创建支持 I P e r s i s t接口的组件,设置类属性 P e r s i s t a b l e为 1 - P e r s i s t a b l e,如图 2 0 - 1 4所示。
一旦设置了 P e r s i s t a b l e标志,三个事件会添加到 C l a s s事件中:
InitProperties。
ReadProperties。
Wr i t e P r o p e r t i e s。
I n i t P r o p e r t i e s事件用来在 R e a d P r o p e r t i e s事件引发前设置任何缺省值或设置任何其他东西。
R e a d P r o p e r t i e s和 Wr i t e P r o p e r t i e s事件非常简单。它们提供对 P r o p e r t y B a g读写状态 (内部数据 )的事件,这个 P r o p e r t y B a g将存放在 M S M Q M e s s a g e对象中。
下面的代码展示了类是如何支持持续特性的,注意事件处理器 C l a s s _ R e a d P r o p e r t i e s和
C l a s s _ Wr i t e P r o p e r t i e s。当 M S M Q查找 I P e r s i s t接口时,V B运行期将要调用这些事件。注意,
V B类并不真的支持 I P e r s i s t接口。 V B运行期对开发人员隐藏这一事实,作为类事件来传递这个调用:
第 2 0章 A S P和消息队列服务器 计计 607下载图 20-14 类属性设置窗口现在,已经创建了 C O M组件,下面调用这个类,并把内部状态 ( P r o p e r t y B a g中的
m s t r F i r s t N a m e和 m s t r L a s t N a m e )放在消息的正文中。 V B中此代码比较容易。
由创建一个类实例开始并设置 F i r s t N a m e和 L a s t N a m e属性。下一步为发送访问打开队列。
最后一步是通过创建 M S M Q M e s s a g e对象的实例,设置 L a b e l为一个字符串,设置 B o d y的值为已定义的类实例。所有这些工作对对象使用者隐藏:
608计计 ASP 3 高级编程 下载看上去这些代码 (对于 V B S c r i p t稍做改变 )可用于 A S P页面中。但事实上不是这样的。所有代码都会正常工作,但将对象放在消息正文中的那一行代码将会出错。导致的错误描述为:
,Cannot save an uninitialized class,You must use the global InitProperties method to
initialize the class,or load the class from a PropertyBag before trying save it.”
(“不能保存一个未初始化的类。必须使用全局 I n i t P r o p e r t i e s方法来初始化这个类,或在保存前从 P r o p e r t y B a g中装载这个类。,)
这是一个非常讨厌的错误 (或限制 ),即使将保存消息正文到组件的逻辑移到组件本身,
仍然存在相同的问题。因此如果想在队列中保持 C O M对象,那么必须创建一个组件来完成。
20.7 COM+队列化组件考虑 C O M +的附加特性,C O M组件现在可以配置为作为队列化组件运行。
队列化组件允许 C O M对象的用户 ( c o n s u m e r )通过 M S M Q与对象进行通信,且不需要修改 C O M对象或用户的任何代码。
队列化组件使用了四个代码块,分别称为
r e c o r d e r,q u e u e,l i s t e n e r和 p l a y e r,允许客户与队列化 C O M对象通信。 r e c o r d e r记录了客户与对象的交互,将信息绑定到 M S M Q消息中,并发送到 M S M Q中的队列。这个服务器上的 l i s t e n e r
响应来自客户的 r e c o r d e r的消息,并把消息发送到 p l a y e r,然后 p l a y e r读取此消息并调用客户使用的方法。它们之间的关系如图 2 0 - 1 5所示。
第 2 0章 A S P和消息队列服务器 计计 609下载图 20-15 四个代码块与客户及服务器之间的关系图 20-16 设置队列化组件客户服务器
player
listener
queuerecorder
队列化组件非常有用,但它们也有局限性。由于客户不能与 C O M对象直接交互,不能使用通过引用传递的参数或有返回值的函数。但是,队列化组件对于调用 C O M对象的子程序是非常有用的。
要作为队列化组件来设置 C O M对象,只需在 COM+ MMC插件中简单看一下包含此 C O M
对象的包的属性,选择 Q u e u i n g选项卡,选择 Q u e u e d和 L i s t e n选项,如图 2 0 - 1 6所示。
关于队列化组件特点的信息可参考 M i c r o s o r f t的 M S D N网站,网址为 w w w,m s d n,
m i c r o s o f t,c o m或 M S M Q运行期的帮助文件。
20.8 扩展联机订货的示例我们已经看到了如何使用 M S M Q的相关内容,下面将扩展前一章中的示例程序,让它利用 M S M Q I作。这里将以两种不同的方式来示范 M S M Q的使用。
首先,修改订单放置组件,将订单发送到队列中,而不是直接更新数据库。
其次,创建一个服务器端可执行程序,这个程序等待和处理发到队列的消息,把订单实际存放在数据库中。
首先我们需要在组件中添加相应的一些代码。
20.8.1 在组件中添加 M S M Q
我们将使用本章前面创建的 A S P Tr a n s队列。你现在应该认识到为什么将其设置为事务性的。因为我们想使其与这个组件包含在同一事务中。
打开 A S P Tr a n s项目,在加入任何新代码前,必须加入对 MSMQ 2.0类型库的引用,如图
2 0 - 1 7所示。
图 20-17 添加对 MSMQ 2.0类型库的引用下一步,加入代码把消息发送到 M S M Q中的 A S P Tr a n s队列里。我们将改变这个程序的功能,以使这个订单放在队列中而不是立刻发生作用。
610计计 ASP 3 高级编程 下载把这个代码放在 O r d e r组件的 P l a c e O r d e r子程序中,其中没有我们没见过的代码:
第 2 0章 A S P和消息队列服务器 计计 611下载现在如果重新编译并加入一个新的订单,会发现订单已存放在 A S P Tr a n s队列中,如图 2 0 -
1 8所示。
图 20-18 添加订单后的 A S P Tr a n s队列然而,这个订单任务仅完成了一半,需要将订单从队列取出并放入数据库中。
20.8.2 处理队列化订单我们将使用 M S M Q E v e n t对象“监听”订单被放入队列这一事件,完成这个工作的是一个非常简单的服务器端的标准可执行程序。当消息放置好后,仍使原来的 I N S E RT语句存储订单。
创建一个新的 Visual Basic Standard EXE项目,并增加对 MSMQ 2.0 Object Library和
ActiveX Data Objects 2.5 Library的引用现在,在 V B项目的窗体中加入一个列表框。下一步,进入代码窗口并加入下列的代码:
612计计 ASP 3 高级编程 下载上面的程序是由 F o r m _ L o a d事件开始的,然后打开 A S P Tr a n s队列。下一步,代码设置
m o b j M S M Q E v e n t对象并把它链接到队列中。这由调用 M S M Q Q u e u e对象的 E n a b l e N o t i f i c a t i o n方法来完成。一旦 M S M Q E u e n t对象链接上了,剩下的事情就是处理 A r r i v e d和 A r r i n e d E r r o r事件。
每当在队列中接收到新的消息时才引发 A r r i v e d事件,这时把消息正文中的订单细节取出来,并把它放到的数据库中。
一旦接收了消息,必须再次调用 E n a b l e N o t i f i c a t i o n方法使 M S M Q在下一个消息到来时通第 2 0章 A S P和消息队列服务器 计计 613下载知代码。如果代码调用 E n a b l e N o t i f i c a t i o n失败,将永远不会见到下一个消息。
现在可以试验代码了。从编译可执行文件或在 V B开发环境中运行代码开始。注意当窗体的 L o a d事件引发时,队列为接收访问而打开,并且 M S M Q E u e n t对象会用来查找消息。
如果在队列中存在任何消息,V B应用程序会立刻响应,如图 2 0 - 1 9所示。
现在回到浏览器,再加入一些新的订单。注意,V B应用程序已经处理了它们。现在停止执行 V B应用程序并加入更多的订单。直到 V B应用程序重新启动之前,这些订单作为队列中的消息在等待着。 V B应用程序开始执行,这时消息 (订单 )将被处理并且队列重新变空。
20.9 小结
M S M Q提供了一个中间层。使用这个中间层,
应用程序之间可以在松散配合的情况下以异步方式互相交流。在一个设计较好的 C O M对象模型中,各种各样的程序语言都可以使用 M S M Q。
本 章 讨 论 了 微 软 消 息 队 列 服 务 器 系 统,
M S M Q允许应用程序之间异步通信,即使这些应用程序不在同一时间内运行或应用程序之间的连接是不可靠的。理解它的最简单的方式是,
把它当作供应用程序使用的电子邮件。对一个系统的互连网络来说,M S M Q系统允许消息在网络之间来回传送。系统指出了消息传输的目的地,并确证消息到达。 M S M Q可从 A S P或者
A S P组件通过 C O M接口直接起作用。
本章主要讨论了以下几个方面的问题:
消息排队的定义。
MSMQ及其结构。
MSMQ能做什么。
如何管理 M S M Q。
如何使用 C O M对象与 M S M Q交互。
创建与 M S M Q交互的组件。
在 A S P应用程序中使用 M S M Q组件。
MSMQ消息的异步响应。
如何将 M S M Q合并到事务中。
614计计 ASP 3 高级编程 下载图 20-19 响应窗体