动态 Web 应用程序的体系结构决策:性能、可伸缩性和可靠性(摘自MSDN)

 

动态 Web 应用程序的体系结构决策:性能、可伸缩性和可靠性

Gregory Leake
Microsoft Corporation

2000 年 11 月

摘要:本文讨论 Doculabs 对 Windows 2000 进行的基准测试,说明不同的体系结构决策如何影响 Web 应用程序的可伸缩性和性能。其中包含对各种部署选项和配置设置的基准测试。

在 MSDN Online 代码中心浏览或下载 Nile.com 代码示例(英文)。

单击此处下载 Nile.com 代码示例(英文)。

目录

简介
Nile 应用程序
测试平台
使用 Active Server Pages 的 Visual Basic 应用程序
完全 ASP 实现方案
Visual C++/ISAPI/COM+ 实现方案
测试
结果
使用/不使用 COM+ 的性能对照
进程隔离级别和性能
通过 Windows 2000 网络负载平衡向外扩展
组件负载平衡
智能划分
引入 COM+ 事务之后的效果
动态 SQL 与存储过程对比
向上扩展与向外扩展对比
总结和性能调整考虑

简介

近期,Microsoft 雇用 Doculabs 对 Microsoft Windows® 2000 作为电子商务应用的服务器平台进行了一系列基准测试。本文就 1999 年 7 月 PC Week 的文章“应用服务器评测”继续说明基准测试的发现。在早先的 Doculabs/PC Week 的基准测试中,运行在 Compaq Proliant 服务器上的 Microsoft Windows NT® 4.0 击败了七种运行在高端 Sun 服务器上的不同 Unix 应用服务器(包括 Sun Microsystems 的 iPlanet)。在 Microsoft 在 PC Week 可伸缩性基准测试中表现出众(英文)中可以看到 PC Week 上发布的最初测试结果。您也可以阅读 Doculabs 对 Windows 2000 的新测试报告:@Bench 测试报告:Windows 2000 的性能和可伸缩性(英文),由 Marianne Pendleton 和 Gautam Desai 撰写。此文章也包含在示例软件包中。

在基准测试之后,我们对不同观众演示了测试结果。观众的反映很好,但经常会提出这样一些问题:

  • 最初的结果是根据 Windows NT 4.0 得出的。Windows 2000 的进步有多大?

  • 我是否应该在 COM+ 组件中使用 Microsoft Visual Basic® 或 Visual C++®?

  • 我是否应该使用 ASP 或 ISAPI 来创建我的应用程序?

  • 管理状态并保持良好的伸缩性的最佳途径是什么?

  • COM+ 事务如何影响性能?

  • 我应该在进程中还是进程外运行应用程序?

  • COM+ 负载平衡对应用程序的可伸缩性有什么影响?

  • 应该使用动态 SQL 还是存储过程?

  • 如何使用网络负载平衡来提高可伸缩性?

  • 如何在负载很重的情况下使我的应用程序保持最高的可用性?

  • 向服务器中增加更多的处理器对性能有多少改善?

  • 我能得到基准测试的源代码吗?

本文将要解答这些问题。实际上,本文就是我们在许多技术活动(包括 Tech Ed 2000)所作演示的书面版本。本文的目的是说明不同的体系结构决策如何影响 Web 应用的可伸缩性和性能。本文中包含了一些不属于 Doculabs 正式报告的数据,因为我们想花一些额外的时间来对不同的部署选项和配置设置进行基准测试,以便回答上述问题。Doculabs @Benchmark 应用程序的完整源代码包含在示例中。

Nile 应用程序

Doculabs @Bench 基准测试应用程序名为 Nile,模拟一个在线书店。我们使用三种方式实现了此基准测试应用程序(按照 Doculabs 所指定的功能):使用 ASP 页和 Visual Basic,完全使用 ASP,或者使用 Visual C++ 以及 ISAPI 和 COM+ 组件。

Nile 应用程序是一个很简单的 Web 应用程序。所有基准测试应用程序都是典型的简单应用程序,用来测试基础技术底层结构处理真实应用程序负载的能力。当然,真实的应用程序要复杂得多,并可以和内部的旧式系统进行典型的协作通信,其逻辑比 Nile 中的逻辑更复杂。但 Nile 还是有用处的。它突出了应用程序服务器处理数据库通信、动态页面生成和事务的能力。这些都是应用服务器产品的日常任务。

