深入理解基层知识
——COM+和MTS,DCOM和MSMQ,
.NET中的序列化
作者:KenSpencer
开发人员经常要我讲一些关于微软在今后对于以下几个方面的策略:COM+、微软事务服务(MTS)以及它的JIT引擎和对象缓冲(objectpooling)、微软消息队列(MSMQ)和DCOM。还有网站、应用服务器、ASP和组件整合之间的关系到底是什么?既然每个人都嚷着要答案,那么就让我们一次解决掉所有这些问题。首先,我来讲解一下有关COM+和MTS的问题。
使用COM+和MTS
COM+一直以来都很流行,所以如果需要用到COM+或MTS的特点,你可以使用微软.NET组件中的一些相应的技术。我认为:不管组件是否被发布都是解决方案的一部分。.NET中的组件就象COM组件,因为两者都是包含类的DLL,都能被另一应用程序实例化。它们之间主要的不同之处在于它们的实现方式不同,这也超出了我们所要谈论的范围。
当考虑在一个应用程序中使用什么组件时,有几个可供选择。可以选择使用COM+,也可以选择使用MTS,或者这两者都不用。COM+和MTS都是建立在COM组件上的。这样,如果你要创建一个可以在这两者中都可运行的组件,那么这个组件必须符合COM的二进制标准,而且在它可以使用前,必须先在注册表中进行注册。
.NET框架(同样VisualBasic.NET)是通过COM互操作服务来支持COM+和MTS的。一个基于窗口的应用程序(COM组件或类似COM组件的应用程序)可以叫做一个.NET组件;同样,一个.NET应用程序可以叫做一个COM组件。这两种方式的协同工作能力是很强大的,允许你在应用程序中混合使用它们的技术。
正如我所说,COM+和MTS是建立在COM组件上的。如果你把一个.NET组件(已编译好的)放在一个MTS包中或者一个COM+应用程序中,则这个组件可以被一个.NET应用程序调用,就像直接调用.NET组件而并不是一个MTS或者COM+组件一样。
当使用COM互操作时,一个潜在的问题是会增加系统开销。因为.NET和COM的执行方式是不同的(.NET使用通用语言运行时(CommonLanguageRuntime);COM则不是),而且.NET程序和COM组件的实现方式也是不同的(.NET用的是类型标准,而COM用的是二进制标准)。从一个环境中到另一个环境中进行调用显然会增加不少的系统开销,所以仅当必要时才使用COM互操作。实际上,对于每一次的互用操作都需要执行约20到30条的CPU指令。如果你调用一个基于COM+类的方法,则对于每个这样的调用,都会增加系统开销。
如果你的程序确实必须用到COM+的特征,或者必须用到MTS的特征,而且你确信需要所有的功能,那么就把你的组件放到COM+中,或者放到MTS中。如果你的组件是在单个数据库上执行事务的,并将总是仅在单个数据库上工作,则你没有必要用COM+来实现那些事务,你可以用ADO.NET来实现它们。不过,如果你需要对象缓冲或者对多数据库事务进行支持,那么就使用COM+或MTS。
如果你想实现在MTS或者COM+中的组件,那么你应该去查看.NET框架的MSDN文档,并且查看有关COM+的信息。这些文档会告诉你如何实现组件、如何使用不同的属性来自动化进程。
使用DCOM和MSMQ进行远程通信
你既可以使用.NETRemoting,也可以使用WebServices来取代DCOM。那么这两种方法有什么区别呢?区别在于你的应用程序以及你是如何在不同的程序段中进行通信的,还有程序的结构是不是有一个位于前端的ASP.NET。而你可以把代码放在程序的多个地方。
第一,你可以把代码放到APS.NET后置代码页中。这使得该页面类似于大多数ASP页面,代码被连到输出页。对于这种情况,此应用程序并不是分布式的,而只是一个双层架构,即:ASP.NET在前端;数据库在后端。
第二,你可以把代码放在一个模块中。如果在你的项目中进行一个模块定义,则一个模块文件就是一个简单的VisualBasic文件。你可以把函数和全局变量放在模块中,以便你可以在程序的任何地方都可以调用它们。这样一来,模块就代替了那些用来存放共用代码的包含文件。
第三,你可以开始把共用代码移植到一个类集合中。具有类定义并且包含一个接口(属性和方法)的文件或者一个文件的区段叫做类,你既可以在ASP.NET项目中创建一个类,使它成为项目中的一部分,也可以单独创建一个项目来实现一个类。后一种方法由于其共用代码较受欢迎,因为共用的代码可以以DLL的形式出现。正如在COM世界中一样,这个DLL可以被许多应用程序共享。
我们假设这个类含有存取数据的代码,是用来执行事务的。为了说明,我采用图1中所示的设计。此图包含了两个.aspx页,调用了一个商务对象来获得一些需要的信息。无论客户(Customer)、产品(Product)或订单(Order)对象都调用了数据库层(DatabaseLayer)对象,数据库层对象再对数据库进行数据存取或信息更新。
图1订购体系结构
这个应用程序并不需要MSMQ或者.NETRemoting或者WebServices,因为所有的组件都在同一个服务器上。你可以把数据库层组件或者商务组件移到另一个服务器上,但是如同ASP.NET应用程序一样,将所有的组件都放在同一个服务器上的运行速度会更快。这是什么原因呢?因为组件可以像ASP.NET应用程序那样,在同一个程序空间(同一个进程)中运行,这样就免掉了进程间的通信。是访问组件最快速的方法。无论何时调用进程外组件,都会增加系统开销,从而会减慢你的应用程序的运行速度。
如果商务需要,你也可以将其分割,把某些组件放到另外一个服务器上。例如,假设应用程序允许用户输入数据,经处理后再送往数据库,而此时系统又很繁忙,经常在传送数据时出现瓶颈,一种缓解此问题的方法是将MSMQ插入此进程中。一般地,你的应用程序将从用户那里收集到信息,通知用户正在执行,然后将信息送进MSMQ。应用程序能在队列的另一端取出信息,并更新数据库。这种应用程序的性能将会是相当不错的,因为用户无须等待数据库更新。但是这种结构只有在应用程序支持一种无连接操作的架构时,才行得通。