计算机应用研究
APPLICATION RESEARCH OF COMPUTERS
2000　Vol.17　No.5　P.54-57



COM+及其基于属性编程
潘登　侯文永
摘  要  讨论了作为Windows DNA架构的核心部分的COM+在原有DCOM和MTS的基础上提供的多种服务以及COM+的基于属性编程。
关键词  COM+  基于属性编程  DCOM  MTS
1  概述
　　Windows DNA (Distributed InterNet Application Architecture)是微软从基于工作站的应用程序开发向企业级应用程序开发转移的核心架构。它作为一个完全集成的n-层开发模型，为开发人员在Windows平台上开发扩展性好的企业级应用程序提供服务。图1展示了Windows DNA的长期目标：客户端的图形用户界面Forms+，中间层的COM+，以及数据层的Storage+。现在的程序员在开发用户界面时常常为选择什么样的开发平台而左右为难，Forms+则是对这个问题的回答，它将Win32 GUI和Web API结合了起来。Storage+是Windows未来的文件系统，看起来有点像OLE DB。这两者的详细情况微软尚未公布，而COM+作为Windows DNA的核心将随着Windows 2000一同发布。在这里将首先讨论什么是COM+，然后讨论COM+为现在的COM和MTS技术增加了哪些服务，最后再讨论一下COM+的属性编程。

图1Windows DNA长期目标
2  什么是COM+
　　COM+覆盖了许多领域，为简单起见，可以将COM+看作是COM加上MTS编程模型再加上一些新的特征。COM是作为工作站级的组件技术开发出来的。随着DCOM的发行，COM也可以通过远程方法调用和远程组件实例化来支持分布应用。MTS是用来提供服务器端的组件服务，并弥补一些COM的不足，如安全性问题，组件管理等。COM+则将COM，DCOM，MTS统一成为一个企业级的组件技术。如图2。

图2COM+MTS=COM+
　　COM+扩展了COM和MTS编程模型，同时还解决了许多COM和DCOM开发过程中的许多问题，并提供了更多的服务。例如，COM+提供了更好的组件管理环境，支持负载平衡和对象缓冲和使用更加方便的事件模型。
　　从另一个方面来看，COM+是微软组件技术的成熟。COM的概念对程序员来说比较难以理解，尤其是在刚刚接触COM的时候。而COM+则将许多细节移到了操作系统，使程序员将精力集中在高层次的业务逻辑方面。
3  COM+服务
3.1  COM+目录服务
　　现在COM和MTS组件把它们的配置信息放在Windows注册表里，而COM+则把大多组件的信息放在一个新的数据库里，这个数据库就叫做COM+目录(COM+ Catalog)。COM+目录统一了COM和MTS注册表，并提供了一个组件管理环境。开发人员通过COM+ Explorer或一系列新的COM接口来访问COM+目录。
　　COM+的一个新特征是它支持声明编程(Declarative Programming)。意思是说，开发人员按通常的方式开发一个组件，在分发的时候组件的细节却各不相同。例如，开发人员开发一个可以在有负载平衡环境下工作的组件，但是否使用负载平衡特性却各不相同。有些应用程序需要使用负载平衡特性，而另一些却不。是否使用负载平衡特性是通过COM+ Explorer在管理层上设置的。
3.2  COM+负载平衡
　　现在的COM和MTS的一个缺点是它们不支持动态负载平衡。为了创建远程组件的一个实例，客户端应用程序必须显式地指出组件服务器的机器名称。这样就导致应用程序的扩展性不好。COM+通过对客户端应用程序提供透明的负载平衡服务解决了这个问题。
　　为使用负载平衡特性，首先定义一个应用服务群(多台安装有组件的服务器)，然后配置一台负载平衡路由器，由它接收创建对象请求并将请求送到应用服务群中的某台服务器上。COM+负载平衡作为一个Windows NT服务运行在路由结点上。当收到一个创建对象的请求后，它和本地SCM (Service Control Manager)一起将请求送到应用服务群中负载最轻的服务器上。

图3COM+动态负载平衡
　　每个具有负载平衡能力的组件与一个负载平衡引擎相联系，引擎和路由结点通信来决定将请求送到哪一台服务器上。缺省的COM+负载平衡引擎使用应答时间算法，应答时间通过测量每台组件服务器上每个接口的每个实例的每次方法调用的时间来计算出来。这个算法不一定对每个应用都最合适，但在大多数环境下它工作得很好。程序员还可以开发自己的负载平衡引擎，引擎组件本身也是一个COM+组件。
　　路由结点在收到创建对象的请求时，首先在COM+目录检查该组件是否支持动态负载平衡，如果是，再将请求送到合适的服务器。请求被送到服务器后一旦对象创建好，则将对象的引用直接传回到客户，在客户和服务器间建立直接连接。
　　虽然COM+负载平衡对客户端透明，但为了提高效率，在编程时仍要小心。首先，创建远程对象时使用路由结点的名称而不要使用远程服务器的名称。由于COM+的动态负载平衡只在组件激活时起作用，所以客户应只在需要的时候创建远程对象，使用完毕后应尽快地释放(这和MTS客户编程模式有点不一样。MTS客户应尽早地得到对象引用，然后就一直抓着不放，以免频繁地创建释放对象)。
　　虽然COM+动态负载平衡仍然存在一些问题，比如说，在路由结点上存在单点失效问题，但它毕竟在对分布应用的扩展性支持方面迈出了一大步。
3.3  COM+内存数据库
　　我们知道，对于数据访问频繁的应用程序，提高其性能的最好方法就是把尽可能多的数据放到物理内存里。COM+的IMDB(In-Memory Database)就提供了这方面的服务。IMDB是只在物理内存上操作的临时性事务数据库系统。虽然IMDB主要是用于Web环境以解决大量用户对数据库的访问问题，但它依然适用于任何需要快速大量数据访问的应用。