从功能上看,Nile 应用程序是基于 TPC-W 的一个松散的程序,TPC-W 是事务处理性能委员会 (TPC) 关于电子商务基准测试的新标准。Nile 应用程序是一个简单的在线书店应用程序,强调将应用服务器用作产品目录、相关产品搜索、产品浏览、客户帐户管理、购物车和订单事务。在基准测试中,90% 的页面都是根据数据库内容动态生成的。Doculabs 指定使用该应用程序,这意味着我们必须遵循许多规则,这些规则限制了使用真实应用程序中已经应用的某些更高级技术。例如,即使某些页面调用某些级别的缓存,也不缓存数据库信息。另外,必须在中间层或数据层上对状态进行管理,即使用单个 Cookie 将客户端会话映射回各自的购物车。最后一点,此应用程序不考虑安全性。所有用户均为匿名用户,且不使用数据加密。在真实应用程序中,客户帐户页和事务页毫无疑问将使用 HTTPS。 

我们使用三种不同的体系结构来实现 Nile 基准测试应用程序:

  1. 由 ASP 页激活 Visual Basic 6.0 COM+ 组件。

  2. 用 Visual C++ 6.0 编写的由 Visual C++ ISAPI 通用接头激活的 COM+ 组件。

  3. 完全使用 ASP 页,而不包含已编译组件/代码。

示例中包含了这些应用程序的源代码和安装说明。

注意:   请参见 Nile.com:COM+ 实现方案(英文)以了解有关 Vertigo Software, Inc. 对 Nile.com 的 Microsoft 实现方案所作的修改的讨论。修改后的程序示例是使用 Microsoft Windows 2000 中的 COM+ 的多层 Web 应用程序。

测试平台

测试平台包括下列硬件:

  • 一台 Compaq Proliant 8500(八个 550 MHz Pentium III 处理器,2 MB L2 高速缓存,3 GB RAM),使用 SQL Server 7.0 数据库

  • 四台 CMPQ 8500 Web/应用服务器(均为八个 550 MHz Pentium III 处理器,2 MB L2 高速缓存,512 MB RAM)

  • 五台 CMPQ 1850 Web/应用服务器(均为两个 550 MHz Pentium II 处理器,512 KB L2 高速缓存,512 MB RAM)

  • Cisco 千兆网络主干

  • 100 台 Dell 客户端工作站(一个 500 MHz CPU,128 MB RAM),用来产生负载,运行 Windows 2000 Server

图 1:Microsoft @Bench 测试实验室

使用 Active Server Pages 的 Visual Basic 应用程序

在 Visual Basic 实现方案中,我们使用了大多数企业开发人员在 Microsoft 开发平台上使用的各种核心 RAD 技术:Active Server Pages、Visual Basic 6.0、COM+ 和 ADO 2.5,用以进行所有数据访问。我们使逻辑保持极度简单,因此没有复杂的技术,诸如在数据层和表示层使用 XML 和 XSL。您看到的应用逻辑可能类似于现在 Internet 上基于 Microsoft 的多数企业 Web 应用程序。特别要说明,Visual Basic 实现方案具有下列特性:

  • 使用 COM+ 的逻辑化三层实现。

  • ASP 激活用 Visual Basic 6.0 编写的 COM+ 组件。

  • 不使用 IIS 会话对象。

  • 使用 Cookie 存储从数据库标识种子生成的客户端 sessionID(会话标识)。

  • COM+ 组件为所有数据库逻辑使用 ADO 2.5。

  • 没有数据缓存。

  • ASP 从 COM+ 组件取回断开连接的记录集以进行格式化或显示。

  • 使用正确的 ADO 编码技术;数据库索引被高度优化;为所有 SQL 使用 SPROC。

完全 ASP 实现方案

完全 ASP 实现方案的代码与 Visual Basic 实现方案完全相同,但它完全是用脚本编写的,并使用 VBScript 类文件来代替已编译的 COM+ 组件。该方案的目的是展示使用脚本相对于已编译 COM+ 组件的性能损失。该体系结构仍旧是三层的,所有数据访问都使用单独的类文件,而不是业务和表示逻辑。但是,由于所有工作都在脚本中完成,其部署选项少于 Visual Basic/COM+ 版本中的选项。例如,该实现方案不能利用 COM+ 动态负载平衡、COM+ 安全性机制等等。

Visual C++/ISAPI/COM+ 实现方案

此实现方案与前两个示例完全不同。它的目的纯粹是性能方面的,而不是进行 RAD 开发。我们希望显示出 Visual Studio 6.0 开发工具的灵活性,让开发人员编写低级代码以获得可能的最高性能。此代码编写起来比较困难。但有一个好消息,Visual C++ 组用它作为练习来帮助设计 Visual C++ .NET。现在,Visual C++ .NET 附带了名为活动模板库 (ATL) 服务器的新功能,它将彻底简化使用此类体系结构开发应用程序的过程。 

该体系结构使用了瘦 ISAPI 层(激活 Visual C++)和 COM+ 组件(执行所有工作/数据访问)。数据访问没有使用 ADO,而是使用 ODBC API。

