针对 Microsoft Visual Basic 程序员的 COM+ 概述

针对 Microsoft Visual Basic 程序员的 COM+ 概述

http://msdn.microsoft.com/library/chs/default.asp?url=/library/CHS/dntaloc/html/complus4vb.asp

Ted Pattison
开发顾问

2000 年 2 月

摘要:COM+ 和 Windows 2000 Server 提供了一个用于生成分布式应用程序的复杂结构。本文识别和阐释生成 Windows 2000 Server的大型信息系统需要掌握的关键技术和服务。(共 22 页打印页)

改编自 Programming Distributed Applications with COM+ and Microsoft Visual Basic 6.0(第二版 Microsoft Press ISBN# 1-57231-961-5)的第一章

啊,一个千年刚结束,另一个千年又开始了。作为专业开发人员,千年的更替对您的生活究竟产生了多大影响?的确,当所有的指针都指向零点时,这里或那里出现了一些停顿。少数过时的系统不得不退出历史舞台。但我们的行业整体上并没有经历媒体所预测的那种世界末日的局面。这对我们中那些基于最近十年内创建的操作系统和开发工具生成应用程序的人来说尤其如此。当您回顾所有这一切时,您会发现这相当滑稽。公司信息系统要毁灭的谣言显然言过其实。

此外,难道新闻界真的了解我们行业内正在发生的事情吗?它是一个世纪虫,而不是千年虫,他们把这个事实弄错了。此问题产生的根源在于日期使用的是两个字符,而不是四个字符。如果人类在 100 年前就拥有目前这样的技术,那我们在 1899 年的新年前夕也要面对所有这些问题。然而,“千年虫”似乎要耸人听闻得多,因此售出了更多的报纸和杂志。

是否记得早在几年前新闻界就预测一切事物都要用 Java 重新编写,其中包括美国宪法和宪章?现在,围绕 Java 的炒作已经平息,我们看清了 Java 的本质,它是一种年轻而有前途的语言,既有优点,也有缺点。它并没有如暴风雨般迅速占领整个行业。它是一种在某些情况下合用但在某些情况下却不合用的语言。

现在每个人都认为 XML 是一种万能的技术。我知道,随着 XML 日趋成熟,我们会发现它的更多用途。它将解决许多非常困难和实际的问题。但正如许多人所指出的那样,XML 永远不会代替 COM、Corba 和 Java 这样的技术。从长远看,保留所有这些新技术是重要的。在您不得不在几个月内开发出某个应用程序的当口,如果有某项技术可能解决您在未来几年中遇到的问题,因此就对此技术过度沉迷是不健康的。

为何应使用 COM+?

我将假定您至少在考虑使用 COM+ 来生成分布式应用程序。许多公司都在使用 COM+ 和 Microsoft Windows®2000,因为它们提供了健壮的开发平台。此平台由若干核心技术组成,这些技术提供了构造多层业务应用程序的基本生成块。毕竟,基础平台带给表的东西越多,需要编写和调试的代码就越少。

我大概不需要说服您相信,与 20 世纪 80 年末和 90 年代初风行一时的双层应用程序相比,多层应用程序提供了许多优点。您的公司或许已决定放弃双层方法,而接受了多层策略。不过,在本文开始时,我希望用一点时间来回顾一下双层应用程序的最重要的问题,并解释多层应用程序是如何就其中许多问题提供解决方案的。我还将讨论多层开发为什么会引起一些新问题和额外的复杂性。

Microsoft 开发 COM+ 的目的之一是为公司提供多层应用程序的优点,同时尽可能多地隐藏内在复杂性。在过去的十年中,Microsoft 已在创建分布式应用程序的这种结构方面取得了许多进步。

COM 的第一个版本于 1993 年交付。从那时起,COM 已从年轻而复杂的技术成长为 Microsoft 多层策略的核心。本文将对 COM 最重要的事件进行考察。其间,我还将尽力对这些年来由那些营销人员创造的所有缩写词进行详细的说明。您或许已经听说过 OLE、DCOM、ActiveX® 和 MTS。COM+ 和 DNA 是此列表中最近增加的两项。但是您曾经在鸡尾酒会上设法向其他人解释过这些术语之间的差异吗?这并不容易,是吗?它们对不同的人有不同的含义。

本文的最后将从更高的层面对集成到 COM+ 平台的分布式服务进行概述。任何重要的多层应用程序都需要诸如事务支持、集成安全性、Web 服务器、消息处理和发送事件通知等功能。本文将识别上述每种 COM+ 服务适用的环境,使您在整体上对 COM+ 有一个正确评价,并为您指明方向。

从双层系统到多层系统

使用 COM+ 的最佳理由之一是将公司的信息系统从双层结构转换为多层结构。这种转换要求设计和创建业务对象的中间层。业务对象通常位于客户端应用程序和数据库服务器之间。COM+ 充当这些系统类型的平台。

双层系统在业内已得到广泛的使用,因此,与它相关的问题众所周知。让我们回顾一下传统双层结构的主要缺点,例如图 1 中所示的缺点。

图 1:典型的双层应用程序要求每个用户具有与数据库服务器的单独连接,并且用户的计算机必须有适合特定数据库管理系统 (DBMS) 的驱动程序。

  • 用户界面代码与业务逻辑和数据访问代码混合在一起,这使得难以在多个客户端应用程序间重用业务逻辑和数据访问代码。而且,更改业务逻辑或数据库通常要求重新生成和重新发布客户端应用程序。
  • 每个客户端应用程序均具有业务逻辑和数据访问代码,并在单独的进程中运行,因此您无法共享进程特定的资源,如线程和内存。在双层系统中还无法共享数据库连接,因为每位用户需要单独连接到数据库服务器。对于连接到大型机的客户端应用程序来说同样如此。由于不能在一组用户之间有效地共享资源,从而限制了系统的总吞吐量和可缩放性。
  • 每台客户端计算机需要一个或多个专有驱动程序,以便可以与数据库服务器或主框架应用程序进行交谈,这使得维护和配置台式计算机的开销更大。系统管理员必须在每台计算机上安装并维护一套驱动程序,以提供对开放式数据库连接 (ODBC) 数据库等的访问。如果您需要交换出后端数据库(例如要从 Sybase 转到 Oracle),管理员必须访问每个桌面。这样做的开销很大。
  • 客户端应用程序在访问来自多个数据源的数据时相当困难。在企业环境中,将关键的业务数据散布在许多不同的系统之间的做法并不少见,如图 2 所示。当应用程序需要使用散布在多台计算机上的数据来运行业务事务时,情况就会变得相当棘手。当数据同时存储为各种不同的格式时,情况则变得异常困难。

    图 2:当公司有多个客户端应用程序或多个数据库服务器时,双层策略无法正常运行。

  • 客户端应用程序通常需要在数据库服务器或主框架应用程序所在的同一个局域网 (LAN) 上运行,这使得不可能生成跨多个地理位置的分布式应用程序。许多公司的雇员遍布全球,他们中有很多人需要为永远无法集成到受控环境(如企业 LAN)中的客户和供应商创建系统。
  • 用户被限制在特定的平台上。例如,双层系统通常要求每个人运行相同的操作系统,如 32 位版本的 Windows。在任何计算机都可以与任何其他计算机相连的世界中,这种限制变得越来越无法接受。
  • 当计算机断开连接时,比如当数据库服务器脱机以进行维护时,或笔记本电脑用户在飞机上或客户地点工作期间从网络断开连接时,双层系统便停止运行。如果系统每当各计算机无法直接连接到另一台计算机时都经历停机,系统的可用性将受到严重限制。

拆分表示层

随着计算机科学中的许多其他问题通过添加一个间接寻址层得以解决,双层结构的问题也可以得到解决。您可以通过引入一组业务对象将客户端应用程序从业务逻辑和数据访问代码中分离出来,如图 3 所示。包含用户界面代码的客户端应用程序通常称为表示层。除非另外说明,本文中的术语客户端应用程序是指包含用户界面的元素和代码的表示层应用程序

图 3:在中间层引入一组业务对象可消除客户端应用程序和数据库服务器之间的昂贵依赖项。

业务对象允许您集中逻辑,并在多个客户端应用程序间重用它。在基于 Windows 2000 和 Windows NT® 的网络中,可以使用 COM 作为基础来部署这些业务对象。COM 还可以提供客户端应用程序和中间层对象之间的远程通讯基础。

COM 的最大卖点之一是:它允许中间层程序员更新其业务对象中的代码,而无需重新编译或重新分发客户端应用程序。在组件已经投产后,更改业务逻辑或数据访问代码相当简单,因为客户端应用程序不受业务对象实现细节的保护。

应用程序数据可以更改存储格式,并且可以使新的数据库服务器联机,而不用经历过度的痛苦和挫折。可以经常对单个 Visual Basic® 动态链接库 (DLL) 做必要的修改。在成品服务器上的中间层很容易重新编译和替换 DLL。客户端应用程序在成品中保持不变。

在如图 3 所示的典型多层应用程序中,一组中间层对象代表许多不同的用户运行。然而,所有这些对象通常在 Windows 2000 服务器上的单个进程内运行。这使得可以共享进程特定的资源,如线程、内存和多个用户间的数据库连接。另外,运行客户端应用程序的计算机不需要数据库驱动程序,与它们在双层模型中一样。

逻辑层与物理部署的比较

多层开发过程中出现的首要问题之一是应将每层部署在何处。图 4 显示了两个可能的方案。层数不一定指示所涉及的计算机数。在小型部署中,业务代码和数据库服务器可以在同一台计算机上运行。在大型系统中,数据可以保存在一个或多个专用数据库服务器中,而业务对象在单独的主机上运行。

某些物理部署方案设置起来更容易,开销也更低。某些则提供更高级别的可缩放性、可靠性和容错。当人们谈及多层系统时,他们指的是若干不同的逻辑层。在系统投入生产后,物理部署可以改变并且很轻易更改。COM 的最大优点之一是允许在不修改或重新编译任何应用程序代码的情况下对物理部署进行更改。

图 4:业务对象和数据访问层之间的映射开始时可以很简单,然后在不影响客户端应用程序的情况下变得更复杂。

一些人使用术语三层N 层而不是多层。这些术语的含义大部分都相同,即系统有三层或更多的层。图 5 显示了一组更复杂的物理层。在多层模型中,业务和数据访问层的复杂性可以是任意的。该模型的最大优点是客户端应用程序只知道业务对象的可见层。隐藏在业务对象后面的所有其他复杂性都与它们无关。因此,多层系统的主要设计目的是向组成表示层的客户端应用程序尽可能多地隐藏此复杂性。

COM 的另一个强大功能是允许客户端应用程序从网络上创建和使用对象。在后台,COM 使用称为远程过程调用 (RPC) 的协议跨进程和主机边界执行方法调用。RPC 是若干重要协议中的第一个,在用 COM+ 设计分布式应用程序之前应了解该协议。

图 5:多层结构的最大优点之一是向客户端应用程序隐藏不断演变着的公司 IT 结构的复杂性。

如果您有一组用户,他们都运行 COM 识别的操作系统(如 Windows 2000、Windows NT 和 Windows 98),则可以创建如图 5 中显示的多层应用程序。运行客户端应用程序的计算机依靠 COM 在 LAN 上建立与业务对象的连接。客户端应用程序从网络上创建了业务对象后,它就可以使用这些业务对象来运行事务和检索信息。

虽然该方法适合某些应用程序,但对另一些应用程序并不适合。这种开发形式通常要求每位用户均运行 32 位版本的 Windows。当您的所有客户端应用程序和业务对象都在同一个 LAN 中运行时,该方法同样可靠得多。然而,您可能想到达尚未登录到本地网络或运行其他操作系统(如 Macintosh、OS2 或 UNIX)的用户。通过使用基于 Web 的开发策略,您可以到达广泛得多的听众。

基于 Web 的应用程序

Internet 和基于 Web 的应用程序的普及刺激了业界采用多层结构。在基于 Web 的系统中,客户端应用程序在浏览器中运行。浏览器使用称为超文本传输协议 (HTTP) 的轻量协议将请求提交给 Web 服务器。基于 Web 的应用程序中的表示层是用超文本标记语言 (HTML) 构造的。

典型 Web 应用程序的工作机制其实相当简单。客户端向 Web 服务器提交请求,Web 服务器通过处理请求并将基于 HTML 的页发送回用户来响应请求。使用 HTTP 和 HTML 的重要意义是每个主要平台都支持它们。您的应用程序可能可以到达 Internet 上的任何用户。

注意,Web 服务器是客户端进入中间层的入口点,如图 6 所示。当客户端提交 HTTP 请求时,中间层应用程序必须加载和运行业务对象才能实现多层开发的优点。虽然组成表示层的代码和 HTML 页位于服务器上时,仍然可以分开用户界面元素、业务逻辑关系和数据访问代码。可以创建一套业务组件,并在基于 LAN 的客户端之间和基于 Web 的客户端之间共享这套组件。

如果正确设计基于 Web 的应用程序,就可以实现到目前为止所讨论的多层开发的所有优点。可以在一大组用户之间共享进程特定的资源,如线程、内存和数据库连接。可以通过针对多个数据源检索数据和运行事务来响应一个 HTTP 请求。此外,基于 Web 的开发显著减少或消除了客户端的配置问题。

图 6:基于 Web 的开发使得可以通过 Internet 到达运行各种浏览器和操作系统的客户端。

在设计基于 Web 的应用程序时,必须决定打算支持的浏览器和平台。如果主要目标是到达最广泛的可能听众,则应选择纯 HTML 解决方案。如果想生成更复杂的用户界面,通常需要将用户限制在某个特定的浏览器上或一组流行的浏览器上。

例如,最新版本的 Microsoft Internet Explorer 和 Netscape Navigator 支持动态 HTML (DHTML) 和客户端 JavaScript 等功能。但是,如果您使用了这些功能,使用早期版本浏览器的用户在使用您的应用程序时将遇到麻烦。通常必须决定是支持更多的用户重要,还是创建拥有更精美用户界面的应用程序重要。这是一个在设计阶段初期就应做出的艰难决定。

消息处理的需要

在多层应用程序的初始设计阶段应解决一个决定性的问题。分布式应用程序中使用的许多协议(如 RPC 和 HTTP)是同步的。这意味着在服务器计算机执行请求的任务时,客户端计算机上运行的应用程序必须在每个请求期间耐心等待。另外,如果服务器的请求备份日志巨大,客户端可能会被迫等待一段无法接受的时间。

另外请注意,使用同步协议生成的应用程序依赖于处理同时联机的请求所涉及的每台计算机。服务器必须联机,客户端才能发出请求;而客户端必须联机并发出请求,才能利用服务器必须提供的可用处理循环。如果服务器脱机,客户端将无法发出请求。客户端脱机时,服务器呆在那儿什么也不干。从本质上讲,每个人都必须同时联机,整个系统才能运行。

多个应用程序常常需要以异步和断开连接的方式进行通讯。消息处理是一种在两个或更多的应用程序之间建立异步通讯的机制。客户端应用程序通过网络将异步消息发送给队列。每条消息通常表示一个客户端请求或某种类型的通知。服务器应用程序监视这些队列,并在消息到达时或稍后处理消息。消息和队列只是在发出请求的应用程序和处理请求的应用程序之间提供了一个间接寻址层。

建立在消息处理协议上的应用程序可以在各计算机脱机时继续运行。然而,创建可靠的消息处理结构,通过它可以将每条消息与所需的传递保证一起路由到各自的目标队列,这并不是一件价值不高的工作。消息处理结构必须提供一组广泛的子系统,以在计算机脱机时透明地存储消息,并在稍后可以建立连接时将消息转发到它们的目的地。

大多数公司都不愿意投入时间和金钱来编写和调试自定义消息处理结构的代码。幸运的是,有若干商用消息处理产品,如 IBM 的 MQSeries 和 Microsoft 的 MSMQ Server,它们提供了异步和无连接通讯的优点。这便消除了自己创建自定义消息处理结构的必要。

Microsoft 多层平台的演变

正如我在前面提到的,Windows 2000 和 COM+ 提供了一个用于生成多层应用程序的平台。但是,组成该平台的许多核心技术已存在了很长时间。了解该平台的各部分这些年来是如何演变的很重要。

早在 90 年代初,Microsoft 的权威人士就认识到在大型多层系统的开发中,有很多不必要的钱都花在了结构上。他们认识到:公司希望花更多的时间编写自定义业务逻辑,而只用较少的时间编写复杂的代码来解决像共享中间层资源和监视分布式事务这样的问题。Microsoft 的整个多层策略基于这样的假设:公司宁愿让其他人创建分布式应用程序框架的一般但关键的部分。

随着 Microsoft 多层策略的发展,给策略赋予名称和一致标识的尝试导致了一些混淆。营销人员似乎每隔一两年就会为已存在一段时间的技术设计出全新的名称和缩写词。例如,Microsoft 平台的最新名称是 Windows 分布式 interNet 应用程序 (DNA) 结构。从市场的角度看,Microsoft 需要全新的名称以与类似的技术(如 Corba 和 Enterprise Java Beans)竞争。从开发人员的角度看,这些名称改动并无太大意义。尽量不要让它们干扰您。这里并没有人在重新从头做,他们只是开始将它称作循环移动设备 (CLD)

本文中讨论的每个主题均在巨大的 Windows DNA 伞下。我甚至不会尝试介绍所有与 DNA 有关的技术,如 DHTML 和客户端脚本撰写。术语 DNA 包含 Microsoft 为帮助公司生成多层应用程序曾经采取的所有动作。许多程序员完全避免使用此术语,因为他们不希望被销售部门的人员或非技术管理人员搞糊涂。如果您确实希望在开发周期中三句话不离本行,必须了解组成该平台的所有重要技术。

基础:COM

Microsoft 的多层策略建立在称为组件对象模型 (COM) 的核心技术之上。虽然 COM 提供许多优点,但它是一种复杂的技术,涉及若干具有挑战性的概念和大量的低级细节问题。其中的一些概念和许多细节对于理解如何正确生成 COM+ 应用程序的中间层组件至关重要。与 COM 关联的许多其他细节已不再相关,或者只对生成表示层应用程序的程序员重要。您无需关心对象链接和嵌入 (OLE)、ActiveX 控件、连接点(如 Visual Basic 事件)这类与 COM 有关的主题,所以本文省略了这些主题。本文专注于 COM 的细节,这些信息对于生成中间层的非可视组件的程序员来说非常重要。

术语 COM 对许多人有许多不同的含义。一方面,它是编写在基于组件的系统中运行的可重用软件的规范。另一方面,它是允许客户端和对象跨进程和计算机边界进行通讯的复杂结构。很多对 COM 已心领神会的开发人员将它看成一种新的编程样式和一套规范,它们是在以 Microsoft 为中心的环境中工作所必需的。

COM 编程模型基于二进制组件中的类代码分布。这意味着遵从 COM 的软件(组件)可以在源代码上没有任何依赖项的情况下重用。开发人员可以将其作品以二进制文件的形式交付,而不必公布其专用算法。重用二进制格式的代码还可以消除许多编译时问题,当使用基于源代码重用的开发样式对应用程序进行汇编时会出现这些问题。

在基于组件的技术(如 COM)出现之前,生成大型应用程序的方法是在一个批处理作业中,将数百个甚至数千个源文件发送到编译器,以生成一个可执行文件。这种开发样式依赖于整体式应用程序,需要巨大的可执行文件和很长的生成时间。而且,如果要利用一行源代码的修改,就必须重新生成整个应用程序。这使得协调共同开发大型应用程序的编程小组愈发困难。乐观地讲,维护和增强整体式应用程序是笨拙的。

基于组件的开发解决了许多与整体式应用程序有关的问题。它允许开发小组交付二进制文件而不是源代码。二进制组件可以独立更新和现场替换,这使得在已投产后维护和扩展应用程序容易得多。大多数人都同意在开发大型信息系统中绝对需要使用 COM 或其他一些基于组件的技术。

COM 基于面向对象的编程 (OOP)。这意味着 COM 是关于与对象通讯的客户端的。COM 利用 OOP 范例获得比使用其他二进制重用模型可能获得的级别更高的重用和可维护性级别。COM 客户端和 COM 类一般位于不同的二进制文件中。COM 定义一个使客户端能够在运行时创建对象和绑定到对象的结构。

基于面向对象的组件重用的平台必须提供动态的类加载机制。这是 Java 与 COM 相似的一个方面。在运行时,客户端通过命名一个特定的类来创建对象,而该类已编译成一个单独的二进制组件。系统提供的代理程序跟踪该类的代码,装载它,并以客户端的名义创建对象。

二进制重用使合并对应用程序的小改动容易得多。例如,可以修复 DLL 的小错误或修改 DLL 的性能。然后可以现场重新编译和替换 DLL,而不会对任何使用它的客户端应用程序造成负面影响。基于源代码重用的系统一般必须重新编译整个应用程序中的每行代码,这使软件的维护和扩展既麻烦又昂贵。

二进制重用原则允许使用与语言无关的组件构造基于 COM 的应用程序。当多个小组为一个系统生成组件时,每个小组可以独立选择自己的编程语言。现在,支持 COM 的语言包括 C++、Visual Basic、Java、Delphi,甚至还有 COBOL。每个小组可以选择与其编程专业技术相匹配,并提供最佳的灵活性、性能和工作效率组合的语言。

例如,如果一个小组需要低级别的系统代码,出于灵活性考虑,它可以使用 C++。如果另一个小组编写和扩展同一应用程序的业务逻辑和数据访问代码,出于高级别工作效率的考虑,它可以使用 Visual Basic。这种混合和匹配语言的能力使公司可以更容易地充分利用现有的编程能力。

基于接口的编程

Microsoft 工程师在设计 COM 的过程中做出了许多重要的结构性决策。其中一个意义最深远的决策是要求 COM 具有在形式上同实现分开的接口。这意味着 COM 建立在基于接口的编程的想法上。

基于接口的编程概念并不是 Microsoft 工程师提出的新妙想。这种编程样式已经为计算机理论科学家和需要生成大型可扩展应用程序的组织所采用。基于接口的编程首先在诸如 C++ 和 Smalltalk 这类语言中得到应用,这类语言没有对独特的独立接口概念提供正式支持。今天,Java 和 Visual Basic 这类语言和工具均具有对该编程样式的内置支持。因此,虽然 Microsoft 不能因该想法而赢得赞誉,但的确应该因预见到基于接口的编程的简洁性并将其用作 COM 的基础而赢得赞誉。

和类一样,接口也是一个独特的数据类型。它定义一组公共方法,但不包括任何实现。在另一种意思上,接口为客户端和对象之间发生的通讯定义一个非常特定的协议。将接口与实现接口的类分离开使类的作者得以执行许多原本不可能的操作。开发人员根据接口定义编写客户端应用程序可以避免类定义上的依赖项。虽然基于接口的编程可以证明是 COM 更具挑战性的方面之一,但其概念对于理解 COM 的工作机制和理由非常重要。

分布式 COM

COM 最初是为超越进程边界而设计的。在 COM 的早期版本中,只有当客户端进程和服务器进程在单个计算机上运行时才可能实现此目的。在 Microsoft Windows NT 4.0 版中,COM 中增加了使这种进程间通讯得以扩展到计算机边界以外的支持。Microsoft 为 COM 创建了一个新的连网协议,使得可以在 LAN 环境中部署分布式应用程序。这在 Microsoft 的企业计算策略中是一个重要的里程碑。

起先,Microsoft 经过努力,提出了一个销售用语来表示 COM 最终可用于从网络上创建对象。当 1995 年 8 月 Windows NT 4.0 首次面市时,名称分布式 COM (DCOM) 胜过了网络 OLE。今天,这两个术语在开发人员中间都不再时髦。虽然许多开发人员认为 COM 本身就是一种分布式技术,在 COM 前面加上分布式是多余的,但是分布式 COM 目前是谈论 COM 网络协议时使用的恰当术语。

正如前面提到的,COM 对分布式应用程序的支持基于名为远程过程调用 (RPC) 的进程间机制。RPC 是一种行业标准,在许多不同的平台上已经成熟了。Microsoft 用面向对象的扩展增强了 RPC 以适应 COM,而 Windows 平台上的结果实现称为对象 RPC (ORPC)

COM 和 RPC 之间有共生关系。COM 为 RPC 提供面向对象的感觉,而 RPC 给予 COM 从网络上提供对象的能力。COM 利用 RPC,通过在客户端和对象之间发送请求和响应数据包,在远程计算机上透明调用方法,而客户端仍照常调用方法,就像对象在附近一样。值得注意的是,COM 的结构设计者如何做到向中间层程序员和客户端程序员隐藏 RPC 所需的如此多的细节。

从 COM 到 MTS

发布 Microsoft Transaction Server (MTS) 是平台发展过程中的一个重要里程碑。MTS 是一个为 Windows NT Server 创建的软件。正如其名称所暗示的,MTS 允许在 Windows NT Server 上运行的中间层对象从中间层运行和控制分布式事务。但是 MTS 远不仅是一个事务监视器;它向中间层中运行的 COM 对象提供了一个全新的运行时环境。MTS 增加了许多 COM 中不包含的关键性结构支持。具体说来,它新增了对分布式事务、集成安全性、线程池和改进的配置和管理的支持。

名称 MTS 已引起混淆,因为该软件并不只是为要运行分布式事务的公司创建的。它提供了一个载体,使 Microsoft 可以交付下一代分布式应用程序框架。专门用于 Windows NT Server 的中间层对象应在 MTS 环境中运行,不论它们是否涉及事务。当人们得知 MTS 可用于部署非事务性对象时,他们会感到迷惑不解。在 Windows 2000 中,为消除这种混淆,Microsoft 将中间层运行时环境的名称由 MTS 改为 COM+。为 MTS 创建的事务支持也包括在 COM+ 中。如果您已经知道如何使用 MTS 编写事务程序,则无需了解更多内容就可编写 COM+ 事务性组件。它们的工作机制几乎完全相同。

除了支持分布式事务外,MTS 还扩展了 COM 的安全模型。MTS 安全性基于角色的概念。角色是一个抽象概念,表示 MTS 应用程序中一个或多个用户的安全配置文件。在设计时,开发人员可以声明方式或编程方式,使用角色来设置安全检查。在部署时,管理员将一组角色映射到 Windows NT 域中的用户帐户和组帐户。MTS 基于角色的安全模型与 COM 提供的原始安全模型相比,提供了更大的灵活性和更细的粒度。

MTS 添加到平台的另一个重要功能是通过在后台操作线程池来管理并发的方案。MTS 引入了一个称为活动的抽象概念,表示 MTS 应用程序中的逻辑执行线程。MTS 程序员在编写他们的应用程序时,应基于每个客户端应用程序提供一个活动。MTS 运行时自动将逻辑活动绑定到物理线程。一旦客户端数量达到预定义阈值,MTS 运行时就开始在多个客户端间共享各线程。

使用线程池方案的多层应用程序比使用单线程模型或每个客户端一个线程模型的应用程序具有更好的缩放性。单线程模型消除了任何并发机会,因为它无法同时执行两个或更多客户端的方法。每个客户端一个线程模型在大型应用程序中导致令人无法接受的资源使用,因为需要不停地创建和删除物理线程。线程池方案(如内置在 MTS 中的方案)的目的是在较高级别的并发和更有效的资源使用之间建立最佳平衡。在这方面,MTS 承担的任务相当艰巨,并且将它巧妙地隐藏起来。

MTS 的另一重要功能是对计算机配置和网络管理的改进支持。COM 使在网络环境中部署和管理基于 COM 的大型应用程序变得复杂和昂贵。MTS 管理工具使配置和管理运行中间层对象的服务器计算机变得更容易。与 COM 不同,MTS 使得从一个桌面管理许多服务器计算机成为可能。MTS 还提供生成客户端和服务器端安装程序的工具。

基于属性的编程

MTS 在平台的编程模型中引入了一个非常重要的概念:基于属性的编程。平台提供的服务通过声明性属性公开。属性设置由程序员在设计时决定,并且可由管理员在应用程序投产后重新配置。基于属性的编程与过去大多数操作系统公开系统服务的方式非常不同。

传统上,操作系统通过调用级应用程序编程接口 (API) 中的一组功能公开服务。在该模型中,应用程序通过发出对 API 的显式调用来利用系统服务。这意味着必须将显式系统级调用编译到应用程序中。如果在应用程序投产后想更改系统服务的使用方式,必须修改代码并重新编译应用程序。基于声明性属性的编程模型则灵活得多。

让我们考察一个示例,使您对声明性属性的工作机制有一个更清楚的了解。MTS 应用程序中的组件有一个通知 MTS 运行时环境它是否支持事务的属性。如果程序员标记组件需要事务,则该组件的实例化对象在逻辑 MTS 事务的上下文中创建。当客户端调用这些事务性对象的其中一个时,MTS 运行时自动发出启动物理事务的调用。它还发出相应的调用以提交或回滚事务。关键是程序员从不发出启动、提交或中止事务的显式调用。所有必要的调用都由 MTS 运行时在后台发出。

图 7:基于属性的编程模型依赖侦听来利用系统服务。

基于属性的编程模型为什么优于原来的过程模型?哪一个要求显式 API 调用?首先,新模型需要的代码更少。您在设计时通过设置属性表明您的选择,基础运行时环境将确保您的要求得到满足。其次,不太明显的原因是,管理员在应用程序投产后可以很容易地重新配置应用程序使用系统服务的方式。无需修改任何代码或重新编译应用程序。

MTS 基于属性的编程模型依赖于称为侦听的机制。当客户端从已配置在 MTS 应用程序中的组件创建对象时,基础运行时插入一个侦听层,如图 7 所示。该侦听层表示允许 MTS 运行时对方法调用执行系统提供的预处理和后续处理的挂钩。当对象即将在每个方法之后执行代码之前和刚执行完之后,系统窃取控制。

COM 问题与 MTS 问题的比较

对于生成专用于 Windows NT Server 的多层应用程序的程序员来说,最大的两难选择之一是决定在 COM 与 MTS 两者间何时使用哪一个。很多公司选择使用 MTS,因为它提供了许多 COM 没有提供的重要内置服务。其他公司则选择使用 COM,因为他们不了解 MTS 运行时环境的附加价值。

COM 随 Windows NT Server 一起提供,而 MTS 则不是。若要使用 MTS,必须安装一个额外的软件 Windows NT Option Pack。这意味着 MTS 其实并非 COM 的组成部分。COM 具有自己的编程模型和运行时层;而 MTS 具有不同的编程模型和单独的运行时层。

应该明白,MTS 只是建立在 COM 之上的一个层。从未修改过 COM 以适应 MTS。那么这意味着什么呢?这两个运行时层的集成紧密程度并没有达到它们所能达到的程度。这导致平台包含一定程度的低效率、不明确和混淆。事情对于 MTS 程序员来说很棘手,因为他们需要了解这两个编程模型的工作机制。而且,许多有效的 COM 编程方法在用于 MTS 应用程序时不能正常工作。

从 COM 和 MTS 到 COM+

随着平台体系结构设计者开始计划更改和增强 Windows 2000,有一件事很明显:COM 和 MTS 必须统一到单个运行时层和单个编程模型中。这不是一项价值不高的工作,而是非常值得努力去做。

在 Windows 2000 版中,COM 和 MTS 的所有最佳构想都集成到名为 COM+ 的新运行时中。与 MTS 不同,这种新的运行时层不是可选的。COM+ 是 Windows 2000 默认安装的一部分。但好的方面是 Windows 2000 上已不存在 COM 与 MTS 间的两难选择。而且,编写 COM+ 的组件比编写 MTS 的组件更容易,因为许多与 MTS 有关的烦人特性已不存在。

与 COM 一样,COM+ 基于二进制组件和基于接口的编程。通过使用透明 RPC 层,可以跨越进程和计算机边界进行远程方法调用。正如 COM 组件那样,COM+ 组件可以在成品中升级和扩展,而不会对使用它们的客户端应用程序造成负面影响。

与 MTS 一样,COM+ 支持分布式事务和基于角色的安全性。它提供内置线程池方案,该方案与 MTS 的线程池方案一样透明。COM+ 编程模型同样利用侦听通过声明性属性向开发人员公开平台服务。但是,COM+ 比 MTS 更进一步地利用了基于属性的编程。除了事务性服务和集成安全性外,COM+ 还公开自定义对象构造、同步、对象池等服务。COM+ 的其他新功能(如排队组件和 COM+ 事件)也通过可配置的属性公开。

配置组件与未配置组件的比较

如果希望组件利用 COM+ 服务,必须在 COM+ 应用程序中安装这些服务。在 COM+ 应用程序中安装了组件后,系统会在名为 COM+ 注册数据库 (RegDB) 的系统目录中为该组件提供一个配置文件。该目录保存组件和 COM+ 应用程序的已配置属性设置。已安装在 COM+ 应用程序中的组件称为配置组件,主要是因为它具有关联的 COM+ 属性设置。

您还会遇到一种没有关联 COM+ 属性的早期组件类型:未配置组件。未配置组件不安装在 COM+ 应用程序中,而是以与早期版本的 COM 一致的方式进行注册。未配置组件无法利用 COM+ 服务,但它们可以在除 MTS 和 COM+ 以外的环境中运行。

如果创作 COM+ 应用程序的组件代码,生成的一般是配置组件。该方法使您可以利用各种平台服务。在编写代码时,还可能会遇到未配置组件。例如,ActiveX 数据对象 (ADO) 库就由未配置组件组成。ADO 对象可以在 COM+ 应用程序中运行,但与配置组件不同,它们还可以在基于早期版本的 COM 的应用程序中运行。

了解 COM+ 服务

除了提供运行时环境外,COM+ 和 Windows 2000 还包括若干内置服务,这些服务对于生成多层应用程序的程序员而言非常重要。有些多层应用程序可能只需利用其中一两种服务。有些则可能需要使用所有这些服务。应该对所有这些服务共同配合的机制有一个大体了解,以便在最初的设计阶段能够做出明智的决定。下面各节简要概述分布式应用程序平台的最重要服务。

Internet Information 服务

Internet Information 服务 (IIS) 是 Microsoft 的 Web 服务器。该产品最初是为 Windows NT Server 开发的。最新版本是 IIS 5.0,随 Windows 2000 一起提供。与其他 Web 服务器产品一样,IIS 处理客户端应用程序发送的传入 HTTP 请求。早期版本的 IIS 主要用于提供静态 Web 页。今天,许多基于 Web 的应用程序都使用 IIS 在每个传入请求之后运行自定义处理。

对于需要创建带有自定义服务器端逻辑的 Web 应用程序的开发人员,IIS 公开了一个称为 Internet 服务器 API (ISAPI) 的专用 API。直接用 ISAPI 编程的程序员创建名为 ISAPI 扩展ISAPI 筛选器的软件模块。虽然编写基于 ISAPI 的软件可以提供最高级别的性能和灵活性,但此方法仍有几个重大的开销——它要求用 C 或 C++ 而不是 Visual Basic 来开发,并且通常迫使程序员处理低级别的结构细节,比如编写线程池管理器。

许多公司不希望直接用 ISAPI 编程,因为他们没有专业知识,或者不愿意投入必要的时间和金钱。IIS 提供了一种替代 ISAPI 的方法,此方法具有一个名为 Active Server Pages (ASP) 的框架。ASP 框架本身是 ISAPI 扩展,它允许程序员使用脚本语言和 Visual Basic 编写服务器端逻辑。

应注意,使用 ISAPI 或 ASP 生成的 Web 应用程序可以提供纯 HTML 解决方案(如果您希望如此)。您做出所有与应用程序将支持的浏览器有关的决定。您可以创建支持大型 Internet 样式用户基的纯 HTML 解决方案,也可以在 Intranet 样式环境中利用某种浏览器(如 Internet Explorer)的优点。

许多公司只使用 ASP 便建立了相当复杂的站点。使用脚本语言(如 Visual Basic Scripting Edition (VBScript) 和 JavaScript)和开发工具(如 Microsoft Visual InterDev®)可以相当容易地编写服务器端业务逻辑和数据访问代码。但是公司也发现重用、维护和扩展遍布许多不同页的逻辑非常困难。随着站点的扩大,这一点变得更加明显。一种更好的方法是将业务逻辑和数据访问代码封装在已编译的组件中。

ASP 和 COM+ 间的集成使得易于从 ASP 页创建和运行自定义业务对象。这意味着可以使用嵌入在 ASP 页的组件而不是脚本来分布大多数服务器逻辑。使用组件使得重用、维护和扩展代码变得更容易。这种组件可以用 Visual Basic 来创建,Visual Basic 提供的测试和调试实用工具比任何基于 ASP 的开发工具都要好得多。许多公司已发现 ASP 与 Visual Basic 一起使用可以提供工作效率、可维护性和性能之间的最佳平衡。

Microsoft 消息队列服务

Microsoft 消息队列服务 (MSMQ) 是平台的另一个重要部分。MSMQ 是一种中间件服务,它有助于多层应用程序中各进程间的消息处理。如前面提到的,消息处理非常重要,因为它提供异步和无连接通讯,而这是 RPC 和 HTTP 都不能提供的。

MSMQ 是基于到命名队列的异步消息传送的消息处理产品。在高级别上,消息模型过程在客户端和服务器之间进行调用,但任何一方在缺少对方的情况下也能正常工作。概念上的最大差异是消息只沿一个方向移动,而 COM 方法调用既涉及发送到对象的 RPC 请求,也涉及返回到客户端的 RPC 响应。

使用 MSMQ 时,即使服务器应用程序脱机,客户端应用程序也可以发送请求消息。这还意味着服务器可以在所有客户端应用程序脱机后响应请求消息。在客户端应用程序和服务器因任意多个原因而断开连接的情况中,该功能使分布式应用程序得以全部保持并运行。

何时需要使用 MSMQ?让我们看一个典型的例子。在一个销售订单应用程序中,即使服务器应用程序未运行,客户端也可以向订购请求队列提交销售订单。服务器应用程序稍后可以打开该队列,并开始处理订购请求。MSMQ 还使服务器应用程序可以像响应方法调用一样,将响应消息返回到发送方。当涉及消息处理时,它只需稍微多做一点工作。

MSMQ 对有使用便携机的用户(这些用户不断与网络断开连接并重新连接到网络)公司来说也有用。使用 MSMQ 时,您只需创建在网络上将消息发送到队列的客户端应用程序。如果便携机脱机,MSMQ 自动将消息存储在临时本地队列中。当便携机重新连接到网络时,MSMQ 检测到网络可用,并自动将缓存的消息转发至适当的目标队列。正如可以看到的,存储-转发机制的主要方面巧妙地隐藏在基础平台中。

与基于 RPC 或 HTTP 的产品相比,消息处理产品(如 MSMQ)还可以提供更好的传送保证。可以在事务范围内发送 MSMQ 消息,以提供只一次的传送语义。这意味着 MSMQ 采取许多额外的防范措施,确保消息最终到达目的地。当消息超时或无法路由到目的地时,它还提供额外的结构支持将故障通知传输回发送方。MSMQ 确保将消息发送到目的地,或者通知您消息未能发送。MSMQ 消除了许多影响基于 RPC 和 HTTP 的应用程序的消息丢失问题。

排队组件

MSMQ 于 1997 年 11 月随 Windows NT Option Pack 的发行首次出现在 Windows NT Server 中。从那时起,Visual Basic 程序员便能够利用 MSMQ 获得异步无连接通讯带来的益处。但是,MSMQ 编程要求编写额外的代码从客户端应用程序创建、准备和发送消息。它还需要您编写服务器端侦听器应用程序。与使用 COM 方法调用进行通讯相比,使用 MSMQ 进行通讯在发出请求和得到响应上需要执行的工作明显增多。

COM+ 提供一个名为排队组件的服务,它允许无需用 MSMQ API 进行显式编程即可利用 MSMQ。排队组件服务只是一个建立在 MSMQ 上的生产层。创作排队组件的方法与创作标准 COM+ 组件的方法几乎完全相同,但是有一两个限制。例如,无法用输出参数或返回值设计方法。

在 COM+ 应用程序中创建并安装了排队组件后,必须配置一个属性来指示所使用的接口应该排队。还必须将 COM+ 应用程序配置成排队和用作侦听器。当您做这些工作时,排队组件服务自动为应用程序创建特殊队列。它还设置系统提供的侦听服务,以在传入消息到达时处理它们。

在服务器上正确配置了排队组件后,可以编写使用该组件的客户端应用程序。客户端应用程序不直接实例化排队组件的对象,而是创建称为记录器的特殊客户端代理对象,就客户端而言,其外观就像实际的对象。然后客户端照常开始调用方法调用。排队组件服务提供一个结构,用于在 MSMQ 消息中记录这些方法调用,并将该数据通过网络传输到安装有排队组件的计算机。排队组件服务的服务器端接收该消息,创建排队组件的实例,并重播方法调用。

如您可以看到的,排队组件的主要设计目的是提供 COM 方法调用的便利和异步无连接通讯的益处。本质上,排队组件将 MSMQ 而不是 RPC 用作基础传输协议。排队组件因此可以避开面向连接的同步协议的许多限制。

应注意,不必使用排队组件服务来利用 MSMQ。总是可以直接用 MSMQ 编程。排队组件服务是面向工作效率的框架,它隐藏 MSMQ 编程的许多冗长细节。与任何其他框架一样,它通过牺牲灵活性来提供更高的工作效率。

有相当多可以用 MSMQ 完成的工作不受排队组件的支持。应该仅在排队组件服务支持所需功能,并且节省许多 MSMQ 编程时间时才使用它。它的最有价值的功能之一是服务器端侦听器服务。只使用 Visual Basic 创建多线程侦听器服务几乎是不可能的,所以,如果需要每秒可以处理许多消息的服务器端侦听器应用程序,而又不希望用 C++ 来开发,排队组件正是您需要的。

COM+ 事件服务

一些多层应用程序要求某些用户或应用程序接收引起关注的事件的通知,如雇佣新职员、股票价格变化或要求重新进货的库存水平下降。COM+ 事件提供在应用程序之间发送和传输事件通知的服务。

在 COM+ 事件模型中,发出事件通知的应用程序称为发布服务器。接收事件通知的应用程序称为订阅服务器。COM+ 事件通常称为松耦合事件 (LCE),因为发布服务器和订阅服务器彼此并不了解。相反,一组事件在事件类范围内定义,而该事件类安装在 COM+ 应用程序中。发布服务器和订阅服务器知道事件类,但永远不知道对方。

发布服务器和订阅服务器的分离带来相当多的好处。您不用担心在创建发布服务器应用程序时由谁来侦听,所以要编写的代码较少。并且在发布服务器应用程序投产后,如果需要添加或移除订阅服务器,无需修改它。此外,如果需要添加或移除与事件类关联的发布服务器,也不必修改订阅服务器。

下面简要概述一下该事件模型的工作机制。您创建一个实现一个或多个接口的事件类。每个接口定义一组方法,它们表示一个事件集。您编写订阅服务器组件,以实现这些接口并在激发事件时响应事件。最后,您编写发布服务器应用程序,以创建事件类的对象并在它想要激发事件时调用各种方法。事件服务负责处理方法并将事件发送到每个订阅服务器。

有两种订阅类型:持久订阅瞬态订阅。当事件发送到持久订阅时,COM+ 事件服务从配置的订阅服务器组件创建新对象,并调用与事件关联的方法。如果订阅服务器应用程序尚未运行,事件服务会将其唤醒。应注意,对于持久订阅,每次激发事件时都创建和销毁对象。

第二种订阅类型是瞬态订阅。应用程序一旦运行,就可以将自己注册到特定的事件类,以在事件激发时侦听事件。这种情况下,事件服务不为每个事件创建和销毁对象。这两种订阅类型的主要差异在于:瞬态订阅必须以编程方式创建新订阅,并且必须注册回调才能侦听事件。

创建瞬态订阅服务器比创建持久订阅服务器需要更多的代码。创建持久订阅服务器更容易,因为可以使用 COM+ 管理工具。而且,如果保存事件类的服务器重新启动,持久订阅服务器将继续正常工作。但是,所有瞬态订阅服务器必须创建和注册新订阅。

可缩放的事件通知结构需要异步通讯。如果发布服务器必须等待每个订阅服务器处理其事件通知,则可能说明系统性能不够完善。而且,一些应用程序可能要求用与 MSMQ 一致的无连接方式发送事件通知。COM+ 事件已与排队组件紧密集成在一起,以提供异步无连接通讯的优点。可以同时将发布服务器和订阅服务器配置为使用排队组件而不是 RPC。对于许多应用程序来说,COM+ 事件只有在和排队组件服务一起使用时才有价值。

用 Visual Basic 生成分布式应用程序

如果使用 COM+ 及其服务生成用于 Windows 2000 的分布式应用程序,您会发现自己所处的环境与图 8 所示的环境一样。如您可以看到的,有很多东西需要学习。

图 8:使用 COM+ 和 Visual Basic 创建中间层组件

在市场上所有支持 COM 的开发工具中,Visual Basic 提供的工作效率水平最高。Visual Basic 3.0 和 Visual Basic 4.0 在产品的 COM 支持方面都有一定程度的进步,但只有 Visual Basic 5.0 真正使该开发工具成为一个为基于 COM 的系统生成组件的可行选择。Visual Basic 6.0 添加了更多对 COM 和 MTS 开发的支持。

请花点时间考虑下面的问题。您如何看待 Visual Basic?它是否提供了编写大型应用程序的代码的可行选择?您为什么阅读本文?从 Visual Basic、C++ 和结构化查询语言 (SQL) 三者之中选择,以回答下列问题:

  • 哪种语言最易于编写业务逻辑?
  • 哪种语言提供了最低的代码维护开销?
  • 哪种语言提供了最快的增强现有应用程序的手段?
  • 哪种语言最适合没有典型的计算机知识背景的人?

对于上述所有问题,许多设计人员和项目负责人会不假思索地回答:“Visual Basic”。但 Visual Basic 决不是万能语言。在某些情况下,C++ 或某个其他语言对特定的组件可能是更好的选择。例如,许多 COM 接口(如由 OLE-DB 公开的接口)只有通过 C++ 才能容易地访问,这意味着应该使用 C++ 编写某些组件。但是,公司有许多机会在分布式应用程序中使用 Visual Basic。其中最大的一个机会是编写大型信息系统的中间层中分布式对象的业务逻辑和数据访问代码。

在双层系统盛行的时候,Visual Basic 是用于生成用户界面的极为流行的工具。那时公司使用 Visual Basic 生成在桌面系统上运行的基于窗体的应用程序。Visual Basic 程序员花费大量的时间设计窗体和编写代码以解决用户交互。情况的确发生了变化。越来越多的公司已转变为使用基于 HTML 的开发工具(如 Visual InterDev)生成用于表示层的基于浏览器的应用程序。Visual Basic 程序员一直在以某些方式寻找新的归宿。

对于 Visual Basic 程序员而言,新的光明前途是生成用于中间层的非可视组件。认为 COM 编程需要用 C++ 的公司正在改变自己的论调。越来越多的公司尝试用 Visual Basic 编写尽可能多的中间层代码。而且,Visual Basic 程序员得到生成平台的人们的大力支持。搭建 COM+ 体系的结构设计者和实施者将 Visual Basic 程序员看作他们的最大用户。

posted @ 2005-06-11 17:50  vboy  阅读(867)  评论(0编辑  收藏  举报