图4COM+内存数据库
　　IMDB实现了一个面向数据库，优化查询的缓冲系统。它能从后台数据库装入物理数据或者用来存放临时数据。对一个热门Web站点，每分钟要对成千上万的用户提供数据查询服务，这个代价将是相当昂贵的。通过使用IMDB，把那些访问频繁的表格装入Web服务器的物理内存，就能简单地通过增加物理内存来支持更多的用户，而内存的价格越来越便宜，这样也就大大降低了成本。同时也减少了Web服务器和数据库服务器之间的网络流量。
IMDB的一个重要的不同是它不通过SQL语句来访问数据。IMDB的主要目标是尽可能快地访问数据，为了达到这个目标，数据访问是通过标准的ISAM技术而不是SQL解释器来实现，这就是说，必须对查询或过滤的字段建索引。
　　IMDB作为快速数据访问的缓冲相当有效，它同时也能为应用程序管理临时数据。现在的MTS组件通过SPM(Shared Property Manager)来共享临时数据。IMDB现在支持事务操作，并且将来也会支持分布操作，它最终将成为组件共享临时状态信息的解决方案。
3.4  COM+对象缓冲
　　对象缓冲(Object Pooling)是把多个组件实例装入内存的过程。对象缓冲后，当有客户请求到来时就能立即给客户应答，大大提高了客户响应速度。对象缓冲是大型可扩展应用程序的另一个重要特征。在MTS环境下开发组件时，组件实现IObjectControl 接口。当组件在MTS内部实例化时，MTS通过IObjectControl接口提供激活/失效通知。当使实例无效时，MTS调用CanBePooled( )来看实例是否能被放入缓冲。现在的MTS不支持对象缓冲，所以CanBePooled( )永远不会被调用。COM+系统则支持对象缓冲。
　　其实大多数情况下不需要开发支持对象缓冲的组件。那么，什么时候需要呢？一，对象的创建时间大于对象的实际使用时间。二，组件访问有限资源如数据库，管道连接等。由于对象缓冲的大小可以限制，对象缓冲在第二种情况下特别有效。
　　COM+系统已经提供了许多系统级的支持对象缓冲的组件(例如ODBC资源对象等)，所以在开发大型的可扩展应用程序时开发人员可以集中精力提供应用级组件。
3.5  COM+排队组件
　　现在的COM开发模式是基于过程调用。客户与组件建立RPC连接，查询某个接口，然后用返回的接口同步调用某个方法，通过[out]参数取得返回信息。客户的生存期是和组件实例紧密联系在一起。
　　COM提供的基于RPC的服务对构建分布应用来说是必须的，然而，对某些应用来说，使用消息传递技术可能会更适合。新的COM+排队组件(Queued Component)服务为这一类应用提供了解决方案。
　　基于消息传递的应用在底层使用消息传递系统而不是RPC连接，这样将客户和组件的生存期分离开来。COM+排队组件使用的底层系统是MSMQ (Microsoft Message Queue Server)，客户与组件通过排队机制分离开来。