如您将要看到的那样,此应用程序的性能特性与 Visual Basic/ASP 和完全使用 ASP 的版本明显不同。主要原因有三点:

  1. 使用 ISAPI 而不是 ASP 作为对 IIS 的低级扩展。在此应用程序中没有激活的服务器端脚本引擎。

  2. 使用 ODBC API 而不是 ADO 进行数据访问。ADO 是一个很好的数据访问包装程序,节省了许多手动编码工作,但是作为一个抽象层,它增加了某些开销。

  3. 使用 Visual C++ 而不是 Visual Basic。C++ 代码完全是低级语言,更接近于已编译格式的机器代码。尽管如此,要牢记 Visual Basic 也被编译为本机代码(从 Visual Basic 5 以来一直如此)。不过已编译格式的 Visual C++ 代码的执行效率更高。

当然,所有这些决策要在必要的开发技能和构造应用程序所需的时间之间取得平衡。我想强调一下 Visual Basic 和完全 ASP 应用程序,虽然它们没有 Visual C++ 应用程序快,但通过服务器群集也能达到我们意想不到的速度和卓越的可伸缩性。事实上,我们会毫不犹豫地将 Visual Basic 和 ASP 应用程序放到任何或所有运行在最昂贵的 SUN 设备上的非常高端的 UNIX 应用程序服务器上。Visual Basic 和 ASP 技术将满足 Web 上绝大多数电子商务应用程序的性能和可伸缩性需求。

Visual C++ 实现方案是 Doculabs 在 PC Week 的基准测试的最初 C++ Nile 应用程序的一个改写版本。在最初的实现方案中,所有代码都包含在一个 ISAPI DLL 中,是单一的两层结构。新的 COM+ 应用程序在这一点上更高级,它是一个逻辑化三层体系结构,更易于维护,并提供了更多的部署选项,例如使用组件负载平衡和 COM+ 事务。

测试

在看到真实的基准测试结果之前,有重要的几点需要注意。首先,我们使用 Quest Software 的 Benchmark Factory 来生成负载并测量性能结果,并在可靠性测试中追踪错误率。要记住,Doculabs 执行重要的测试并审核结果,但是用来显示体系结构平衡的后续测试是由 Microsoft 自己在相同实验室中完成的。

Benchmark Factory 的负载特性与 Microsoft 自己的 Web Application Stress 工具类似。这表明相对较少的客户端能轻易地在系统上产生巨大的负载。为确保安全,我们使用了 100 台客户端计算机,并确保这些客户端不会成为测试中的瓶颈。为了最大程度地增加系统负载,我们“毫无停顿”地运行所有测试,就象 Doculabs 最初的 Windows NT 4.0 测试(发布于 PC Week )和 2000 年 8 月的 Windows 2000 Advanced Server 重新测试一样。当您查看结果时,牢记这一点非常重要。测试中的一个虚拟“用户”实际上等于许多个“真实”用户访问服务器。据 Doculabs 估算,在不停顿情况下的一个用户相当于在页面请求之间有正常用户延迟情况下的至少十个真实用户。但这只是粗略的估算。100 台客户端计算机上的 Benchmark Factory 向服务器上增加的负载应该比绝大多数 Internet 站点将要经受的负载还要大。

结果

图 2 描述了最初 Doculabs/PC Week 评测的结果,我们在 Windows NT 4.0 上运行 Nile 应用程序,分别在 Visual Basic/ASP 中和在 Visual C++ 中作为 ISAPI 应用程序进行测试。在此测试中,Nile 直接与运行在高端 SUN 服务器上、使用 Oracle 8i 数据库、基于 Java 的应用程序服务器比较。Microsoft Nile 组则使用 SQL Server 7.0 数据库。

图 2:最初的 Unix 与 Windows NT 大拼比

此测试是在一年前进行的,那么现在又有了哪些影响性能和可伸缩性的改进?主要的变化有两个,其一是使用了 Windows NT 4.0 的换代产品 Windows 2000,其二是使用了具有更快的 Intel Pentium 芯片的新型八路系统。这两个要素一起使得性能大大增强,下面显示的是 2000 年 8 月 Doculabs 对 Microsoft Nile 应用程序重新测试的结果:

图 3:Unix 与 Windows NT 的重新测试比较

下面的图表显示向系统中增加用户时,每个受测应用程序的完整的相对吞吐量曲线。请记住后端硬件和操作系统都已升级,以便达到最佳的结果。硬件从带四个 500 MHz CPU 的 Compaq ProLiant 6400R 升级为带八个 550 MHz CPU 的 Compaq ProLiant 8500。操作系统从 Windows NT 4.0 Enterprise (Service Pack 5) 升级为 Windows 2000 Advanced Server。

图 4:最初 Windows NT 4.0 结果与 Windows 2000 重新测试结果 (Visual Basic-COM+/ASP)

