下载第26章 优化ASP的性能有些性能指标,例如正确性,是只有在其不出现时才被人们注意到的品质特征。如果能努力地改正网站中的所有错误,并不断提高其工作性能,那么其用户很少会提意见。如果网站存在少量错误,或者是运行缓慢,那么其用户们会产生抱怨。
本章将介绍与 A S P工作性能有关的几个重要概念,提供一些优化 A S P工作性能的方法和应注意的事项。
本章的主要内容如下:
以处理速率和响应时间衡量性能指标。
硬件的性能。
脚本优化。
NT Performance Moniter 和 Web Application To o l( WA S)等工具。
会话和应用程序状态。
进程隔离、组件和线程模型。
最后,我们用一些综合技巧结束本章的内容,这些技巧在实践中行之有效,而且可以用来改善网站性能。首先,让我们考虑一下应该用什么样的尺度来衡量 A S P的工作性能。
26.1 衡量工作性能的标准在研究如何提高 ASP 的工作性能之前,我们需要来理解两个基本的指标:吞吐量和响应时间。
吞吐量( T h r o u g h p u t),是指服务器处理请求的速率。从网络管理员的角度来看,可以实现的吞吐量越高越好。如果能够提升网站潜在的吞吐量,就可以应付日益增加的用户请求;
就能处理更多的事情;而且也可以因此推迟升级服务器的硬件。
响应时间( Response Ti m e),是指从客户开始提出请求到接收到响应最后一个比特之间的时间。响应时间越短越好。用户很在意响应时间,对全系统的吞吐量不太关注。
26.1.1 吞吐量吞吐量通常用每秒或每天的请求次数来衡量。有时,使用页请求数比使用请求次数更有意义。当浏览者要求得到一个 H T M L页面时,一般会紧跟着发出与图片和网页有关的独立请求,其中图片一般都标有 < I M G >的标记。这些紧密联系着的请求被视为一个页面请求。
另一个近似衡量吞吐量的方法是客户数量除以客户的“思考时间” 。例如,假如有 1 0 0个客户,平均每人用 2 0秒阅读一个网页,那么吞吐量就是 1 0 0 / 2 0,或者说是每秒回答 5次。吞吐量并非表示阅读一个网页需要的时间,表明请求多快才能到达服务器,服务器要多久才能对它们做出响应。
吞吐量受许多变化因素影响。其中之一就是带宽,带宽是用来计量每秒能够传输多少数据的物理量。如果使用一条 I S D N线来连接到 I n t e r n e t,那么由于 I S D N很容易饱和,相对较低第 26章 优化 ASP 的性能 计计 783下载的带宽将成为限制性能的主要因素。带宽是限制网络服务器向用户快速传递内容的一个主要因素。
网页尺寸( Page size)同样影响吞吐量。传递的网页越大,每页花费的时间越多,每秒可以传递的网页越少。如果可以减少网页的尺寸(尤其是嵌入式图片的尺寸,这些图片往往是最大的文件),不仅可以提高吞吐量,而且减少了响应时间;也就是说,客户看到完整一页所需的时间更少。
复杂的应用程序( Complex application)会降低吞吐量。如果每一个请求都需要花费较长的时间来执行,那么每秒可以处理的请求数就比处理简单的申请时少。对于动态内容来说,
C P U的性能是影响吞吐量的主要因素。
在速度较快的局域网上,H T T P的连接是几乎瞬时完成的。但是,在相对较慢的广域网上,
例如 I n t e r n e t,它的连接就需要几秒钟。同时,由于每一个连接都要使用服务器资源,所以并发连接个数成了重要的指标。
有两种方法测量吞吐量:
一是使用性能监视器( Performance Monitor)来读取由网络服务器产生的吞吐量统计数据。
对于静态文件来说,N T性能计数器为 Web Service (_Total) | Get Raquests/sec;对于 A S P来说,
N T性能计数器为 Actire Server Pages | Requests/sec。本章的后面将详细讨论性能计数器。
二是使用装载产生工具,例如 WA S。在运行了一个特殊的测试程序后,WA S将报告吞吐量和许多其他的统计数据。
26.1.2 响应时间用户希望响应时间少于一秒,但是却很少能够实现。人们经常半开玩笑地称 W W W是
“世界范围内的等待( Wo r l d - Wide Wa i t),。响应时间取决于网络延时、请求在服务器端排队的时间及服务器处理请求的时间。
WAS 提供获得第一个比特的时间( T T F B)和获得最后一个比特的时间( T T L B)
的统计纪录。
网络延时是一个数据包从一个地方传送到另一个地方的时间,它受以下几个因素的影响:
网络拥挤度、链路的质量、链路的带宽、链节点间的物理距离,与目的地之间的中继站或区域的个数和在路由器和网关的等待时间。
延时既受到请求从客户端传递到服务器端的时间的影响,也受到从服务器端到客户端返回响应的时间的影响。在大多数情况下,响应时间既不受客户控制也不受服务器控制。
窄带设备,例如调制解调器,延时更长。相反,宽带设备通常延时较少,不过并非总是如此。两个通过微波、卫星连接的系统,每秒可以传递几百万比特的数据,但如果仅把单个数据从一个终端经卫星传送到另一个终端的话,花费的时间比在局域网内传输要长。
即使从客户端到服务器的延时为零,任何一个请求在排队等待接受服务器处理时仍要花费时间。请求排队时间取决于队列的长度和服务器处理每个请求的时间。队列的长度与服务器的负荷成比例。
请求执行时间是响应时间的最后一个组成部分。它是唯一的一个服务器可以控制的量。
较长的处理时间会减低吞吐量。减少执行时间是本章的主要任务。
业务量特性曲线另一个概念是业务量特性曲线,业务量曲线在一天内并不平坦。地区性的新闻网站在清晨、午饭时间和傍晚会有较重的业务量,但在半夜却非常闲,这时其主要读者已经睡着了。
在业务较重的时间,服务器可能要处理三到五倍于 2 4小时平均业务量的业务。新闻网站在发生突发新闻事件时会偶尔遇到尖峰业务量。
显然,一个 We b站点必须不仅可以处理平均业务量,也必须有足够能力应付一天中可能的高峰,而且它的速率最好能应付得了最高容量。
从长远角度看,应该建成一个可以适应日益增长的业务量的成功网站。不要让服务器超负荷运转。如果平均业务量占用了 C P U资源的 5 0 %,那就可能不能很好地应付业务量的高峰。
使用 NT Performance Monitor来了解站点的工作情况。 PerMon 可以把所有计数值记录到一个日志并在 NT 事件日志中报警。
26.1.3 衡量性能的其他指标如前所述,衡量工作性能最基本的标准是吞吐量(服务器每秒可以处理的请求数量)和响应时间(处理一个指定的请求有多快) 。作为一个网络管理员或者 A S P应用程序开发者,最关心的是使吞吐量最大,因为它既能够使网站可以处理更多的下载请求,还可以推迟升级硬件。与此不同,用户希望响应时间越短越好,因为他们已经厌倦了“世界范围内的等待” 。
其他的性能指标也是非常有用的。这些指标是兆赫费用、资源利用率和多处理器可扩展性。兆赫费用是一种估计执行一个动态网页有多“贵”的方法,而且它还能帮助你推断出通过改换不同的硬件可以得到的性能。使用的资源越少,可用空间就越大,而且对多用途的服务器来说,就越是好成员。在单处理器系统上开发的应用程序在多处理器系统中并不能自动地扩展。
1,兆赫费用兆赫费用使用每秒每个请求的兆赫值表示,即:兆赫费用 = CPU数量× C P U速度× C P U利用率 /每秒请求数。例如,如果一个双奔腾 I I服务器的工作频率为 3 3 3 M H z,系统可以利用 6 0 %
的 C P U资源稳定地工作在 8 0页 /秒的速度上 (由 Task Manager 或 Performance Moniter实测得到),
即:
总频率为 2× 333 MHz = 666 MHz,可利用的频率为,6 6 6× 0.60 = 400 MHz,因此,4 0 0
MHz / 80页 / 秒 = 5 ( M H z /每秒页),所以,兆赫费用为 5 MHz/每秒页。
兆赫费用与吞吐量等其他指标相比有一定的优点,它使得规划系统的容量变得相对容易。
例如,尽管系统 B与系统 A的硬件不同,假如两个系统的 C P U个数相同,并且一个页面的兆赫费用一定的话,则页面在系统 A与在系统 B运行的兆赫费用基本相同,只是在速度较快的机器会略高一点。
然而现在还不能把兆赫费用看得太重;它仅仅是一个估计值。对动态内容的处理能力还无法确定。
例如,网站上最高层的主页的兆赫费用为 3,搜索网页是 2 5,订单网页是 1 5。网站可承受的速率是每秒有 5 0个客户访问最高层的主页,一人在搜索,2人在下订单,同时还需有一些剩余能力用来对付业务高峰和满足其他网页的用户的要求。网站的兆赫费用多大才能满足需求?
784计计 ASP 3 高级编程 下载第 26章 优化 ASP 的性能 计计 785下载
( 5 0× 3) +( 2× 1 5) +( 1× 2 5) = 150 + 30 + 25 = 205 MHz
考虑到系统业务高峰时的冗余,至少要使系统的兆赫容量达到 3 0 0 M H z,才可以满足需求了。
建议系统的平均工作量不超过 C P U资源的 5 0 %,否则将不能很好地应付业务量的高峰。
这个网站的工作频率为 4 0 0 M H z是比较安全的。
2,降低 C P U的占用率很明显,C P U占用率越低越好。如果可以优化网页使其可以运行得更快且占用最少的
C P U资源,那么网站就有更多的能力来应付业务高峰。另外,对于运行在同一系统上的数据库和电子邮件服务器等其他服务来说,希望让给它们尽可能多的 C P U资源。
3,降低带宽的占用率即使是专用的网络服务器也不得不与其他系统分享网络资源。因此,应该尽可能地占用较少的网络带宽资源。这不仅仅意味着可以给其他系统留下更多的带宽,还可以使网络服务器达到更高的吞吐量和提供更短的客户响应时间。有三种方法可以实现这一目标:
第一种方法是为每个请求传递较少的数据。去掉 H T M L文件中的空格;发送一部分结果以代替整个结果;发送尽可能少的图片,并且通过剪切使图片尽可能小,或使用较高压缩比例的 J P E G和颜色较少的 G I F方式使图片变小。
第二种方法是减少客户与服务器在网络上的往返时间。服务器可以下载给客户的信息越多越好。往返时间经常由于网络的等待时间而变长,并由此增加了服务器的工作量,还占用了网络的带宽资源。优秀的客户可以用客户端脚本来验证数据;使用 D H T M L来改变显示器的显示图案而不用请求从服务器下载新的 H T M L文件或图片;用 R D S来巧妙地处理 A D O记录集;用 X M L来转换数据等。
第三种方法是数据缓冲。把数据寄存起来,然后一次性发出可以节约网络资源的占用。
IIS 4.0的缺省值并不缓冲 A S P动态网页,而 IIS 5.0的缺省值是缓冲 A S P动态网页。
每一个 R e s p o n s e,Wr i t e和 H T M L段分别传递给客户的。每个数据包内都加上了描述性的报头;每一次传递都需要花时间来完成;每一次传递都给网络增添了阻塞问题。这就像分几次从超级市场买回采购单上的物品而不是一次把所有的东西都买回来一样。 T C P / I P协议有一种慢开始的算法,它先传递一个数据包,然后是一次两个,再一次传递四个,如此下去,直到建立起最大的数据传输速率为止。如果一个网页被分割成许多小的部分来传送,T C P / I P对每次传递都有一个慢开头的数据流,而不是对整个数据仅用一个慢开头的数据流。当整个网页被缓冲后,T C P / I P会变得更高效,尤其是在等待时间较长的连接上。
4,多处理器的可扩展性理想情况下,在单处理器系统中增加一个处理器可以使吞吐量加倍,再加两个处理器可以得到四倍的处理性能。但是,实际中一个应用程序很难在多处理器系统上扩展。 IIS 4.0可以很好地出从一个处理器扩展到两个处理器,但超过两个就不行了。 IIS 5.0可以扩展到出 4个甚至是 8个处理器。
图 2 6 - 1表示了在 IIS 5.0中 A S P的性能改善情况。它表明了一个经常使用 L o o k u p Ta b l e组件的不太复杂的 A S P脚本(大约 1 0 0 0行的代码,产生约 25 KB的 H T M L文件)在 IIS 5.0中的性能改善情况。
图 26-1 IIS 5.0中 A S P的性能改善情况应用程序无法很好地扩展的原因是资源争用和串行化过程。每一个线程都在争用共享的资源、组件的关键部分或系统总线。当一个线程对某一资源进行独占访问时,其他线程被阻塞,只有第一个线程释放这些资源,其他线程才能再使用这些资源。资源的使用是串行的而不是并行的。由于单处理器系统在一个瞬间实际只有执行一个线程,所以这种问题不容易出现。对有 n个处理器的系统,同时执行 n个线程,就会出现资源争用问题。
如果 A S P应用程序要在多处理器系统上使用,首先必须对应用程序在多处理器系统上的可扩展性和性能进行测试。
通过测试可以把一些诸如线程安全、死锁等问题及发现的其他问题从应用程序中清除掉。
26.2 改善服务器的硬件性能必须有合适的硬件支持,才可以满足现在的要求和将来可能的负荷要求。一个奔腾 1 3 3也许足以应付小部门的网络服务要求,但却不能满足一个繁忙的商业站点的要求。
26.2.1 内存服务器有足够的物理内存是至关重要的。如果没有足够的物理内存,那么,改善服务器性能的最简单最有效的方法就是增加内存。虚拟内存子系统虽能很好地工作,但是系统的吞吐量将会大大降低,因为系统将很多的时间用在内存与硬盘之间的页面交换上。即使系统有足够的内存,增加内存仍能提高系统性能。 I I S的核心需要大量内存来高速缓存存储静态文件,
A S P需要内存来存储编译了的 A S P文件和 A S P会话数据。
可以使用 N T Performance Monitor来诊断内存问题。在 IIS Technet 网站和 M S D N
网络服务器技术站点上,有些文章对这一问题做了进一步的讨论,微软出版社出版的
,IIS Resource Guide》对这一问题也进行了研究。
1 2 8 M B是专用网络服务器的最小内存数,增加到 2 5 6 M B较好,如果是任务比较繁重的商业网站,内存应为 5 1 2 M B到 1 G B。增加内存可以改善服务器的工作性能,最终将逐渐接近系统的最高性能,例如,少数服务器的实际内存为 2 G B。
786计计 ASP 3 高级编程 下载
IIS 5 中的 ASP 性能提高进程内进程外进程内进程外进程内进程外
26.2.2 硬盘硬盘用来存储静态的内容( H T M L文件和图片),程序、脚本、日志文件和数据库等。对许多的网站来说,标准的 E I D E或 S C S I硬盘就够用了。将系统文件、数据库、日志文件、临时文件和网页文件分别存储到不同的物理硬盘上,可以减少硬盘磁头的寻找时间,从而改善性能。硬盘工作量较多的网站应该使用 RAID 0,RAID 1或 RAID 5 硬盘子系统来提高硬盘的吞吐量。一定要确定硬盘的工作瓶颈不是由过度页面交换所致。
26.2.3 网络带宽确保有足够的网络带宽可以满足网络服务器的负荷要求,确保有合适的网卡和网络交换器。快速的以太网( 1 0 0 M b p s)在大多数情况下能满足需要,主要的问题是费用太高。
26.2.4 CPU
用 I I S传递静态文件非常高效,但是要产生一个动态文件就要占用许多 C P U资源。如果服务器经常满负荷使用 C P U,那就应考虑换一个速度更快的 C P U了。如果已经有了一个较快的
C P U,那就要考虑增加第二个。如果使用 IIS 5.0,就可以考虑增加到 4至 8个 C P U。
还要确定 C P U有较大的二级缓存,每个至少 1 M B。 C P U的二级缓存要比内存快得多。如果缺乏二级缓存,将影响系统的性能。
26.2.5 更多的服务器有时,一台机器是不够的。它可能应付不了现有工作量。拥有更多的机器可以得到更高的可用性,即使有一台机器坏了,网站仍能继续正常运行;也就是就没有单一故障点。
可以有几种选择。如果 We b服务器上正在运行一个数据库,可以把数据库转移到后端服务器上,这样可以减轻服务器的负荷。特别是对于一个 We b阵(许多机器作为一台逻辑网络服务器使用),多服务器更是非常必要的。我们将在下一章详细介绍 We b阵。
26.3 性能的调整总体来说,静态内容很少会有性能问题。性能问题常常是由于服务器的硬件不足(尤其是缺少内存),带宽不够或网络等待时间长而产生的。然而,I I S和其他现代的网络服务器都擅长传递高容量的静态文件。
许多性能问题发生在动态内容上。但不幸的是,这些问题是无法确定的,比较难解决。
有无限种方法可以用来编写 A S P网页,可它们中的许多是低效的。即使是在像 A S P或 I S A P I这样完善的系统中,应用程序开发者仍可能写出低效率的代码。
26.3.1 解决性能问题首先,必须设置一些合理的目标。例如,指定网站应有能力每秒传递至少 5 0个 A S P网页,
且只使用不超过 4 0 %的 C P U资源,在低于平均负荷时,9 5 %的请求的响应时间低于 5秒。然后,
用最大负荷(或可能的峰值负荷)和平均负荷来衡量网站的工作性能。
最大负荷是指使用 WA S等工具在服务器上产生的极高负荷,它使服务器的 C P U
第 26章 优化 ASP 的性能 计计 787下载或网络饱和。
给出可持续的服务器吞吐量的上限,用平均负荷来测试网站性能看是否达到这一目标。
平均负荷量应该根据原始数据或猜测值来模拟。在可能的峰值负荷下测量网站的工作性能可以检测机器在最繁忙的情况下工作得如何。
如果网站性能达不到要求,就需要找出影响性能的最主要问题,然后解决它。在找到和解决了这个问题后,应该重新进行测量,重新调整,直到获得了满意的性能或从机器中榨取出最后一点性能为止。如果还不满意,还可以选择:
增加新硬件。
重新现实地确定性能指标。
把 A S P应用程序的关键部分重写成 C O M组件或一个 I S A P I。
26.3.2 强度工具调节工作性能的关键因素是要知道应用程序的工作。为分析工作,建立一个受控环境是非常重要的,因为这样可以得到有关负荷能力的正确数据。为了模拟几百个并发客户的行为,
使用多台客户计算机是很必要的。测试应在不受一般的网络活动和尖峰信号干扰的独立网络中进行,这样得到的结果才是有用的。
受控制的强度测试环境的另一个组成部分是网络服务器。强度试验环境要在测试期间提供一致的不受其他活动影响的环境。这就允许通过改变设置和脚本,来清楚地看到这些变化的效果。换句话说,当进行性能分析和调节的时候,需要能够提供一系列一致的试验环境。
如果试验服务器兼任域控制器或邮件服务器,则试验结果将会因为调用的机器用于其他目的而改变。
理想的情况是由拥有一个测试实验室,其硬件环境与站点相同。然而,这不是必需的。
最重要的是这个测试实验室只用于测试期间的测试过程。
一旦建立了强度测试实验室,可以选择多种强度工具。有多种选择,价格可以从免费的到非常昂贵的,功能上从支持 HTTP 1.0规范到支持 H T T P 1,1规范并有分析和报告的能力。如果喜欢 Web Application Stress( WA S)工具,可以免费从微软公司得到的,运行界面如图 2 6 - 2
所示。
图 26-2 运行 WA S的界面
788计计 ASP 3 高级编程 下载
WA S可以从 http,//webtool.rte.microsoft.com下载得到。该站点还提供了有关这个强度工具的基础知识和综合指南。这个工具包括联机帮助,帮助非常完整,包含许多实例。
26.3.3 脚本优化有个比喻:一根链条的强度就是其中最脆弱的那个环节的强度。这个比喻同样适用于评价网络应用程序的性能。可能有几个脚本程序比其他脚本程序慢。然而,网络的性能正是由于这几个脚本程序的存在变得极差。由于这几个脚本程序占用了可被其他脚本利用的资源,
应用程序的性能一般情况下会有所降低。增加环境切换会影响整个应用程序的性能。但如何查明出现瓶颈的原因呢?毕竟,一个脚本程序有一些包含文件,还有相当数量的代码。我们希望能够查明脚本的什么地方占用了时间,什么消耗了太多的处理器资源。我常用的方法如下:
首先,运行强度工具来这个脚本程序以得到性能数据。假设有一个名为 P r o c e s s
R e q u e s t,a s p的脚本程序,当强度工具运行时,将得到每秒 1 0个请求。这是一个开始点,作为参考。其次,在脚本程序的“中点”设置一个 R e s p o n s e,E n d,并且重新运行强度工具。例如,
如果 P r o c e s s R e q u e s t,a s p有 1 0 0行,那就可以简单地在第 5 0行插入 R e s p o n s e,E n d。结果如何?脚本程序的后一半将不会被执行。通过观察前一半的工作性能,可以知道瓶颈是在前一半,还是在后一半,或者是平均分布在两部分之中。假设没有了后一半脚本程序,得到每秒 1 0 0个请求而不是 1 0个,现在就知道了是后一半的某些东西降低了速度。如果得到的结果与“开始点”
接近,说明第一部分有些问题。
现在,移动 R e s p o n s e,E n d到可能出故障的那一半脚本程序的中点,然后重新运行强度工具。我们尽力识别产生最大影响的数据库调用和脚本程序。在我们的例子中,在有 1 0 0行的脚本程序的第 5 0行处中止它。看到每秒请求从 1 0增加到了 1 0 0。所以,下一步把 Response.End 放置在第 7 5行然后重新测试。如果工作性能又降回去,可以下结论:问题出现在第 5 0行和第 7 5
行之间。因此,可以 R e s p o n s e,E n d插在这两点之间,即插在第 6 2行,并重新测试。通过这种方法,可以查出到底是哪里降低了脚本程序的速度。
如果脚本程序代码的测试数据是线性的又会怎样呢?完全有可能在进行这种测试后,没有找到特殊问题。在这种情况下,需要确定正在做的事是不是计算量太大了。也许,一些需要解释的脚本代码应该被调用 C O M对象所取代,因为这样执行起来较快,参见 2 6,3,1 0节。
26.3.4 会话和应用程序状态
A S P通过较小的框架提供了许多方便,如 I S A P I。对应用程序和会话状态的透明支持是
A S P值得注意的一个特征。 H T T P是一种无状态的协议,所以状态可以被任何用户的两个不同请求共享。这使 H T T P非常可扩展,因为客户和服务器的一次连接不会持续几分钟或几小时。
为了保持会话状态,A S P在每一个响应的报头加上一个 ASPSESSIONID cookie,在客户随后的请求中,报头都会包含这个 ASPSESSIONID Co o k i e,A S P就可以利用这个标志,在会话状态数据库中进行查找。会话状态对于在网上采购应用程序尤其有用。一个来到在线商店的顾客在采购筐中加入项目。当他决定购买时,A S P就为他们清点商品数目,计算价格。
不幸的是会话状态有一些问题。在我们研究它的缺点之前,让我们来看看它的优点:
使用起来简单、方便。
第 26章 优化 ASP 的性能 计计 789下载
790计计 ASP 3 高级编程 下载
跨请求缓存信息。只计算一次而且把数据存储在 S e s s i o n对象中,而不是对每一个请求重复复杂的计算或在数据库中查询。这经常会使性能有极大的提高。
无须创建定制的基本结构,可以集中精力创建应用程序。
对于不需要特殊功能或者较大的内存的应用程序来说往往是足够好了。
1,话状态存在的问题注意不是所有这些问题都影响性能,但大多数影响性能。
会话状态的问题是:
对 c o o k i e过分依赖。不是所有的浏览器都支持 c o o k i e。有时即使浏览器支持,用户却不愿接受。没有 c o o k i e,会话状态就无法工作。 Cookie Munger过滤器可以用于缺少 c o o k i e
的不完善工作环境,更详细的内容后面讨论。
会话状态太脆弱。如果没有一致地使用同一种 U R L,有些浏览器就会认为你使用了两个不同的应用程序并且发送不同的 c o o k i e。例如,就会认为 < A HREF =,/ w r o x / b a r,a s p” >
与 <A HREF =,/ w r o x /Qu u x,a s p” > 不一样。
会话状态串行执行。换句话说就是同一会话的两个不同的请求从来不会被同时执行。一般情况下,这是一个优势。它意味着 S e s s i o n对象不同于 A p p l i c a t i o n对象,不需要采用
L o c k和 U n l o c k方法,这使程序简化。然而,串行化执行引发了框架方面的问题,框架执行的顺序是不确定的。如果其中一个框架花费了较多的时间来执行,其他的框架就要被挂起来等待它执行完毕。如果这个框架不需要会话状态(即没有用到 S e s s i o n对象),可以通过在页面顶部使用 <% EnableSessionState = False %>来使会话状态无效。
在会话状态不使用时,仍占用会话状态使用的内存,降低了 A S P的速度。如果应用程序根本不需要会话状态,可在 Internet Service Manager中在应用程序的 Properties 页的 A p p
o p t i o n s 选项卡中将其设置为无效。
会话状态是非持久性的。如果 A S P应用程序发生了崩溃,所有的会话状态和应用程序状态就丢失了。如果不允许这样,那么必须不断地坚持把重要数据记录到硬盘或数据库中。
会话状态超时。在默认状态,如果 2 0分钟内没有接收到请求,A S P就会自动结束这一会话状态。如果用户在浏览你的站点的中途去吃午餐,那等他回来时,其会话状态已经被关闭了。
会话状态持续较长的时间。当站点的一个典型用户仅仅使用你的网站的一至二个网页,
然后就离开了。但是,他的会话状态将会内存中被保持 2 0分钟。对于一个繁忙的站点,
每分钟有几百个新的访问者,合计起来就占用了许多内存。
决不能在你的 G l o b a l,a s a中有空的 S e s s i o n _ O n E n d过程。 A S P优化会话状态的方法是在接收的一个请求后,判断其 S e s s i o n对象是否为空,如果是,则放弃它。这样当用户实际上并不使用 S e s s i o n对象时,可以节省大量的内存。但是如果程序中存在 S e s s i o n _ O n E n d的话,由于程序认为这些清理代码有可能需要运行,A S P就无法进行优化处理了。
较大的数组不应存储在 Session 或 A p p l i c a t i o n对象中。在 V B S c r i p t和 J S c r i p t语言中,当要访问数组中的某一个元素时,都需要一个数组的完整的临时拷贝。例如,存储一个由
100 000元素组成的字符串数组,它以美国的邮政编码为序存储美国各地区的天气状态。
那么,每次要查找某一个特定区域的天气情况时,在检索那个区域的天气情况之前,必须把这个有 100 000个元素的数组整个拷贝到一个临时数组中。通常采用特殊的存取方法将较大的数组分割成一个个较小的数组,以便减少存储空间。
会话状态无法扩展到Web 阵。会话状态被限制到运行于一台机器的一个应用程序中。如果网站升级至 Web 阵,就既可以获得较高的可用性又可以应付更多的业务量,但是会话状态不能在Web 阵中跨机器共享。在这种情况下,可以选择:
1) 放弃会话状态。这是最简洁和最容易实现的解决方法。
2) 定制一个会话状态解决方案。最重要的是把所有状态保存到一个共享的后端数据库,
总是使数据长期有效。
3) 使用“粘性会话” 。大多数的硬件和软件重定向器都有一个特征,通过这个特征一个由有特定 I P地址的用户发来的请求,可以被定位于同一台服务器。然而,这相对于根据工作量均衡负载难于扩展。因为不同的服务器由不同的工作速度。更糟糕的是,粘性会话并不总能工作。例如,美国在线( A O L)有巨大的代理服务器组,这些服务器有许多个不相同的 I P地址。无法保证,来自 A O L的同一个客户的两个连续的请求会通过同一个代理服务器发送而且有相同 I P地址。同样,如果不同的用户使用同一个代理服务器,他们看起来就好像来自同一个 I P地址处。
单元线程组件将会话锁定于特定的工作者线程。 A S P保存工作者线程的集合。通常,当一个请求到达请求序列的排头时,第一个可利用的线程就对它进行处理。如果某个会话被锁定于某个线程,如果该线程正忙于处理别的请求,这个请求必须在该服务器处等待,
直到它可被响应为止。这就像在超市购物,虽然其他的收款处前等待付费的队伍较短,
却总是到 3号收款处排队结账。不要在 S e s s i o n对象中使用单元线程对象,只使用其他灵活对象,如中立线程对象或双线程对象加上自由线程调变器。
已连接的记录集不要存储在 Session 或 A p p l i c a t i o n对象中。如果不打算在 A S P页面结束前破坏记录集,那就要及时断开记录集与服务器的连接,否则会消耗巨大的资源。
上面列出了使用会话状态的许多问题。那么,如何才能避免这些问题呢?
2,会话状态的替代我们已经列出了脆弱性、可扩展性和资源消耗等方面的问题。如何解决这些问题?
完全地避开会话状态。这就绕开了所有会话状态的问题,而且还使应用程序更具有可扩展性。不过,对需要会话状态的网站来说,这样做是不实际的。
在 c o o k i e中直接对会话状态进行编码,而不是存放 A S P S E S S I O N I D。这种方法非常有效,
尤其是当应用在 We b阵上时。不过,这有许多的不足之处:
1) 浏览器必须支持 c o o k i e,并且 c o o k i e在浏览器中启用了。
2) cookie有大小的限制,一台浏览器能存储不超过 3 0 0个 c o o k i e,每个服务器 2 0个,每个
c o o k i e不超过 4 K B。
3) 把会话状态存储在用户的计算机上是不安全。而且,它会随每个请求而在网络内来回地传送。
在 c o o k i e中存储一个后端数据库的键。这种做法是可扩展的并且比较安全,但是它每次都会查询数据库,而且,它仍然需要在浏览器上启用 c o o k i e。 Site Server 附带的 A c t i v e
User Object 会为你办妥这些事。有些等三方软件商,例如 Software Artisans,卖类似的组件。
第 26章 优化 ASP 的性能 计计 791下载
把名称 /值对存储在 U R L查询字符串中。例如,<A HREF=,wrox.asp?Name =
Napoleon&Game = World + Domination” >。这种做法适合所有浏览器,但它会暴露会话状态的内容,而且不能很好地支持 P O S T和窗体器。
修改 U R L,使会话状态可以在 U R L(而不是查询字符串)中编码。 A m a z o n,c o m就是这样做的一个网站。另一个例子是 G e o rge Reilly 写的 Cookie Munger过滤器,它是 P l a t f o r m
S D K( Software Development Kit,软件开发工具包)中的一个 I S A P I过滤器示例。这个过滤器使得 A S P会话状态能在不支持 c o o k i e s的浏览器上工作。过滤器检查服务器和浏览器之间传送的所有数据,从报头去掉 ASPSESSIONID cookie,然后修改网页内所有的 U R L,
这样最后看起来就像 <A HREF=,w r o x,a s p - A S P = P V Z Q G H U M E AYA H M F V” >。它也在所有收到的请求中寻找 U R L,并把它们翻译成符合普通 U R L标准,同时给它们加上一个 Cookie 报头。所有这些在幕后完成,A S P对此一无所知。 Cookie Munger 存在两个问题,像其他原始数据过滤器一样,会导致性能的根本性降低。而且,当 c o o k i e丢失后,
过滤器对纯 H T M L文件(,htm 文件)不起作用。请参阅相关文档。
窗体包含隐藏字段,这些隐藏的字段是对状态的编码。这样做效果还不错,不过,它要求每一页都是一个窗体(或者使用查询字符串) 。如果使用浏览器上的 Back 按钮,数据有可能会丢失。当用户查看网页源代码时,就可以看到隐含的字段,所以它对私有数据并不合适。
简而言之,所有这些改变的效果都不是很好。
对于以上的对 A S P的会话状态阐述,不应完全失去信心。这里不得不说,使用 A S P会话对许多应用程序来说是一种明智的选择。如果不太介意以上的缺点,就可以使用。当然,在你的网站开始流行并逐渐增加业务量时,那些缺陷会就会带来一些麻烦。尤其是移植到 We b阵时,可能被迫做一些代价昂贵的工作。
3,应用程序状态就像会话状态,应用程序状态同样有一些很好的优点和巨大的缺点。在 A p p l i c a t i o n对象中缓存数据可以使性能显著提高。它不是为了每一个会话状态或请求对同样数据进行一遍又一遍的重复计算,而是只计算一次数据并把它们存储在 A p p l i c a t i o n对象中。
跟 S e s s i o n对象一样,A p p l i c a t i o n对象的状态不是永久的,且不能在系统崩溃后挽救。应用程序状态适合于一台计算机的情况,但不适合 Web 阵。这表明只有只读数据应被缓存于应用程序状态中,因为通过 We b阵更新共享数据是困难的。应用程序状态并不依赖于 c o o k i e,因此,也就没有与 c o o k i e相关的问题要探讨。大的数组不应该被存储在应用程序状态中,因为每次访问数组中的任何一个元素时,按 V B S c r i p t和 J S C r i p t的机制需要给整个数组做一个临时的拷贝。
应用程序状态不应包含单元线程对象,因为这会导致严重的性能瓶颈。事实上,为了不鼓励用户使用单元线程对象,A S P不允许用 S e r v e r,C r e a t e O b j e c t创建这种对象。如果一定要在应用程序范围存储单元线程对象的话,就必须使用 < O B J E C T >标记,如:
之所以不应把单元线程对象存储应用程序范围内,原因有三:
792计计 ASP 3 高级编程 下载
对象存放在特殊的 S TA单元中,所有的对象调用都必须从对象的单元调度到工作者线程的单元,这比直接调用对象要慢得很多。
所有对对象的调用都是串行的,所以每次仅一个调用者可以使用对象,这就会导致有许多的工作者线程排队等候访问该对象。存储在应用程序范围的对象应该被并行使用。
存储在应用程序范围内的单元线程对象从不会在调用者的安全环境中执行。
只有灵活对象可以存储在应用程序范围内。灵活对象允许直接调用,不会使调用者排队等待。灵活对象编写困难,因为必须要特别注意线程安全。可以用 C + + / AT L或 Visual J++来编写。
26.3.5 安全套接字层通过 H T T P S协议访问安全套接字层 S S L,可以完成安全的电子商务,在浏览器和服务器之间开辟了一条安全的连接,并且所有的数据在通过电缆传送出去之前,都会被编码加密。
这样就使得在 I n t e r n e t等不可信赖网络上传送信用卡帐号和医疗记录等敏感数据变得较为安全。
由于实现加密、解密需要进行大量数学计算,所以 S S L连接比通常的 H T T P连接要复杂得多。用 H T T P S传输静态文件的费用是用 H T T P的 2 0多倍。经 H T T P S传送 A S P网页与用它传递静态文件相比费用要少些。可是由 A S P产生动态网页却比传送静态文件要昂贵得多,因此在
H T T P S上的花费只占总费用的很小的一部分。相比之下,对一些小型的 A S P网页来说,在
H T T P S上的花费仍是很大的。 S S L可使吞吐量减小到数十分之一。
因为 S S L费用这么高,只有在必需时才使用它。信用卡帐号必须用 H T T P S形式来传递;
医疗记录也必须用 H T T P S网页来提供。主页和其他不含私人内容的网页应该用 H T T P来传递。
除了一些含有机密内容的图片外,所有的图片都不应该用 H T T P S方式来传递。但是,对于连接到 H T T P S页面,如果试图通过 H T T P检索数据,大多数的浏览器会自动弹出一个消息窗口。
一个较慢的页面也比得到一个消息窗口的页面要好得多。
26.3.6 进程隔离在 IIS 3.0中,所有的 A S P应用程序都在 I I S的核心 inetinfo.exe 内被处理。这是很快的却是易受干扰的。一个错误的组件可以使整个 We b服务器系统崩溃。 IIS 4.0引入了进程隔离的方法。
应用程序既可以在进程内(在 inetinfo 进程内)运行,也可以在进程外(由 m t x,e x e作宿主)
运行。一个运行在进程外的错误的组件能够破坏其宿主,却不能破坏 We b服务器的核心。然而,由于进程外应用程序需要与 i n e t i n f o通信,它的运行速度要慢些。性能的降低换来了可靠性的提高。
进程会消耗大量的系统资源,所以不能在 IIS 4.0上运行几十个进程外的应用程序。由于意识到了这一点,在 IIS 5.0中加入了隔离级别,可以缓冲进程外。在较高隔离级别的(进程外的)应用程序继续在独立的进程中运行,这些进程以 d l l h o s t,e x e作宿主。在中等隔离级别的
(共享进程外的)应用程序在一个进程内一起运行,且也以 d l l h o s t,e x e作宿主。低等隔离级别的(进程内的)应用程序直接由 I I S的核心来处理,这个核心就是 i n e t i n f o。
在 IIS 5.0中,大大地提高了 A S P的性能,其进程外应用程序的性能比 IIS 4.0中的进程内应用的性能还要好,进程内应用程序的性能则更佳。因此,可以牺牲一些性能来换取系统的可靠性。新的应用程序在缺省状态下在中等隔离级别中运行;而在 IIS 4.0中,新的应用程序在第 26章 优化 ASP 的性能 计计 793下载进程内运行。
如果有一个受信任的应用程序(即由已测试过的组件组成),则可以把它放置在低隔离级别中运行以提高它的性能。需要注意的是,该应用程序崩溃会使 We b服务器进程崩溃。 IIS 5.0
包含有一个新的可靠的重启动特性,由 iisreset.exe 控制。该功能已经比 IIS 4.0中的同类功能少了许多问题,但仍然不很理想。
26.3.7 缓存技术和字典缓存是提升基本性能的技术。它用空间换取速度。为了不重复计算数据或从远处获取数据,把数据暂存以便再使用。计算机的每一层都十分依赖于缓存,从 C P U的 L 1和 L 2缓存到硬盘的缓存,到操作系统的文件缓存,到 A S P缓存,到 O D B C的连接缓冲。
在 A S P中可以通过四种方法来利用缓存:
第一种方法是把一些数据存储在变量中而在同一页中重新使用它们。例如,一个字符串或一个记录集。
第二种方法是把一些数据存储在 S e s s i o n对象中,这样(同一用户在同一会话中)在访问其他网页时通过这个 S e s s i o n对象可以重新使用这些数据。例如,购物清单或用户名等。
第三种方法是把数据存储在 A p p l i c a t i o n对象中,这样,数据可以被本站点的许多访问者使用。例如,网页的标题栏。
最后一种方法是用一个组件来缓存全局数据,当该组件在一个网页上创建时,它的方法访问内部的数据。例如,一个 Browser Capabilities组件缓存了 b r o w s c a p,i n i的内容,仅当硬盘上的文件改变时才更新它的缓存,这种工作只需几个月进行一次。
字典也称为“相关数组”或“映射”,对于缓存名称 -值对是非常有用的。例如,可以用两个字母的国家代码映射其全称。如,F R”·,F r a n c e”,,I E”·,I r e l a n d”,等等。因为这些数据仅仅在有一个新国家成立时才发生改变,所以把这个字典缓存于 A p p l i c a t i o n对象中是十分合适的。
另一个例子就是 I S B N号码,包含单位名称及其详细情况。因为 I S B N号码有成千上万个,
而且每天还会新增几千个。这些数据太大了,所以不可以存储在内存中,最好存储在数据库中,并定期更新缓存中的数据。不过为在线书店的购物清单建立一个 ISBN 和其详细情况的映射是合适的。
A S P含有一个 D i c t i o n a r y组件,S c r i p t i n g,D i c t i o n a r y。但是,S c r i p t i n g,D i c t i o n a r y是单元线程的,不适合存储在 S e s s i o n对象或 A p p l i c a t i o n对象中。
对于商业服务器,可以使用 C o m m e r c e,D i c t i o n a r y。它包含两个可以自由使用的字典:
L o o k u p Ta b l e和 C a p r o c k,D i c t i o n a r y。
A s p t o d a y.com 站点上有一本关于 L o o k u p Ta b l e字典的好教材。
如果要在 S e s s i o n对象或 A p p l i c a t i o n对象中缓存一个记录集,首先确保断开它的连接。
跨多个网页保持连接是一个非常不好的想法。
更好的是,如果记录集总是被转换成相同的 H T M L(例如表或列表框),缓存 H T M L文件内容可以避免每次在记录集中遍历的时间花费。如果列表框在不同的环境下有不同的选项集,
仍然可以缓存列表框,并且使用 R e p l a c e函数通过适当的选择来产生一个新的字符串。
794计计 ASP 3 高级编程 下载
26.3.8 数据库性能对于数据库的定义,一些著名的计算机公司经理的解释为:,数据库就是 We b应用程序” 。
动态的站点不断地存储、检索和更新数据。数据库的性能常常是网络应用程序本身性能的核心部分。有几种简单的方法可以减少网络应用程序使用数据库的瓶颈。努力调整数据库的性能更为人们所重视。企业数据库甚至提供分析使用模式的工具以便帮助开发者和管理者。
微软公司的 SQL Server 是我们的网络应用程序使用的数据库,也是我们这里所指的数据库。大多数情况是这样,如果有例外,另外指明。
要做的第一件事就是不要在网络应用程序中使用 Microsoft Access。 A c c e s s在其设计的范围内使用时,是一个很好的应用程序。然而,却不利于快速传送大量数据。最好将其在 D a t a
Sources 面板中的驱动程序也删除。
在缺省状态下,A D O被设置成单元线程的。这可能是由于 A c c e s s仅支持通过 O D B C驱动程序的单元线程访问。 A D O支持多线程模型,使用这种方式可以使性能提高。有一个批处理文件可以用来进行这样的转换。在典型安装的情况下,可以在 \ Program Files\Common
Files\System\ado 目录下找到它。在此路径下运行 m a k e f r e l 5,b a t,A D O可以转换成双线程对象,
同时支持单元线程模型和自由线程模型。同样,也有一个批处理文件可以返回单元线程模型。
当使用的 A D O是 2,5版时,其批处理文件及 D L L文件名中的,1 5”很容易把人搞糊涂,因为 1 5表示 1,5版。 D L L文件中的 C O M能力改进了,但 D L L文件仍然继承低版本的名字。这尽管不直观,但这比相同的组件在不同的版本中使用不同的名字好。
尽管各个企业数据库的管理系统不尽相同,但它们仍然有一个共同之处:为了使其获得较高的性能,需要足够的内存。如果有足够的内存支持缓存,I I S的表现也会更好。正因为此,
把 I I S和 S Q L分开放在不同的机器上是一个好主意。许多人马上就会想到由于计算机间的传输问题会使系统的性能下降。然而,从使用情况看,大容量的内存、专用的处理能力及良好的低层通信方法使得对数据库的访问速度极快。
如果数据库运行在一台独立机器上,使用数据库有两个可行的方案,两者都能提高网络应用程序的性能。
第一,应用程序几乎全由数据库来驱动。在这种情况下,数据库需要足够的资源来有效处理查询和缓存数据,
第二个方案是另一个极端,很少使用从数据库来的数据。在这种情况下,把数据库独立放在另一台机器上仍然十分有意义。这将使得处理主要业务量的网络服务器的资源不被数据库占用。跨机器边界所付出的代价多于提高数据库和网络服务的效率所付出的代价。
一个数据库经常可以同时处理几个网络服务器的请求。
利用 C O M +的特性,包括以前的 M T S,可以处理一些数据检查的工作。通过利用置于数据库定义内的引用完整性校验,不用启动脚本显式地检查就可以找出相应的错误。利用 We b
页的事务可以进一步保护数据库数据的更新和插入。引用完整性检查在数据库中执行得要比在脚本中快得多。例如,检查用户现在的地址提供的邮政编码和服务器提供的邮政编码表。
另外,要确保索引存在于被访问的表中。数据库引擎能做一项神秘的工作:当得知数据库如何被访问的某些线索后,系统能自动调整性能。这些线索由已经建立起来的索引提供。
第 26章 优化 ASP 的性能 计计 795下载
796计计 ASP 3 高级编程 下载发挥数据库中存储过程的优势:经常需要的例行程序可以作为存储过程或触发器而建立起来。
这些操作如果在脚本实现比较困难并且速度较慢。通过利用数据库内的表连结、联合体和视图,脚本会出现较少的错误而且运行得会更快。在网络应用程序运行的时候,往往看重数据库的管理和调节,但对数据的访问通常是网站最大的瓶颈。当看到这样一行短语,l o n g -
running and blocking processes”时,这常常表明数据库正在被使用。
26.3.9 真正充足的时间,M S M Q
前面有一章专门讲述了 M S M Q,现在让我们从性能的角度重新来分析 M S M Q。网络浏览具有实时性。没有人希望发生这样的事:他们请求了一个网页,而需要几分钟等待网页在其浏览器上显示。然而,这种现象在服务器端经常发生,换句话说,用户不总是需要等待 We b
页的脚本执行完才跳到下一页。
假设一个应用程序接收到一个发送一个产品的样品的命令,这个应用程序可能需要根据请求更新数据库并通过电子邮件发送一个最接近的样品。这是一个例子,用户不必等所有的样品都发送完就可以进行切换。为什么这样呢?与其在脚本中完成以上操作,不如把这个定单请求加入到一消息队列中。 We b服务器可以继续处理请求,用户继续浏览。这个消息队列允许处理定单并确认传送,而不影响 We b应用程序性能。 M S M Q使得把工作从正在运行 I I S的计算机上移到后端服务器上变得十分容易,而且进一步降低了响应时间。
26.3.10 脚本与组件的比较脚本的速度比组件要慢,因为脚本是解释运行而组件是编译后运行。
可以通过把 A S P网页中的脚本模块替换为组件调用来大幅度提高性能。
这是否意味着必须把 A S P网页全部写成组件?不,有几个与组件有关的潜在的问题必须注意:
组件难于调试,因为不能用脚本调试器对它们进行行步执行,必须用单独的调试程序。
组件不易修改。对于 A S P网页,利用自己喜欢的方式对其进行编辑,保存,然后用浏览器重新加载。对于一个组件,则必须停止使用该组件的所有 A S P应用程序,修改源代码,
重新进行编译,重新启动 A S P应用程序,只有这样才可以通过浏览器加载这个网页。这样的“编辑-执行-调试”的周期相当长。
不完善的组件易崩溃。调用一个有错误的组件会使 A S P应用程序停止工作。一个完全由脚本和系统组件组成的 A S P应用程序是不太可能崩溃的。如果对一个组件无法完全相信其可靠性,就应该在单独的进程(高或中等隔离级别)内运行 A S P应用程序,而且要使组件作为库包与 A S P运行在同一个进程中;或者应该在 C O M + E x p l o r e r中把组件作为服务器应用程序使其在自己的进程中单独运行。我们推荐让 A S P应用程序在高隔离级别上运行而把组件作为库包运行。
不完善的组件会“泄漏”内存。这样的组件在其卸载后不能完全地释放内存、句柄和其他资源。长此下去,将导致 We b服务器不能使用。请记住,一台 We b服务器的正常运行时间为几个月,如果组件有上述问题,We b服务器不可能正常运行。
不完善的组件不能在高强度环境下维持运行。许多组件不能安全地通过强度试验,而且当 We b服务器在高负载环境下时它们会失败。死锁和访问违规是非常普通的现像,尤其第 26章 优化 ASP 的性能 计计 797下载是在多处理器系统中。 A S P应用程序和组件在使用前必须经过强度试验。
许多组件(它们都是单元线程的)之间有线程相似性,将它们存储在 S e s s i o n对象或
A p p l i c a t i o n对象中时执行得并不好。对于用 Visual Basic 或 M F C写的组件来说就是这样。
会话和应用程序范围的组件应该是灵活组件,即中立线程或双线程(并配合自由线程高度器),一般比较难以编写。
组件在多处理器系统上往往不能很好地扩展。 许多组件通过获得锁使自己得到线程安全。
这样做在单处理器系统上非常好,但在多处理器系统上就有许多争用和串行化等问题。
在 2 6,3,11节将进一步讨论。
另外,有许多的网页不值得转换成组件,因为转化它们并不能使系统性能得到提高。小的网页或不经常被执行的网页不提倡转换为组件。 初始化组件和调用它们都要花费时间,
如果组件内容不多,用脚本执行可能更快一些。为了找出哪些网页应该转换,应该看日志文件。经常被访问的网页和需要花费较长时间来执行的网页要考虑转换。分析这些网页。看是否使用了低效的算法?有棘手问题?代码能否被组件调用取代?
除非有至少一百行的脚本和一些大的循环在脚本中,否则不必考虑把网页转换成组件。
要知道 A S P网页的 # i n c l u d e功能包含的代码比实际所能看到的要多得多。为了找出
/ w r o x / b a r,a s p在服务器端有多少脚本,应把它重新命名为 / w r o x / b a r,s t m,然后,用浏览器访问新的网页,并且查看源代码。这个技术依赖与 A S P和 S S I对于 # i n c l u d e使用同样的语法,不同的是 S S I不解释 A S P脚本,因此,它直接发送到客户。
那么,考虑使用组件的原因是什么呢?
首先,也是本章的目的所在,就是性能。如果做得好,系统的速度将可能获得 2 0 ~ 3 0倍的提升。通常,速度的提升不是戏剧性的,但足以使站点不会因为太慢而被遗忘。方法是:不仅用编译的二进制码取代解释的脚本,而且用早期绑定取代后期绑定;绕过 O L E
的自动化层、使用低层接口(例如用 OLE DB 代替 A D O)使程序更高效;直接调用文件系统而不是使用 F i l e S y s t e m对象。
组件提供可扩展性。如果组件占用太多的 C P U资源,可以把它们放到后端机器上去运行,
并通过 D C O M与之连接。这样就不再受单台机器的限制了。
对于是否要把所有的业务逻辑都放入到组件中存在着很大的争议。这需要将业务层从表现层中分离出来,而 A S P正是,H T M L胶水” 。如果改变一些业务规则,只需修改组件,
而不是每个 A S P网页。如果已经把内容从规则中分离出来,则将网站的语言转换成另一种语言也十分简单。更进一步,如果一部分人写业务规则,另一部分人写 H T M L的内容,
当业务规则在独立的组件中时,集成很容易。
组件具有较好的重复使用性。在丰富的 Wi n 3 2用户界面背后可以使用相同的业务规则组件。可以在应用程序的许多 A S P网页中或其他 A S P应用程序中重复使用组件。
组件是强类型的。 V B S c r i p t是一种弱类型的语言:所有的变量都是 Va r i a n t。这对于较小的快速开发出来的性能较差的程序来说非常方便,但对于工业强度的程序来说,强类型是非常重要的。
组件允许访问操作系统的所有功能。例如,在 A S P中无法读到注册表的任何信息,必须使用组件。在 A S P中不能直接对文件做任何处理,必须使用 A S P内置的 F i l e S y s t e m对象。
最后,组件可以保护作者的知识产权。如果为顾客建立了一个 A S P网站,你的顾客就能读到你的源代码。如果把重要的代码都放在组件中,这些代码就不会被看到了。
脚本引擎的第五版包括通用的一个脚本编码工具,提供了一般性保护,不是密码级保护。
1,组件的线程模型在写一个 C O M对象时,对于线程模型的选择非常重要。由于混合线程模型的复杂性,性能可能会发生戏剧性的变化。
在 A S P上不要使用单线程对象。
每一个使用的对象都必须调度到 C O M主线程上。如果多线程的环境必须等待可利用的单个线程,性能会降低。随着负载的增加性能显著降低。
自由线程对象也不适用于一般使用目的的 A S P应用程序。
除非额外在 C O M服务管理器上注册,否则这种类型的对象没有相同的环境可利用。
对象的单线程或自由线程模型都遇到了作为系统运行的问题。一般情况下,应用程序的进程作为特定的用户,或作为安装过程中设置的默认帐户运行。作为本地系统帐户运行时,
免除了一般的安全检查。这种运行方式是不希望看到的,这也是不能使用单线程或自由线程模型的原因。
单元模型适合于页面范围的对象。这意味着对象应该用 S e r v e r,C r e a t e O b j e c t方式创建,而且不可以赋给 S e s s i o n变量。正如在 2 6,4,3节中讨论过的,单元线程对象会导致会话因某个特定线程“死锁” 。把一个单元线程对象使用 < O B J E C T >标记放到一个应用程序中是可能的。然而,
单元线程对象永远不应该运行在应用级程序级。如在 2 6,3,4节中讨论的,单元线程对象在应用程序范围中和作为系统运行时表现很不理想。
灵活对象是获得性能和灵活性的一种方法。在 IIS 4.0下,灵活对象是配合上自由线程调度器( F T M)的双线程对象。在 IIS 5.0下,新的 C O M +中立线程对象也同样是灵活的。当一个双线程对象配上 F T M时,在线程之间的调用不会因调度和额外的线程切换慢下来。如果双线程对象不配上 F T M,那就会被当作一个单元线程对象来对待。即,它不适合用于会话和应用程序范围。这可以通过设置元数据库中的 A s p Tr a c k T h r e a d i n g M o d e l为 Tr u e来实现,但不推荐这种方法,因为这违背了双线程的语义。
中立线程对象同样是灵活的。这些对象可以直接从任何单元调用,所以适合于存储在会话或应用程序范围内。中立线程对象不应该配上 F T M。
如何在中立线程对象和双线线程对象(配上 F T M)之间选择?如果组件需要在 IIS 4.0 上运行,就必须使用双线程对象(配上 F T M),因为中立线程对象仅能在 Windows 2000的 C O M +
下才可以运行。配上 F T M的对象在缓存其接口指针时要特别小心,保持其接口指针是单元中立的。否则就会发生 R P C _ E _ W R O N G T H R E A D错误。这限制其在配上 FTM 的对象中使用接口指针,或者可以把接口指针存储在全局接口表中。中立线程组件没有这样的限制。
2 6,3,11 多处理器的可扩展性许多人都有这样一个天真的想法:一个在单处理器系统下写成的 ASP 应用程序在 n个处理
798计计 ASP 3 高级编程 下载第 26章 优化 ASP 的性能 计计 799下载器的系统上运行速度将快 n倍。这对于 IIS 3.0来说肯定是不正确的,在 IIS 4.0系统上对双处理器的情况有所改善;直到出现了 IIS 5.0,在 4个或 8个处理器的系统上这种想法才多少有些真实性。
问题在于像 I I S这样的多线程程序需要用“锁”来确保一致性。没有锁,两个或多个线程就可以同时修改共享的数据,使其处于混乱或不一致的状态。考虑下列程序代码放在
g l o b a l,a s a中会发生什么情况。
如果有 2 0 0个用户,一个用户的会话结束时,另一个用户的会话正好开始。下面的情况可能发生(特别是在多处理器系统中),等式右边的数字同时被计算( 2 0 1或 1 4 9),S e s s i o n _ E n d
和 S e s s i o n _ O n S t a r t以不确定的次序两次更新 A p p l i c a t i o n (,N u m b e r” )。第二个被执行的更新将会取得“胜利”,但这是一个错误的“胜利”,因为在任何情况下,这个结果都是错的。它应是 2 0 0,而不是 2 0 1或 1 9 9。
使这些变化一致的正确方法是使用 A p p l i c a t i o n,L o c k和 A p p l i c a t i o n,U n l o c k来避免弄乱
A p p l i c a t i o n (,N u m b e r” )中的共享数据。
一般情况下,所有可能覆盖的执行代码(包括第三方组件)都必须用锁保护共享数据。
如果共享数据经常被读取或修改,那么这些锁就会变“热”,各线程开始争夺“锁”,进而使之成了瓶颈。由于同一时刻只能有一个线程持有这个“锁”,从而使线程变为串行的。所有的线程都在等待获得“锁”,在拥有锁的线程把锁释放之前,其他线程不能做别的工作。这会导致多处理器的可扩展性很差:吞吐量不比单处理器系统更好。更不幸的是,吞吐量实际会有所下降。要了解这是否会发生的一种方法是监视 Wi n d o w s提供的性能监视器( Perfmon 工具)
中的 System|Context Switches/Sec计数器。如果看到每秒超过 1 0 0 0个环境切换,则说明系统遇到了严重的锁争用问题。
Windows 2000和 IIS 5.0为了确保系统提供的各类组件在多处理器系统上运行良好,做了大量的努力。如果你的程序有多处理器的可扩展性问题,那么最大的可能就组件得编写不合适。
虽然锁争用在多处理器上是个大问题,但在单处理器系统上却并不是什么大不了的问题。
原因是单处理器只是给人以同时执行多个线程的错觉。而在多处理器系统中,多线程却实实在在地执行着。在单处理器系统中,在系统的环境切换前,一个线程可以执行好几百万条的
800计计 ASP 3 高级编程 下载指令,然后再让其他的线程运行。一个线程可以得到一个锁,执行一些操作,然后释放锁。
当它持有琐时,就不会产生环境切换。因此,没有其他的线程试图获得锁。在一个有 n个处理器的系统中,n个线程同时运行,两个或两个以上的线程试图获得同一个锁的几率变得非常高。
为了使组件中锁的争用最小化,应该遵循以下的原则:
不要在组件实例之间共享数据。例如,不要有任何的全局数据,如果没有数据共享就不必去保护数据,也不会产生锁的瓶颈(这仅适用于组件本身不被共享的情况) 。
不要在线程之间共享组件的一个实例。没有全局的应用程序范围对象。应用程序范围的组件必须保护被并发访问的实例数据以及全局数据,这两个点通常是不切实际的。
使每个锁的持有时间最小化。当必须锁住数据时,要尽可能晚地获得锁,在锁定期间要做尽可能少的工作,尽可能早地释放锁。使对象线程安全的最简单的方法是在代码的开始处就锁住数据,在代码结束处时释放数据,不过这样做会导致锁的争用问题。
使用尽可能少的锁。如果不需要锁,就不要使用。
使用细小的锁。用一个全局锁来保护所有的数据是比较方便的,但同时会减少并发操作。
例如,如果要建立一个字典组件,可能会为每个字母选择不同的锁。这会允许一个线程更新一个以,h”开头的条目,而另一个在查询以,q”开头的条目。
不要自找麻烦。拥有一个从某种程度上来说较慢的正确程序比拥有一个较快却不安全的程序要好得多。
26.3.12 线程闸门当 A S P接到一个 H T T P请求时,例如一个以,,a s p”结尾的 U R L,它就把这个请求加到请求队列的末尾。容纳 A S P的每个低、中、高隔离进程都有自己的请求队列。性能计数器 A c t i v e
Server Pages/Requests Queued显示了在所有队列中的请求总数。这些线程从请求队列的排头取走请求,编译 A S P网页(如果它未被缓存),执行网页,最后把结果返回给客户。
有时,所有的 A S P工作者线程都会阻塞,等待外部资源可用(例如,等待从数据库传来的响应) 。 C P U的利用率会变低,而且当工作者线程阻塞时,会有一些可以处理的响应被放在等待队列中。但是,没有更多的工作者线程可用。可以通过观察性能计数器 Active Service
Pages|Requests Execution 和 Active Server Pages|Requests Queued 和 P r o c e s s o r ( _ To t a l ) | %
Processor Time 知道是否发生了这种情况。在这样的情况下,对于 A S P来说有较多的工作者线程是较适合的。在其他的情况下,请求执行得较快。此时,拥有许多的线程倒成了缺点;工作者线程消耗系统资源而且增加了环境切换开销。同样,如果机器很忙( C P U的利用率高),
最好能有较少的线程。
在 IIS 4.0中,如果想要调整工作者线程的个数,就必须在注册表中修改 P r o c e s s o r
T h r e a d M a x ( P T M )的设置,然后重新启动 I I S。如果网站的工作量较少,这会非常有效。然而,
在许多的网站上,工作量会戏剧性地一会儿变大。一会儿变小,在这种情况下,手动调整和重新启动 I I S就不太切合实际。
不推荐 P M T的注册表默认设置值。其默认值是 1 0,这意味着 A S P在每个 C P U上为每个 A S P进程中创建 1 0个线程。换句话说,一个双 C P U系统在每个 A S P进程中有 2 0个线程。
IIS 5.0尝试着动态调整工作者线程的个数,以响应工作量的变化。这称为线程闸门
( thread gating) 。有一些相关的设置在元数据库中(现在 PTM 设置称为 A s p P r o c e s s o r T h r e a d M a x,
驻留在元数据库中,其默认值是 2 5 / C P U,而不是 1 0) 。随 I I S提供的 a d s u t i l脚本能列出 We b服务的设置。结合 f i n d s t r的使用,可以找到所有包括,T h r e a d”一词的设置。
如果线程闸门启用,线程闸门就会根据 C P U的利用率( 0 % ~ 1 0 0 %)调整线程的上限。每
A s p T h r e a d G a t e Ti m e S l i c e m s(默认上极限值 1 0 0 0 m s)调整一次。线程的上限值就是在某一时刻在 A S P进程中的最大工作线程者数量。最低值是一个 C P U一个线程;最大值是 A s p P r o c e s s o r
T h r e a d M a x乘以 C P U的数量。如果 C P U的利用率低于 A s p Tr e a d G a t e L o a d L o w(默认值为 5 0 %),
那么线程上限就应提高(运行更多的线程) 。如果 C P U的利用率在 A s p T h r e a d G a t e L o a d H i g h
(默认值为 8 0 %)之上,线程上限就应调低(允许较少的线程运行) 。如果 C P U的利用率处于这两者之间,那么不必调整。根据现在的 C P U利用率的情况,调整改变线程上限。无论何时,
当工作者线程将要执行请求时,它进入线程闸门。如果闸门禁用,线程就会立刻通过线程闸门。如果它启用了,请求就只有在有效的线程少于线程上限时才会被处理。如果线程上限被突破了,线程就会被迫休眠至少是 AspThreadGateSleepDelay ms(默认值为 1 0 0 m s) 。为了确保线程在线程闸门上花费的时间不会太多,它最多只能被迫休眠 AspThreadGate SleepMax ms。
请记住,线程上限每 AspThreadGateSlice ms 调整一次。
一般来说,线程闸门似乎比人工在注册表中设置和重新启动 I I S更有效,因为它在负载发生变化时会做出响应。如果更喜欢人工控制,只需将 AspThreadGateEnable 设置为 f a l s e,然后修改 A s p P r o c e s s T h r e a d M a x就可以了。
26.3.13 设置元数据库下面将列出最重要的元数据库( m e t a b a s e)设置。这些都可以通过使用 A D S I接口检索和改变。下面有一个简单的示例脚本,它是一个在 I I S中附带的脚本,使得维护元数据库更容易。
可以在 \ I n e t p u b \ A d m i n S c r i p t s目录中找到 a d s u t i l,v b s。
1,AspAllowSessionState的设置在元数据库中把默认的 Tr u e改为 F a l s e,就可以获得性能的提升。这个设置在一些实际需要利用 S e e s i o n对象的网页中必须显式覆盖。通过在网页顶部使用 < % @Enable SessionState =
True %> 来改变设置。
2,AspProcessorThreadMax 的设置这在 2 6,3,1 2节中已经论述过。
3,AspRequestQueueMax的设置正如在下一节讨论性能计数器时提到的,对于队列中的请求的默认限制值在 IIS 5.0中增加了。而且,这个设置的效率取决于应用程序的特性。如果请求的执行时间非常短,那么在队第 26章 优化 ASP 的性能 计计 801下载
802计计 ASP 3 高级编程 下载列中等待的时间就会很短,那么有理由增加这个限制。
4,AspQueueConnectionTe s t Ti m e的设置这对于 IIS 5.0来说是新的设置,而且它显著影响网络应用的性能。在 IIS 4.0中,对于一个请求的处理总是在它从队列中移走时开始的。在下一个版本中,如果请求在序列中等待时间过长,超过这个“序列连接测试时间”,服务器就会检查一下在请求开始处理之前这个客户是否还继续连接在服务器上。这个功能适用于解决一些不切实际的用户通过不断在同一页上发出无数请求来尝试加快速度的问题,缺省值是 3秒。是否改变这个数字取决于应用程序的类型。
5,AspSessionMax和 A s p S e s s i o n Ti m e O u t的设置默认的设置是不限制并发会话的数量,而是限制单个会话的长度为 2 0分钟。实际情况,
对于利用会话的应用程序,谨慎地减少会话超时,以减少所需的服务器开销。但是,如果并发的会话数量无限增长,那就有必要用一个会话数量最大值来限制。
6,AspScriptEngineCacheMax的设置脚本引擎缓存在内存中的最大数量的缺省值为 1 2 5。应根据应用程序内容的类型对其进行调整。如果有几千个单独的网页,增加缓存数量可能有一些益处。
26.3.14 性能计数器性能计数器是监视和调整网络应用程序的核心,有许多性能计数器可供选择。 Wi n d o w s
附带的 Performance Monitor工具提供了对大量计数器的监视能力。在这一节中,将介绍应该注意观察的一些性能计数器,而对其他的只需偶尔检查一下就行。 Performance Monitor的界面如图 2 6 - 3所示。
图 26-3 Performance Monitor的界面通过在视窗的主视区右击鼠标,可以选择 Add Counters,这时弹出一个 Add Counters对话框,如图 2 6 - 4所示。在这里可以选择所需的监视器,并把它加上。
有一个建议,就是使用 Add Counter会话框中的 E x p l a i n按钮。这时会在屏幕上显示关于选定的性能计数器的简单解释窗口,如图 2 6 - 5所示。
1,Active Server Pages\的 Debugging Requests,Active Server Pages\Errors During Script
R u n t i m e,Active Server Pages\Errors From
ASP Preprocessor和 Active Sever Pages\Errors
From Script Compilers
我在做基准工作时,学会了一些重要的内容。
我为了测试和研究 WA S工具,给网络服务器加了一些网页。在数据集合中未加入任何性能计数器,因此,在做分析和调整时,看不到任何数字。
我从一台测试机上的浏览器向服务器发出请求网页的信号时,对应用程序进行得如此顺利感到吃惊。实际上,这儿有一个包含文件错误,因此没有脚本代码被执行。我应获取统计数据,因为服务器只发送了错误信息。应该检查 A S P错误计数器和调试计数器,以确保应用程序功能正确。
2,Active Server Pages\Requests Executing
和 Active Server Pages\Requests Queued
这两个计数器在繁忙的站点上是系统管理员经常查看的计数器。虽然关于如何对这两个性能计数器进行解释的各种各样的理论已经广为流传,但是应该说,它们的含义是明确和显而易见的。
当一个 A S P网页的请求到达时,将排队等待执行。一旦有足够的系统资源可以用来处理这个请求,不管是进行编译然后执行,还是从缓存中取出来执行,该请求总是被从队列中移出,然后处理。当一个请求到达服务器时,如果请求队列的长度没有达到其上限值
R e q u e s t Q u e u e M a x,就将其置于队列中。这个上限值在 IIS 5.0中不再在注册表中设置。修改它的过程变成了访问元数据库。由于 IIS 5.0 的性能的改善,默认值已经从 5 0 0增加到了 3 0 0 0。
这两个计数器之间的相互作用和相互影响被人们误解了。而且从 IIS 3.0到 IIS 4.0到 5,0它们有少许的变化。 IIS 5.0与前面的几个版本相比较,虽然变化不大,但性能的提高却是显著的。在 IIS 4.0中,检查程序优先把脚本放在队列中,检查 Requests Queued和 R e q u e s t s
E x e c u t i n g的总和。毕竟目的不是使在队列中等待的总的请求数目最大化,而是使它们被迫等待的时间最少。根据在单处理器计算机上的 IIS 4.0的默认值,由于请求到达的速率大于处理它们的速率,当队列中有 4 9 0个请求的时候,服务器会发出“服务器太忙”的信号。如果加上
1 0个已经从队列中移出并正在执行的请求,正好 5 0 0个。对于新的版本,这个值是与排队等待的请求数比较的。
虽然本章并不致力于元数据库及其操作处理,但在此仍要写一些 J S c r i p t代码来查看和设置 R e q u e s t Q u e u e M a x的值。减少这个值来测试在大工作量下的表现,是一个非常有价值的试验。检查 A S P在传送静态文件时当达到限制值时的性能,可以在应用程序由于某种不可预见的原因使得在传输方面遇到大问题时有所准备。试验结束后,不要忘记恢复这个值。把以下代码放进扩展名为,j s的文件,然后执行这个文件。
第 26章 优化 ASP 的性能 计计 803下载图 26-4 Add Counters对话框窗口图 26-5 解释性能计数器的界面
3.Active Server Pages\Request Execution Ti m e和 Active Server Pages\Request Wait Ti m e
这两个性能计数器简单地跟踪最近的请求的数量。根据最后一个执行的网页的特性,
Request Execution Ti m e的变化非常大。不断观察这两个数字可以帮助理解应用程序的特性。
执行时间的上升可能表明共享资源(如数据库)的负荷增加或执行了运算量大的脚本。竞争
Critical Session的线程间的环境切换,强迫一个请求在其执行状态停留更长的时间。如果每秒到达的请求速率超过脚本完成执行的速率,等待时间会开始变长。监视这些性能计数器有助于识别性能问题的根源。
4,Active Server Pages\Requests/Sec
Active Server Pages\Requests/Sec经常用于了解所有的性能指标和整个网络的实际情况。
其平均值、最小值和最大值仅仅反映了现在可以看到的数据。为了更好地随时掌握性能,应当使用 P e r f o r m a n c e M o n i t o r日志功能。它可以存储大量的数据,而且允许定时测量数据。使用这一功能,我们可以使以前做不好的工作做得更有效。
为 A S P提供的性能计数器包括一个扩展的项目的列表。每一个请求都被分类列入这个列表中。定期检查它们对于理解应用程序的工作特点十分重要。如果从列表中看出了的应用程序性能的一个出人意料的跳跃变化,跟踪这些变化可以很快查明其原因。另外,理解这些性能计数器的含义也十分重要。因为它们有些重叠,容易引起误解。
5,Active Server Pages\Requests To t a l,Requests Succeeded和 Requests Failed
首先,有一个请求总数的记录。它可以被分为两个主要的部分;一部分是成功的请求,
另一部分是失败的请求。当然,希望每个请求都成功,但不可能总是这样。因此失败的请求总数又按各种各样的失败原因进一步划分。
(1) Active Server Pages\Requests Disconnected
一些请求的失败是由于底层的网络通信问题。对于这个问题应该有一定容忍限度。网络不时会有传送失误。如果失败的数量剧增或者应用程序仅在可控的单独的网络中运行,这类问题可能成为最主要问题。
(2) Active Server Pages\Requests Rejected
被拒绝的请求是那些被告知“服务器忙( Server Too Busy),的请求。,服务器忙”的信息对于一个迫切希望得到结果的用户来说从来不是什么好消息。
(3) Active Server Pages\Requests Timed Out
请求被置于队列中等待执行。在默认状态下,它们在队列中不会发生超时,但这种情况会有所改变。假如一个请求在队列中发生超时,或者在执行过程中超脚本的超时设置值,就会认为是一个失败的请求,这个数字的逐步上升表明了性能方面有问题,需要引起注意。
(4) Active Server Pages\Requests Not Authorized
I I S提供了几种安全访问网页的模式,假如,无法提供正确的身份证明,就会认为这个请
804计计 ASP 3 高级编程 下载求失败。这种情况少量发生是允许的,但是如果这种情况大量发生,可能就意味着一些错误,
或者某些用户正在试图访问他们无权访问的受保护内容。不管怎么说,假如发生了急剧变化,
查找错误的来源是个很好的办法。
(5) Active Server Pages\Requests Not Found
这是另一个被认为几乎不能发生的而未报警的失败原因。用户经常会猜测请求失败的网页的名字,他们总是猜错。而且各种各样的实体采用不同算法决定什么网站使用什么样的服务器软件和如何使用它们。所以,在公共网站上,希望有一定数量的对 d e f a u l t,a s p的请求,即使服务器被设置为寻找另一个缺省网页。这个计数器的突然变化,表明有线路断开,应该进行检查。日志文件可以提供准确的文件名。
6,Active Server Pages\Template Cache Hit Rate
用缓存的已经编译过的脚本处理请求的百分比对于网络站点的性能来说是非常重要的。
网络服务器的管理员会问为什么这个百分比不能达到 1 0 0 %。这是不可能的。为了向 C a c h e中缓存一个模板,必须首先有一个缓存遗漏( cache miss) 。在 2 6,3,1 3节有关于调节最大缓存数的讨论。没有一个固定的数字目标,它是一个基于特定应用程序的一个函数。有些网站缓存有好几千个网页。缓存的效率随着其容量的增加而下降。缓存 A S P是非常重要的,关心这个数字并且使用它来帮助调整服务器,但不应该被它所困扰。
7,Process(inetinfo)\Private Bytes
假如在较长的一段时间内被分配的内存数量不断增加,这说明有内存泄漏。假如服务器在缓存被填充后稳定地运行在某些状态上,然后突然出现一个稳定增加专用字节的过程,这一般意味着在同一个应用程序中加入了新的定制的 C O M对象。在最好的情况下,查找内存泄漏的原因是十分困难的,NT Resource Kit中包括一个叫作 d h,e x e的工具,这个工具可以给我们一些帮助。确定问题原因的最简单的办法是使用强度测试工具来对对象的属性和方法进行测试,了解专用字节的出现是否对应于相应的用途。
8,System\Context Switches/sec
在 2 6,3,11节已经讨论,对于研究锁的争用问题是非常有效的。
26.4 各种小技巧最后,介绍一些非常有用的小技巧
26.4.1 stm的重命名技巧
# i n c l u d e的语法中提供了一个非常好的方法,用它可以封装用于多个页面的功能。它也提供了一个简单的途径包含页面中不使用的功能。对于一个网络开发者来说,编写应用程序时,
在包含文件中增加一个通用函数或包含一个其他包含文件需要的页面是非常简单的。假如不仔细管理,可能影响网络应用程序的性能。网络服务器包含了一种查看使用 # i n c l u d e的结果的方法。把一个扩展名为,a s p的页面拷贝为扩展名为,s t m的文件,然后在浏览器发出一个对它的请求。处理器端包含的处理将 # i n c l u d e包含的所有文件找出来,但是不用脚本引擎来处理脚本。
代码返回到浏览器用于观察。不用说,这不应该出现在生产机器上,不应把你的源代码暴露于世。用这种方法可以看到脚本和所有包含的脚本,仔细观察会发现这比预期的要大。即使并未使用某个函数,如果它包含在页面中,则仍然占用服务器资源。而且必须分析它,如果第 26章 优化 ASP 的性能 计计 805下载它在缓存中,同样占用内存。
26.4.2 避免嵌套的包含一个普遍的问题是就多余的包含和嵌套的包含。例如,假设一些核心函数包含在一个叫作 c o r e,i n c的文件中。当编写错误处理代码 e r r o r,i n c时,在 # i n c l u d e中包含了 c o r e,i n c文件。后来,
在编写数据管理程序 d a t a,i n c时,在 # i n c l u d e中包含了 e r r o r,i n c和 c o r e,i n c文件。这时已经包含了两次 c o r e,i n c文件。更进一步,还可能在一般的 A S P网页中包含 d a t a,i n c,同时再次包含 c o r e,i n c
文件。现在当请求网页时,就要分析三个 c o r e,i n c拷贝。如果不把此文件拷贝为扩展名为,s t m
的文件,就无法看到这个现象。
26.4.3 不使用非脚本映射的文件扩展名不要使用,,i n c” 文件扩展名。作为一个预防意外地显示包含文件的内容的安全措施,一般的处理方法是绝对不用其他的扩展名来重新命名包含文件。假如想要用一种简单的方法区别仅包含库代码的文件,可以修改文件的名字,而不是修改文件的扩展名。假如使用的文件扩展名不在脚本映射中(并且不是,,i n c” ),那么 I I S就会把文件直接发送到浏览器中。考虑一下假如包含文件包含 SQL Server管理员的口令或连接字符串,将会发生什么样的事情:当文件发送至浏览器而不是在服务器上执行时,用户看到了他们不应该看到的信息。
26.4.4 关闭脚本调试器可能每一个写 A S P应用程序的人都曾忘记关闭脚本调试器,而且会责怪自己为什么忽略了脚本调试器。在某些情况下,使用调试器来单步执行 A S P页面十分有用。在 I n t e r n e t
Services Manager的 Application Configuration属性对话框的 App Debugging选项卡中,有一个
Enable ASP server-side script debugging复选框。不要在实际运行的计算机上选择该选项。网络服务器为了使调试器如所希望的那样工作,把 A S P设置为单线程方式执行,当调试器被激活时,机器不处理另外的请求。这个错误需要花费很长时间来寻找,当找到问题的来源时,
发现仅是这个复选框没有取消选择,网络服务器仅用一个线程来完成所有的工作。在一些错误条件被满足之前,性能降低的原因是不会显露出来的,几天甚至几周后,由于启用调试器而引起的单线程停止时将会引起注意。
26.4.5 最小化脚本块转换许多 A S P开发者用脚本语言编写页面时,他们会忍痛包含尽可能少的 A S P代码。这不利于代码的读取和维护。假设,用数据库的数据填充一个表,使用尽可能少的脚本代码:
所有这些代码都由分析器转换为 R e s p o n s e,w r i t e调用来执行。在本质上,代码首先必须在内部转换为类似于下面的代码:
806计计 ASP 3 高级编程 下载第 26章 优化 ASP 的性能 计计 807下载假如编写解释性较强的代码,使用尽可能大、尽可能少的块,那么性能会稍微好一点,
代码更容易维护,原始代码可以改写如下:
前面 1 3行的中间代码可以减少为 3行,这使得执行和编译时的性能大大提高,不要希望从这种改变中可以得到巨大的收获,但坚持这样做可以有长期回报。
26.4.6 不要混用脚本引擎
J S c r i p t和 V B S c r i p t的比较已经作为一个问题提出来,现在关于其性能还有一些问题要讨论。
过去,使用 V B S c r i p t,可以使用 On Error Resume Next;使用 J S c r i p t,可使用规则表达式。对于新的脚本引擎,这些非常必要的特性在这两种语言中都成为可能。 J S c r i p t现在支持 t r y - c a t c h,
而 V B S c r i p t提供规则表达式对象。
由于这些新的脚本引擎的发布,对于 J S c r i p t和 V B S c r i p t的争论有了明确的答案:
使用哪一个都可以,但不能同时使用两者。
下面解释一下。使用 V B S c r i p t编写一个页面,而使用 J S c r i p t编写另一个页面,这对于满足编写同一应用程序的不同开发者的喜好可能是必要的。但在同一个页面上使用 J S c r i p t和
V B S c r i p t会涉及到性能费用问题,服务器必须实例化并尝试缓存两个脚本引擎而不是一个。
如果为了获得某种特性而不得不这么做,性能的损失似乎可以接受的。但是,假如不是某些事情必须使用一种语言,而另外一种语言不可用的话,应该采用同一种语言。
26.4.7 在“费时”操作前使用 R e s p o n s e,I s C l i e n t C o n n e c t e d
防止服务器做不必要的工作是获得性能提升的最简单的方法,在进行费的时操作前使用
R e s p o n s e,I s C l i e n t C o n n e c t e d是一种减少服务器工作量的有效而简单的方法。如果客户端不再连接,就没有理由继续处理。这种检查不应该被过分使用,因为它本身也占用时间和资源。
当系统处于轻负荷时,用户可能不需要较长时间等待响应,执行长时间的不必要的数据库查询需要等待较长时间。
对于 IIS 4.0系统,标准的方法是把这种检查置于页面的顶端,这在 IIS 5.0中是多余的,假
808计计 ASP 3 高级编程 下载如请求已经在队列中超过 3秒,服务器就会自动执行该检查。这种检查放在大页面的中间时也可能效果不错。
26.4.8 使用 < O B J E C T >标记当使用 < O B J E C T >标记声明对象后,在实际使用它们时,才创建它们。当对象只能在某些条件成立时使用时,这就非常有效,多数应用程序并不使用根据第一个会话请求存储在
A p p l i c a t i o n和 S e e s s i o n中的每一个对象。延迟创建对象,直到需要时才创建,可以加快第一个请求并省略了一些不必要的工作,当然前提是,需要这个对象的页面不被请求。
26.4.9 不使用 O n S t a r t P a g e和 O n E n d P a g e
过去在 A S P内使用对象需要提供 O n S t a r t P a g e和 O n E n d P a g e方法。现在这已经不再需要了。
事实上,调用这两个方法执行空操作迫使服务器做一些额外的没有必要的工作。假如提供了这些方法,它们将被调用,即使它们不完成任何工作。没有它们,服务器会更快地实例化和释放对象。
26.4.10 发挥客户端的作用通过研究可以惊奇地发现,对于一些 A S P代码,其中大约有 9 0 %用于检查客户端发送的数据的有效性及检查错误。对于一个网络应用程序,有许多类似的工作可以交给客户端来处理。
网页每次在服务器和客户之间来回一次都需要消耗 C P U的时间,假如在发送请求前,将要提交的数据已经被预计算,并且是有效的,网络服务器就不会有那么多的工作要做。请不要误解这种策略,不是说在 A S P页中可以取消错误检查和数据有效性检查。如果浏览器立刻检查出错误,用户的感觉更好,省去在客户端与服务器之间往返来报告这些错误,对于像信用卡号中有多余的数字或者在 e m a i l地址中缺少 @等情况,这是一种非常好的方法。
何种类型的工作可以由客户端来完成?网络上有算法检查邮政编码、信用卡号和电话号码的有效性。仅需简单地加入一些客户端的脚本代码就能完成这些任务。根据窗体所需字段的含义,在执行提交之前验证用户输入的内容为可接受的内容。大多数用户使用支持脚本的浏览器。输入姓名的字段不应该允许输入数字。主要的信用卡公司已经建立了他们的信用号的前缀字母和卡号长度及公式。这使得验证输入非常容易,至少能够保证次序正确。
随着新的版本的发布,客户端的能力更加健全。现在不需要大量的客户端代码,也不涉及额外的请求,在浏览器内部对数据进行分类和操作已经变得非常简单。不要忘了定期地重新检查已经建立的 A S P应用程序,优化程序,利用客户端的能力,减轻服务器的某些工作。
这些新的能力包括 X M L,A D O(与未连接的记录集),R D S和 D H T M L。
26.5 小结正如所见,在提高基于网络的应用程序的性能时,需要考虑许多不同的方面,不要急于立即把方方面面都搞清除。首先要关心并理解一个网络站点的主要用途和执行方式,学会找到瓶颈,这样就可以把精力集中于能获得最大的效益的地方。假如速度的变慢是由于资源的争用或数据库查询运行时间太长引起的,而你却致力于把复杂的脚本逻辑转换进组件中,其结果肯定让你失望。长时间地跟踪服务器的性能数据,可以对服务器上的负载及服务器如何响应有更进一步的理解。有时改善硬件本身是最有收获的努力。
网络应用程序在不断地变化与发展,它们的能力也在不断进步,提供这些能力的应用程序也变得越来越复杂和越来越大,不要以为只要一次花一些时间调整性能,就能一劳永逸,
如果已经完成了性能调整工作,说明已经了解了这个应用程序,并且知道了限制吞吐量的最主要原因,就可以通过改进它使应用程序运行得更快。在大多数情况下,这并不需要竭尽全力,但是,对性能的考虑应该包含在网络应用程序设计的所有过程之中。
在下一章中,将讨论有关 We b阵的详细内容,这个概念在前面已经涉及。
第 26章 优化 ASP 的性能 计计 809下载