图5COM+排队组件
　　这样就使应用程序具有更加灵活的可扩展性和可用性。如果组件暂时不可用，则客户程序仍然可以执行。如果客户很多而服务器很少，则可以将客户的请求排队，从而均衡服务器的负载。对像Web站点这样负载不稳定、起伏大的应用来说，采用消息传递方法将带来极大的好处。
当然，基于RPC连接和消息传递的服务对分布式应用来说都需要，开发人员可以根据最终用户需求来选择适当的技术。
　　像大多数COM+服务一样，COM+排队组件也尽可能多地将底层细节对开发人员隐藏起来。实际的排队机制对开发人员透明，开发人员可以像开发其它组件一样开发COM+排队组件，但有两点例外：一、组件接口只能有[in]参数，这些参数将通过MSMQ消息按值而不是按地址传递。二、组件接口方法不能有返回值。
　　当客户实例化一个组件时，COM+运行环境实际上在本地创建一个称为“录音机”的代理对象。当客户方法调用时，录音机把调用按顺序“记录”到MSMQ消息里。客户释放对象的所有引用后，这个消息通过MSMQ被送到服务器。在服务器上，一个特别服务将这些消息取出来，然后用另一个称为“放音机”的代理生成组件实例。放音机“播放”那些方法调用同组件实例交互，就像组件在同客户在交互一样。如果出错，则将消息放回队列里面去。
　　COM+提供的分离、异步处理使开发人员在开发分布式的企业应用程序时具有更大的灵活性。
3.6  COM+事件
　　COM提供了两种技术来处理组件和客户之间的事件。第一种技术使用接口回调机制，由客户实现服务组件描述的接口，组件服务器通过调用这些客户接口来实现事件触发。第二种技术叫做可连接对象(Connectable Objects)，使用标准的COM接口IConnectionPoint 。后一种方法和第一种相似，但它提供了一种更通用的方法来连接客户和组件。
　　谈到事件的时候客户和组件的概念就模糊起来。事实上，组件变成了客户，客户变成了组件。它们实际上是两个共享信息的合作软件实体。COM+称发布信息的实体为“发行者”(Publisher)，接收这些信息的实体为“订阅者”(Subscriber)。
COM事件模型有以下缺点：
　　．发行者和订阅者紧密地联系在一起，在编译时互相要知道对方的接口定义。
　　．支持多路广播需要编写许多额外的代码。
　　．这种模式只定义了一些接口，开发人员仍然需要编写代码来实现这些接口。
　　．IConnectionPoint接口在分布环境下效率特别差。
　　．不支持持久连接，当然这也是由于COM的实现是基于RPC的。

图6COM+事件模型
　　COM+事件模型引入了一个称为事件类(Event Class)的中间对象。事件类是由COM+运行环境实现的组件，位于发行者和订阅者之间。因为事件类实现了事件接口，对发行者而言，它是订阅者。当发行者要触发事件时，它创建一个事件类实例，调用某个事件类接口方法，然后释放接口。运行环境决定何时以及怎样通知订阅者。像排队组件一样，发行者和订阅者的生存期是分开的。也是由于同样的原因，事件接口只能有[in]参数。
　　接收事件比较简单。订阅者通过运行环境的帮助创建一个订阅对象，并将它加到COM+事件库(COM+ Event Store)，这样当发行者触发事件时，事件类就能确定谁“订阅”了该事件，并通知订阅者，甚至在必要的时候激活订阅者。
总而言之，新的COM+事件系统：
　　．将订阅者和发行者的生存期分离。
　　．在事件系统增加了一个激活模式。当事件发生时若订阅者没有激活，运行环境可以激活订阅者而将事件信息传给它。
　　．提供一个第三方的发行者-订阅者环境。一旦事件类创建，双方都可以事件的发行者或订阅者。
　　．支持丰富的过滤机制。通过编写过滤对象，可以在订阅者级和发行者两端过滤事件，后者的效率更高。
　　COM+事件系统不单是为应用程序开发，它还在COM+内部被用来处理调试和跟踪消息，甚至用来实现操作系统本身。
4  基于属性编程
　　COM+提供了这么多特征，C++程序开发人员仍然需要某种方式来利用这些特征。开发COM组件是一项困难的工作，因为COM和C++的开发模式不一样，尽管ATL已经使开发COM组件容易多了，但它仍然需要一些底层的COM知识。COM+采用基于属性的编程(Attribute-based Programming)，大大简化程序开发。
　　基于属性编程是一种在代码里使用声明性指令(Declarative Instruction)来指导它的实现的技术，换句话说，就是不对每个组件编写相同的系统级代码，而是指导开发工具来实现这些代码。属性封装了底层概念，并将这些信息提供给编译器。属性并不改变底层的C++代码语意，而是通过“属性提供者”(Attribute Provider)将嵌入的属性转成标准的C++代码。

图7属性编译
　　在C++语言里支持基于属性编程并不需要修改C++编译器，只需要在编译过程里插入一个支持额外语言属性的机制即可。当编译器在源代码遇到属性时，它把属性传给属性提供者，属性提供者将属性转变成C++代码，然后将这些代码回送到编译器，然后编译器产生最终目标代码。这样任何人都可以写他/她自己的属性提供者来增加语言的功能。
5  结论
　　COM+作为Windows DNA架构的核心部分，在原有DCOM和MTS的基础上又提供了目录服务，动态负载平衡服务，内存数据库服务，对象缓冲服务，排队组件服务等多种可靠服务，同时还提供了新的事件模型，为应用程序开发人员开发大型可扩展的分布式企业级应用程序带来更大的灵活性。基于属性编程将底层的概念隐藏到操作系统内部，从而使应用程序开发更轻松，自然。
潘登(上海交通大学计算机科学与工程系 上海 200030)
侯文永(上海交通大学计算机科学与工程系 上海 200030)
参考文献
1，Windows DNA, Building Applications for the Internet Age, Microsoft Corporation White Paper, October 1998
2，Tom Armstrong, COM+ Event, Visual C++ Developers Journal, 1999 (July/August)
3，Tom Armstrong, COM + MTS = COM+, Next Step in the Windows Component Strategy, Visual C++ Developers Journal, 1999 (February/March)
4，Language Innovations for COM+ and Beyond, TOOL13 Presentation at Microsoft PDC 1998
收稿日期：1999-11-25