图 5:最初 Windows NT 4.0 结果与 Windows 2000 重新测试结果 (Visual C++/ISAPI)

下一组数据显示相同的硬件环境下 Windows NT 4.0 与 Windows 2000 Advanced Server 的完整重新测试结果。它真实对比了这两个操作系统运行 Nile 应用程序的相对性能差异。该数据显示对于 Visual Basic/ASP 和 Visual C++/ISAPI,在较高负载情况下,Windows 2000 的吞吐量都比 Windows NT 4.0 高约 30%。但是请注意,完全 ASP 版本(在最初 Doculabs/PC Week 评测中没有测试)的测试结果更加惊人:Windows 2000 比 Windows NT 4.0 高约 100%。产生此差异的原因在于对 ASP 脚本引擎使用了 IIS 5.0 和 ADO。

图 6:Windows 2000 Advanced Server 与 Windows NT 4.0 (Visual Basic-COM+/ASP)

图 7:Windows 2000 Advanced Server 与 Windows NT 4.0 (Visual C++/ISAPI)

图 8:Windows 2000 Advanced Server 与 Windows NT 4.0 (完全 ASP)

有关以制表符分隔的数据列表,以及 Doculabs 在 Windows 2000 和 SQL Server 7.0 上进行故障转移/可靠性测试的完整讨论,请参见 Doculabs 的正式报告。

使用/不使用 COM+ 的性能对比

后面的数据都是在 Windows 2000 Advanced Server 上得到的测试结果,该测试是 Microsoft Nile 组使用相同的设备自己测试得出的,用以说明不同体系结构和部署选项之间的对比。

图 9 显示了 Visual Basic/ASP/COM+ 实现方案与完全 ASP 实现方案的性能比较。

图 9:完全 ASP 版本(VBScript 类)与使用 Visual Basic/COM+ 组件的 ASP

图 9 显示出某些有趣的发现。首先,在 Windows NT 4.0 下,我们对开发人员的建议是:已编译的 Visual Basic 代码的性能比脚本代码高。同时,通过向 COM+ 组件中放置逻辑,开发人员可以更好地避免剖析长而复杂的 ASP 页的“混乱代码”。但是,完全使用 ASP 实现方案的 Nile 在 Windows 2000 上的实际执行情况和已编译 COM+ 版本一样好(甚至更好)。这说明,在 Windows 2000 上,您不再需要为使用脚本而付出性能代价,就可以获得和使用已编译 Visual Basic 代码一样的效果。ASP 脚本引擎在 Windows 2000 上运行更快。另外,我们使用 VBScript 5.0 的新功能来创建使用类定义的对象,这样,代码就象 Nile 的 Visual Basic 6.0 版本一样简洁。实际上,它的代码是相同的,但是使用了 VBScript 类,而不是 Visual Basic 6.0 类模块中定义的 COM+ 对象。当然,完全 ASP 版本不能利用 COM+ 的特性,例如安全模型、组件队列以及动态负载平衡。另外,许多大规模的站点需要使用脚本,因为脚本便于灵活地升级逻辑,不存在组件版本管理和在产品站点上重新注册所带来的问题。有一个好消息,这些选项不再互相排斥。您可以将经常更改的逻辑保存在脚本中,将已固定的逻辑保存在封装的 COM+ 组件中。

图 10:Visual C++:从单一 ISAPI 移至 n 层 COM+ 组件

图 10 显示了 Visual C++ 应用程序的相似结果。从根本上说,最初的 Nile 应用程序是两层单一 ISAPI DLL,我们将其转为带 ISAPI 层的 COM+,仅从 Web 站点激活 COM+ 组件。基本情况是使用 COM+ 不会带来任何严重的开销,并且两个应用程序的性能非常接近。

进程隔离级别和性能

在部署任何 Web 应用程序时必须回答的另一个问题是有关进程隔离的问题。我们在各种进程隔离级别上对 Visual Basic/ASP/COM+ 应用程序进行了测试,以便说明此决策对性能的重大影响。结果表明,基于 ASP 和 COM+ 的 Web 应用程序的默认的现有进程隔离级别并不理想,应尽可能进行调整。

进程隔离是指将运行代码划分到由操作系统管理的不同进程空间中。其基本用意是在 Windows 2000(和 Windows NT 4.0)下,某个进程崩溃时不会影响另一个进程。例如,如果某个 ASP 应用程序是与 IIS Web 服务器 (InetInfo.exe) 进程隔离的,则该应用程序崩溃时,计算机上的 Web 服务器仍然为其它站点提供页面——因此不会出现系统范围的崩溃。但是,进程隔离的缺点是降低了性能。在一个应用程序中跨越进程边界的代价很高。数据封送将产生大量开销,并导致大量 CPU 上下文切换。在 Windows NT 4.0 下,这个代价很高,因此所有新建的 ASP Web 应用程序的默认设置都是在与 IIS 相同的进程空间中运行。在 Windows 2000 下,ASP 应用程序的性能有了很大提高,因此操作系统改变了默认设置,使所有新建的应用程序都在与 Web 服务器不同的进程空间中运行。如果您正在对 Windows NT 4.0 和 Windows 2000 执行自己的性能测试,要牢记这一点,因为不能将 Windows 2000 的进程外(默认)和 Windows NT 4.0 的进程内(默认)作比较。

