1 前言
性能优化的主要目标是提高“并发用户数量”,“吞吐量”,“可靠性”这样几个指标。
本质上说,性能优化的工作应该是多方面的,要做到“点面结合、由表及里”。比如:从代价的角度来考虑,应尽量做到改动量小,易实施;从用户角度看,应做到快速响应或快速提示;从软件结构的角度看,又要兼顾到系统结构的合理性和可扩展性。由此不难发现,在尝试一些改进方法时往往很难做到面面俱到。
举一个简单的例子:
在一个业务逻辑类中,我们封装了一些处理方法,其中有一个方法的功能是查找一个节点ID在XML文件是否已经存在。那我们自然会想到写两个方法:
XmlDocument LoadXML(string strFileID) //加载XML
bool CheckIDExisit(string strFileID,string strID) //判断节点是否存在
而且,加载XML的方法在其他地方还可以重用;表面上看,这段代码的结构和功能都没有问题。可是在运行时,如果你的逻辑中直接或间接调用了LoadXML多次的话,你会发现程序很慢。原因就在于加载XML文件是个耗时动作,解决的方法很简单,我们再提供几个方法即可:
bool CheckIDExisitByXml (string strXml,string strID) //判断节点是否存在
或 bool CheckIDExisitByXml (XmlDocument objXml,string strID) //判断节点是否存在
这样,我们就可以通过“一次加载”实现多次借用,效率明显提升。所以,在软件结构设计时就应将可重用“珍贵”数据源的因素考虑进来。(这里的“珍贵”数据源是指那些经过复杂处理或长时间计算才得到的各种对象或记录集)。
性能优化的工作又应是长期的,因为我们的工作始终是建立在OS,Web Server, DB Server, Complier & Program Language等等的基础上的。如果你熟悉.NET, JAVA,IIS, J2EE, 你就会发现有些功能或API这个平台提供了,另一个却没有;所以更多时候我们需要过渡的解决方案,等到新版本出来时,我们可能就会抛弃过渡方案直接配置或更简便的实现一些功能。[...]
2 需求篇 性能优化的第一步是看看需求是否合理,这是对项目本身的一次回检。某种意义上说,是一种逃避原则。但如果从软件工程的角度来说这是必须的,因为客户的需求是无止境的,而任何软件都是有生命期的,OS都是这样何况应用软件。我们总是希望用户显示与业务逻辑分开的越远越好,却忽略了一个基本问题:两者终归要衔接起来,如何定义两者之间的I/O关系,让它们能有效的相互配合并最终让用户满意是非常重要的。
所以,在性能优化时回检需求就是要把用户交互定义好,使之更科学化。从业界发展动态看,现在已经有专门的人在研究用户交互,这就像传统行业里的所谓“工业设计”一样,正越来越被重视!
在回检需求时往往会“修改需求”,这时应该结合“需求定义人员”和“开发人员”两方面的意见,因为各方角度不同,一定要取长补短。
3 交互响应篇 前面提到性能优化时可按“由表及里”的顺序,这主要有两方面的考虑:
第一, 这是用户直接看到的东西,见效快;
第二, 改动难度比改动内核要小。
基于B/S结构的应用程序有前台(用户)与后台(Server)交互的问题,所以交互响应过程实际包括“后台计算”与“加载到客户端”两个过程。那么很显然,我们如果尽量减少需要下载到客户端的数据量,会减小响应时间。
根据测试,我们发现将4万条记录绑定到Grid的时间在35s左右,而实际上我们不会在页面一下子显示这么多条记录,用户也不可能一下子浏览这么多记录。通常我们使用分页的方式,而所谓的分页只不过是重新绑定一下数据。所以,如果如果我们每次只绑定所请求的那一页则到客户端的数据量会陡降。这就是我们提出的“计算全部数据,加载局部数据”的思路(如下图)。
图 3-1 “即时按页绑定”原理图
我们再从用户的角度看另外两个问题,曾使用ASP应用程序的人会发现ASP.NET应用程序使用时刷新频率很高,一个小小的动作都要提交到服务端去处理。从软件设计的角度看,我们觉得很合理,因为没有耦合且逻辑可重用。可是“鱼与熊掌不可兼得”,我们还是应该采取折中的手法。回到我们的系统中来,我们发现多数页面在对于使用较频繁的“增-删-改”操作时,都是每一次操作都从数据库重新读,重新绑定。如此频繁的刷新,用户不会很认可,同时如果数据量大也会影响交互时间。
实际上,如果数据是显示在Grid中,那么删除和修改时根本不需要重新Load, 直接用控件本身的方法就可以了,虽然也会提交但与重新绑定还是有明显区别的,速度也快得多!对于TreeView则“增-删-改”都不需要重新Load,因为它不需要分页。
另一个问题是对于复杂并可能耗时的计算过程,用户虽可理解,但还是应该给出提示或进度条。这并不属于性能优化的范畴,但却是重要的UI规范,建议纳入测试要求。关于进度条的显示有两种方式:
1 前台显示等待或完成进度,后台处理完了,前台进度条关闭,处理结果显示;
2 提交任务到后台后,转到一个等待页面,等后台完成后转到确认页面。这种方式通常基于XmlHttpRequest[13]技术,在后台创建单独的计算线程,其优点是可以避免后台过于繁忙导致第一种显示方式中客户端长时间没有反映,连进度条都不动了。
4 部署篇 部署其实是一个很大的概念,涵盖了软件和硬件。这里我们暂将系统部署结构、软件设置、硬件配置都纳为部署范围。关于怎样去部署一个软件系统这里就不赘述了,仅将一些具体做法列举出来。
4.1 ASP.NET
在有大数据量传输时,经常会遇到“out of memory”的异常。这时可调节machine.config文件中processModel子项中的memoryLimit 属性的值,使得.NET可以利用更多的内存。
4.2 其他
4.2.1优化配置Server & IIS
4.2.1.1扩大IIS高速缓存
服务器保留了一部分内存空间用作IIS高速缓存,为将来的请求存储对象,这样IIS就可从高速缓存中检索对象而不用从硬盘中检索。调整IIS高速缓存的容量需要修改注册表,表项如下:
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\InetInfo\Parameters\MemoryCacheSize
=0x 1E84800(类型为REG_DWORD,using hexadecimal notation.)
也可设为十进制,范围0-4GB,缺省值为3072000(3MB)。一般来说此值最小应设为服务器内存的10%。
IIS通过高速缓存系统句柄、目录列表以及其他常用数据的值来提高系统的性能。这个参数指明了分配给高速缓存的内存大小。如果该值为0,那就意味着“不进行任何高速缓存”。在这种情况下系统的性能可能会降低。如果你的服务器网络通讯繁忙,并且有足够的内存空间,可以考虑增大该值。必须注意的是修改注册表后,需要重新启动才能使新值生效。
4.2.1.2调整IIS占用CPU时间
服务器的CPU处理器能力总是有限的。哪一个应用程序占用处理器的时间最长,谁的性能就能得到最大的提高。
(1)在NT的控制面板中,双击系统图标。
(2)单击性能标签。
(3)在应用程序性能下将游标拖到None的位置,这样就可以使所有正在运行的服务,包括IIS,使用处理器的时间达到最大值。
(4)选择最大化网络应用程序的总处理能力。然后单击“OK。”
4.2.1.3协议及相关优化
(1)为了提高性能和节约资源,应该只运行需要的协议。
(2)应该将IIS服务器,设置为独立的服务器,不要让服务器去承受域控制器要求的额外负荷。
(3)可以把NT服务器的页交换文件分布到多个物理磁盘上,注意是多个“物理磁盘”,分布在多个分区上是无效的。另外,不要将页交换文件放在与Windows NT引导区相同的分区中。
(4)使用磁盘镜像或磁盘带区集可以提高磁盘的读取性能。
(5)关于日志的记录,应该采用文件记录而不是记录到ODBC数据源。此外,还可以在记录期间增加用来记录日志的内存缓冲区的容量来减少磁盘的活动。该缓冲区的缺省容量值为64KB。
(6)最好把所有的数据都储存在一个单独的分区里。然后定期运行磁盘碎片整理程序以保证在存储Web服务器数据的分区中没有碎片。使用NTFS有助于减少碎片。
(7)虽然SSL可以提供相当可靠的加密传输。但是所需的额外开销会导致IIS服务器速度下降,尤其是在处理大型文件的时候。所以应该只对确实需要保护的目录进行SSL加密。
4.2.1.4 调整失效时间
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\InetInfo\Parameters\ObjectCacheTTL=0x8CA0.
4.2.1.5 调整最大线程数
HKEY_LOCAL_MACHINE\SYSTEM\ CurrentControlSet\Services\w3SVC\ASP\Parameters,增加ProcessorThreadMax,减小这个值,看看性能的变化;或者增大这个值。)
4.2.1.6 注册表中的其他可优化项
以“HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\InetInfo\Parameters\”为父节点;
CacheSecurityDescriptor Indicates whether security descriptors are cached for file objects. A value of 1 enables this feature. A value of 0 disables this feature. When enabled (the default setting), security descriptors for files are saved when caching a file object. As long as the file is cached, IIS will not need to re-ac
查看本文来源