让我们看一看 Visual Basic/COM+/ASP 应用程序和进程隔离的三个基本选项。然后我们将讨论基于性能数据而建议的途径。Windows 2000 的第一个选项是将 ASP 应用程序的设置改回 Windows NT 4.0 的默认设置,使所有程序与 Web 服务器在同一进程空间中运行。这是最快、最简单的选项。该选项还要将所有 COM+ 应用程序的默认设置从服务器激活(所有 COM+ 对象的实例均使用独立的进程空间)改为库激活(在调用应用程序的进程空间中创建 COM+ 对象)。如果您的 ASP 应用程序和 COM+ 组件经过良好测试,并且该应用程序是计算机上仅有的应用程序,那么这是最佳选项,可以保持性能稳定并支持最大数目的并发用户。

图 11:单一进程选项的进程隔离

下一个选项是保留 ASP 应用程序的进程隔离的默认选项,但是将 COM+ 应用程序从服务器激活改为库激活。这意味着将在与调用 ASP 页面相同的进程空间中创建所有 COM+ 对象,但是 ASP 页面(以及 COM+ 对象)将与 Web 服务器进程隔离。这是比较安全的配置,但是也会降低性能,因为 IIS 必须在 ASP 和 IIS HTTP 服务器之间封送数据。

对于新的、测试相对较少的应用程序,或者对于运行多个站点和应用程序的服务器而言,这是一个很好的选项。该选项确保当某个应用程序崩溃时,Web 服务器能继续运行其他应用程序。COM+ 组件中的故障不会导致 Web 服务器自身瘫痪。

图 12:隔离 ASP/ISAPI 进程的进程隔离

最后一个选项实际上是调入 COM+ 组件的、新建的 ASP 应用程序的默认设置。在这里,ASP 应用程序被标记为进程外,COM+ 应用程序(COM+ 组件的容器)被标记为服务器软件包。但是在此选项中,您可以看出进程实际上已经分解。每个 ASP 调用都跨越进程边界,每个激活的 COM+ 组件都跨越另一个进程边界。这带来了大量的开销,对于绝大多数站点而言,是无法容忍的。

图 13:用 ASP/ISAPI 进程隔离和 COM+ 进程隔离来进行进程隔离

给出这些选项后,下面提供 Nile 应用程序在每个进程隔离配置下的性能数据。此数据是在一台独立的 Compaq ProLiant 8500 上得出的。

图 14:Visual Basic/COM+ 和 ASP 进程隔离变化

很明显,进程隔离策略对性能造成重大影响。

通过 Windows 2000 网络负载平衡向外扩展

负载平衡是 Doculabs Windows 2000 测试的一个重要环节。负载平衡允许某个站点在一个服务器集群上“向外扩展”,这样就可以通过在后端增加更多副本服务器来轻松地提高容量。负载平衡还提供冗余,使站点具备故障转移能力,这样,即使后端的一台或多台服务器出现故障(或因维护而需要关闭)时,该站点仍然可供用户使用。在近期的应用服务器争夺战中,大多数应用服务器供应商、出版物和分析家都频频提及一个名为“动态负载平衡”的特性。但是,动态负载平衡是用在极少数大规模 Web 站点上的特性,而多数大规模站点进行向外扩展的主要途径还是使用更简单的网络级负载平衡。在这种网络级负载平衡中,外来的 IP 请求被简单地路由给副本服务器,然后基于其处理能力动态分布逻辑,而不是试图获得应用程序中的单个组件。为什么这项技术应用更广呢?因为网络负载平衡 (NLB) 简单,易于设置,并能顺利地完成任务。另外,多数应用服务器使用专门的黑盒算法在多个应用服务器上分配负载,有些算法能很好完成任务,但许多则不能完成。设置和维护这样的数据中心可能需要讨论,特别是当分配/路由逻辑十分复杂,并且可能在系统中产生瓶颈的情况下。 

在后端服务器的群集上分配负载时,网络负载平衡比动态的组件级负载平衡更为通用。它既可以通过提供 NLB 的硬件解决方案(例如 CISCO Local Director)实现,也可以通过软件解决方案(例如简单的循环 DNS)实现。完善的解决方案不存在单点故障。简单的循环 DNS 易于使用,但并不完美,因为如果群集中的一台服务器出现故障,外来的请求仍被路由给该服务器。因此,如果您有三台服务器,而其中一台被关闭,则客户端上的三分之一请求将出现故障。Windows 2000 Advanced Server 内置了 NLB 服务,在进行任何 Web 站点设计(Intranet 或 Internet)时,都应该考虑这一重要特性。通过 Windows 2000 NLB 服务,您可以轻易地将所有外来的网络请求分布到后端服务器的群集上。该方案不存在单点故障。一个服务器关闭后,所有请求立即被转移给其他可用的服务器,这些工作可在一秒以内完成。在 Doculabs 的基准测试中,我们使用 Windows 2000 NLB 作为服务器的主要负载平衡机制,在四台服务器(测试的最大数目)上为 Visual Basic 应用程序提供了线性扩展(并在可靠性测试中进行故障转移)。

NLB 为 Visual C++ 应用程序提供了两台服务器上的线性扩展,但因为 Visual C++ 应用程序每秒处理的动态页面更多,所以数据库负载级别更高。因此,如果在中间层的两个服务器上添加第三台和第四台服务器,在吞吐量性能方面的收益将递减。此时,SQL Server 7.0 数据库的 CPU 使用率超过 85%,而关键因素也不再是中间层,而是数据库。继续扩展 Visual C++ 应用程序的唯一途径是将负载分配到多个数据库服务器上。请看下面的数据:

应用程序 一台服务器上的最大吞吐量 四台服务器上的最大吞吐量
Visual Basic/COM+/ASP 每秒 987 页 每秒 3,865 页
Visual C++/COM+/ISAPI 每秒 2,943 页 每秒 8,452 页

形象地说,每秒 8,452 个页面等于每天处理 730,252,800 个页面,即 Internet 业务量最大的站点 Yahoo 在繁忙时全天业务量的两倍。在基准测试中,90% 的 Nile 页面涉及到数据库请求,且没有中间层缓存。在这种情况下,一个 SQL Server 7.0 数据库服务器就可以完成任务。当然,Nile 是一个非常简单的应用程序,但它可以解释,为什么在 TPC-C 最佳结果中涉及绝对性能的前六项中,SQL Server 占据四项,其中包括绝对性能第一名。

要进一步向外扩展 Nile Visual C++ 应用程序,需要在多个服务器上对数据库进行划分,或者通过“向上扩展”的途径来完成,即在更快的计算机上运行 SQL 数据库,例如在新型的 Compaq 和 Unisys E7000 上,这些计算机支持最多 32 个 CPU。同时,使用 SQL Server 2000 中的新特性分布式分区视图 (DPV) 可以进一步扩展,方法是在并行工作的多个后端服务器上划分某些数据库表。

组件负载平衡

Windows 2000 Advanced Server 提供了网络负载平衡,而 Application Center 2000 将使用组件负载平衡 (CLB),它是动态的负载平衡,用于应用程序中的独立远程 COM+ 组件。此特性非常有用,因为它为组件的远程处理提供透明编程。使用 COM+ 来创建逻辑 n 层应用程序的一个原因是:在部署物理两层或物理 n 层数据中心体系结构方面,它能为您提供更大的灵活性。换句话说,您可以在本地调用的 Web 服务器上运行 COM+ 组件,也可以将 Web 服务器以外的某些或所有组件分布到应用服务器的专用层上。

但是,最主要的原因是,从 Web 服务器上以进程外方式运行组件将降低性能,同样,在 Web 服务器以外远程管理组件也降低性能,因为由每个组件交互和跨网络 COM+ 数据封送都将产生额外的网络跃点。然而,许多客户出于不同原因仍需要在 Web 服务器以外远程管理逻辑,包括在 Web 服务器和接触被保护的子系统(诸如 SAP R/3 等内部 ERP 系统,以及客户数据库等)的组件之间加入额外防火墙的能力。

我们让 Doculabs 在 Nile 应用程序上执行了测试,使用三层物理数据中心体系结构来测量远程管理 COM+ 组件的性能影响。图 15 说明,Visual C++/ISAPI/COM+ 应用程序在 Web 服务器上以进程内方式运行所有 COM+ 组件时与通过网络远程管理单一应用服务器上的所有组件时存在明显的性能差异。现在,如果引入更多服务器,吞吐量曲线将得到改善(在这种情况下,瓶颈是单一应用服务器)。但是,要想获得与本地、进程内组件相同的性能级别,则需要更多的硬件。

图 15:Visual C++ COM+ 对象的本地和远程管理

智能划分

我们是否应该在 Web 服务器以外远程管理所有组件?这个关键问题的答案是否定的。实际上,如果在您的数据中心和应用程序自身中正确设置了安全性,在 Web 服务器以外远程管理单独的 COM+ 组件没有安全性优势。但是请考虑构成 Nile 应用程序的组件并引入应用逻辑的“智能划分”观点。实际上,Nile 应用程序访问的绝大多数组件都与服务器上的 GUI 型操作有关——根据目录浏览、相关产品搜索等的结果动态生成 HTML 页面。这些是只读操作,一般适用于只读的产品目录(可更新的主目录可能是不在 Web 上发布的内部系统)。

Nile 应用程序中的其他组件则接触更为敏感的数据库信息。例如,处理对客户数据库交互(读和写)的组件,或执行实际订购事务的组件。如果安全性是使用 Web 服务器外远程管理逻辑的主要原因,请考虑划分您的类文件,这样就可以远程管理真正需要的组件,而不用远程管理所有组件(包括只是用来生成 HTML UI 的简单组件)。对于 Nile 和多数其他应用程序,有三个因素使得智能划分和“选择性远程管理”非常重要:

  1. 大多数组件涉及到生成 UI 以将许多数据传回客户端,从数据库获取产品信息,生成后续 HTML,然后将其传回给 Web 服务器以便发回到客户端。远程管理这些组件将带来许多数据封送开销,并对性能造成极大影响。

  2. 另一方面,用于更新客户记录或进行定购的组件往往不向客户端传回大量数据——可能会传回某种订单确认号,但没有大量要显示的数据记录。远程管理这些组件不会对性能造成相同的影响。

  3. 如果您看一看典型 Web 站点的访问模式,就会发现绝大多数访问都是查看页面以进行产品浏览、搜索等,而进行订购或更新重要客户信息的页面访问量很少。

结合这三点可以得出结论。您可以适度地远程控制接触系统敏感部分的组件,而不会像远程管理 GUI 组件那样付出很大代价。我们之所以要远程管理这些组件,还因为它们经常长时间运行,与多个内部系统接口,同时还可以降低 Web 服务器自身的某些处理负担。

对于 Nile,我们以这种方式智能地划分代码,然后应用特定的规则来决定是在 Web 服务器上单独运行这些组件,还是使用 CLB 在应用服务器的专门群集上运行。首先,如果该组件执行任何事务/写入数据库,则对其进行远程管理。其次,如果组件接触(读或写)任何客户数据库,则对其进行远程管理。如果该组件仅仅接触只读产品数据库以便响应浏览和搜索请求,则可以将其保持在本地运行,作为 Web 服务器的扩展。在基准测试中,Doculabs 混合使用了六种不同的用户配置,用以代表电子商务站点的典型使用模式:某些配置进行浏览/搜索,某些配置进行定购,某些配置创建或更新客户帐户,某些配置则执行不同的混合操作。图 16 是智能远程管理的应用程序与全部本地运行的应用程序的性能对比图表:

图 16:智能远程处理和全本地运行 COM+ 对象

可以看到,与远程管理系统中的所有组件相比,智能远程处理的影响很大。此测试的目的就是让您仔细考虑远程管理组件的原因,并明智地决定哪些组件需要远程管理,哪些组件要保持本地运行。

我们最后测试的配置为多个 Web 服务器以及运行在智能远程管理配置(上述每个标准)中的多个专门应用服务器。我们采用一系列 Compaq ProLiant 1850r 服务器,作为 Visual Basic/COM+/ASP 实现方案的前端 Web 服务器后的专用应用服务器运行。在这种情况下,所有 Compaq Proliant 8500 都通过 NLB 组成群集,作为到应用服务器的冗余 COM+ 路由器,没有单点故障。1850r 服务器使用 CLB 组成群集,仅仅用于运行在 Web 服务器以外分布的 COM+ 组件。同时,此层上没有单点故障,因为与 NLB 一样,CLB 能够在应用层中的一台或多台服务器停机时提供故障转移。下面是结果:

图 17:智能分布和全本地对象

请注意,分布式组件负载平衡配置的吞吐量曲线下降得比全本地配置要快。这是由于应用层(1850r 服务器)在超过一定点后就达到饱和。添加更多的专用应用服务器可使这条蓝线变得平直,并与全本地吞吐量曲线保持一致。但是,这需要在应用层中添加更多硬件。

引入 COM+ 事务之后的效果

COM+ 提供的主要服务之一是对组件间分布事务的支持。给出 Nile 性能数据以后,我们经常听到这样的问题:“进行基准测试时,事务是打开还是关闭的?”答案是:对于最初的 PC Week 评测,事务是关闭的,因为它不是一个基准测试标准,并且其他供应商的应用程序中也没有事务处理 (TP) 监视器。

让我们来看一看,如果在 Nile 应用程序中打开对 COM+ 组件的事务支持,将这些组件标记为“要求事务”,那么会发生什么。这种情况下,对每一个组件调用,它都将调用 Microsoft Distributed Transaction Coordinator。可想而知,这将为系统添加开销。回到有关基于智能划分的远程管理组件的讨论,对于事务支持的问题,其逻辑是类似的。Nile 中的所有组件都涉及真正的数据库事务吗?回答是否定的。实际上,没有任何组件真的需要 COM+ 事务支持,因为应用程序中的事务很简单,仅针对单个数据库,可以很容易地在存储过程中直接进行处理。但是,我们进了一步,以智能方式划分了 Nile 的逻辑,从而能够为所有对订单和客户数据库执行写操作的组件启用事务支持,但仍关闭对执行简单选择语句的组件的事务支持。图 18 显示了这种策略的效果:根据情况智能地使用事务,而不是盲目为系统中的所有 COM+ 组件打开 COM+ 事务。图 18 以运行在一台 Compaq ProLiant 8500 Web/应用服务器上的 Visual C++ 应用程序为例。

图 18:智能地使用 COM+ 事务

另外,您还要仔细考虑哪些组件需要事务支持,并智能地划分您的类文件以便可以有选择地将组件标记为“要求事务”。

动态 SQL 与存储过程对比

如果预先知道 SQL 语句(而不是在运行过程中由使用/应用逻辑动态构造),我们建议在绝大部分情况下都使用存储过程。使用存储过程,而不是在应用程序中直接嵌入 SQL 字符串,这使系统更易于维护。同样,SQL Server 将有一个预编译的查询计划,按照这个计划执行的速度比动态 SQL 快。图 19 用图表对比了 Nile ASP 应用程序使用全动态 SQL 与存储过程的不同情形:

图 19:对 Nile ASP 应用程序使用全动态 SQL 和存储过程

向上扩展与向外扩展对比

最后,我们分别在八个 CPU 和四个 CPU 的 Windows 2000 系统上运行 Nile 应用程序,测试向上扩展带来的影响。图 20 中的数据表明了一个关键问题——不能期望系统添加了处理器后性能会有线性增长。向外扩展(添加副本计算机)通常比向服务器添加更多处理器的效果更好。但是,向上扩展和向外扩展都非常重要。通过向上扩展,您可以显著减少处理用户负载所需的服务器数目,因而降低了数据中心中的管理成本。另一方面,通过向外扩展,您能够以较低成本获得大幅扩展,以及对高可用性站点的故障转移支持。通过新的 Windows 2000 Data Center Server,可在最多 32 个 CPU 的系统上运行,并可将一些 CPU 专门分配给某个应用程序,从而使服务器获得更好的稳固性。另外,如果某个应用程序的 CPU 利用率达到饱和,Windows 2000 Data Center Server 可以自动重新配置处理器,为该应用程序分配更多的 CPU。

图 20:从四个处理器扩展到八个处理器的 Windows 2000 系统

总结和性能调整考虑

下面列出了一些最重要的步骤,在创建和调整 Nile 实施方案时需要执行这些步骤:

  • 加上负载,测试和调整应用程序。
    • 确定性能目标。

    • 发现和消除瓶颈,直至达到目标。
  • 数据库调整最为重要。
    • 适当的索引非常关键。

    • 监视 SQL Server CPU 利用率。它在中度负载情况下应较低,轻度负载时则应很低。
  • 适当配置数据库(例如,根据事务记录,使各 RAID 控制器并行操作,并为数据隔离各个设备)。

  • 使用无状态数据库操作并始终使用断开连接的记录集。

  • 使用适当的 ADO 编码技术(请参阅 MSDN 上的 FMStocks 2000 和 Nile 示例):
    rs.CursorLocation = adUseClient
    rs.Open cmd, , adOpenForwardOnly, adLockReadOnly 
    
  • 避免:
    • 单行记录集(用尽参数),adExecutenoRecords。

    • 大记录集(数百条记录可以,数千条则不行)。
  • 在进程内或以进程隔离的形式运行 ASP 或 ISAPI,但尽可能在进程内运行 COM+ 软件包(库软件包)。

  • 使用 Windows 2000 网络负载平衡。

  • 不要盲目地用 CLB 分布所有 COM+ 组件,而是使用智能准则。许多对象并不需要分布,包括那些只涉及只读数据的 UI 对象。

  • 合理使用 COM+ 事务。

  • 关闭不使用的 COM+ 特性,例如事件和状态、同步、事务和 JIT。

  • 不要过分寄希望于中间层缓存。它们可能不是必需的。

  • 对于用户状态,尽可能使用数据库或客户机程序,避免使用 IIS 会话对象和应用程序对象。

  • 对长时间运行的操作,如订购和与老式系统交互,请使用异步操作(COM+ 松耦合事件,消息队列)。

你可能感兴趣的:(ASP.NET)