• ASP.NET 应用程序性能优化(转)


     备注:写的不错,方便了程序的优化处理,让大家少走了很多弯路

     

    1 前言

    性能优化的主要目标是提高“并发用户数量”,“吞吐量”,“可靠性”这样几个指标。

    本质上说,性能优化的工作应该是多方面的,要做到“点面结合、由表及里”。比如:从代价的角度来考虑,应尽量做到改动量小,易实施;从用户角度看,应做到快速响应或快速提示;从软件结构的角度看,又要兼顾到系统结构的合理性和可扩展性。由此不难发现,在尝试一些改进方法时往往很难做到面面俱到。

    举一个简单的例子

    在一个业务逻辑类中,我们封装了一些处理方法,其中有一个方法的功能是查找一个节点IDXML文件是否已经存在。那我们自然会想到写两个方法:

    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_DWORDusing hexadecimal notation.

    也可设为十进制,范围0-4GB,缺省值30720003MB)。一般来说此值最小应设为服务器内存的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-access the file to determine access rights for new users. This value is most useful for sites that authenticate users and not useful for sites that allow anonymous access.

    CheckCertRevocation Indicates whether IIS checks to see if a client certificate is revoked. If you issue your own certificates and make local certificate checks, you might want to enable this feature. Otherwise, the feature should be disabled, which is the default. A value of 1 enables this feature.

    DisableMemoryCache Indicates whether IIS memory caching is enabled or disabled. By default, memory caching is enabled (meaning this value is set to 0). Disable memory caching only for testing or development purposes.

    ListenBackLog Specifies the maximum number of active connections that IIS maintains in the connection queue. The default value is 15 and the range of acceptable values is from 1 to 250.

    MaxCachedFileSize Determines the maximum size of a file that can be placed in the file cache. IIS will not cache files that are larger than this value. The default value is 262,144 bytes (256 KB).

    MaxConcurrency Specifies how many threads per processor should be allowed to run simultaneously if there is a pending input/output (I/O) operation. The default value (0) allows IIS to control the number of threads per processor. You can also set a specific value.

    MaxPoolThreads Sets the number of pool threads to create per processor. Each pool thread watches for a network request for a CGI application and processes it. This value does not control threads that are used by ISAPI applications. By default, the value is set to 4. On a single processor system, this means that only four CGI applications could run simultaneously.

    MemCacheSize Sets the maximum amount of memory that IIS will use for its file cache. If IIS does not need this much memory, it will be left for other applications to use. By default, IIS uses 50 percent of the available memory. The valid range is from 0 megabytes to the total amount of physical memory available in megabytes.

    ObjectCacheTTL Sets the length of time (in milliseconds) that objects are held in memory. If the object hasn't been used in this interval, it is removed from memory. The default value is 30 seconds (300,000 milliseconds).

    PoolThreadLimit Sets the maximum number of pool threads that can be created on the server. This limit is for all IIS threads. The default value is twice the size of physical memory in megabytes.

    4.2.1.7禁用不必要的服务:

    禁用专用 Web 服务器不需要的 Windows 2000 服务。方法是:单击开始,依次指向程序、管理工具,然后单击计算机管理。在计算机管理(本地)下,展开服务和应用程序,然后单击服务。当前所运行服务的状态 列中显示已启动 。以下服务是专用 Web 服务器上不需要的:

       警报器
     
      剪贴簿
     
      计算机浏览器
     
      DHCP 客户端
     
      DHCP 服务器
     
      传真服务
     
      文件复制
     
      红外线监视器
     
      Internet 连接共享
     
      信使
     
      NetMeeting 远程桌面共享
     
      网络 DDE
     
      网络 DDE DSDM
     
      NWLink NetBIOS
     
      NWLink IPX/SPX
     
      后台打印程序
     
      TCP/IP NetBIOS 支持服务
     
      电话
     
      Telnet
     
      不间断电源
     ================================================
     
      记下与要停止的服务有依存关系的那些服务。方法是:
     
      双击所需的服务。例如,双击信使。
     
      单击依存关系 选项卡。
     
      在服务名 依赖这些服务列表中(其中,服务名是所选服务的名称),记下该服务依赖的那些服务。
     
      在这些服务依赖服务名列表中,记下没有该服务就无法启动的那些服务。
     
      单击确定。
     
      禁用所需的服务。方法是:
     
      右键单击要禁用的服务,然后在出现的快捷菜单上单击属性
     
      在启动类型列表中,单击禁用。
     
      如果要立即停止服务,请单击停止。如果显示停止其他服务 对话框,依赖于该服务的其他服务也将被停止。请记下受影响的服务,然后单击是。
     
      单击确定。该服务的启动类型 列中会显示禁用
     
      重复执行第 4 步,禁用其他不必要的服务。
     
      备注:禁用每个服务之后,应测试 Web 服务器计算机是否运行正常。这样就最大程度地减少了禁用可能需要的服务而带来的影响。
      
      备注:如果 IIS 服务器是 Windows 2000 域成员,则必需 TCP/IP 支持服务,以便将组策略正确地应用到计算机中。

    4.2.1.8 最大化网络应用程序数据吞吐量

    在工作内存中运行IIS 5.0 进程可分页代码。方法是:
     
      在桌面上右键单击网上邻居,然后在出现的快捷菜单中单击属性
     
      右键单击所需的本地连接 图标,然后在出现的快捷菜单中单击属性
     
      在此连接使用下列选定的组件列表中,单击“Microsoft 网络的文件和打印机共享(但不要清除其复选框),然后单击属性。
     
      单击最大化网络应用程序数据吞吐量,然后单击确定 两次

    4.2.1.9优化后台服务的性能

    IIS 5.0 进程 (Inetinfo.exe) 作为后台服务运行。要提高后台服务的性能,请按以下步骤操作:
     
      单击开始,指向设置,然后单击控制面板。
     
      在控制面板中,双击系统。
     
      单击高级 选项卡,然后单击性能选项。
     
      在应用程序响应下,单击后台服务,然后单击确定 两次。
     
      退出控制面板

    4.2.1.10 最小化 IIS 5.0 日志记录

    禁止对不需要的 Web 站点、虚拟目录或文件及文件夹进行日志记录。方法是:
     
      单击开始,依次指向程序、管理工具,然后单击Internet 服务管理器。
     
      展开“*服务器名,其中 服务器名 Web 服务器的名称。
     
      找到所需的项,然后用右键单击该项。在出现的快捷菜单上,单击属性。例如,右键单击默认 Web 站点,然后在出现的快捷菜单上单击属性
     
      执行下列操作之一:
     
      如果选择 Web 站点,则单击主目录 选项卡。
      
      - -
     
      如果选择虚拟目录,则单击虚拟目录 选项卡。
      
      - -
     
      如果选择实际目录,则单击目录 选项卡。
     
      单击日志访问复选框,将其清除,然后单击确定。
     
     
      要禁止整个 Web 站点的日志记录,请单击Web 站点 选项卡,单击启用日志记录 复选框,将其清除,然后单击确定。
     
      退出“Internet 信息服务管理单元。

    4.2.1.11启用带宽限制

    限制各 Web 站点可用的网络带宽。方法是:
     
      启动“Internet 服务管理器
     
      展开“*服务器名,其中服务器名 Web 服务器的名称。
     
      右键单击所需的 Web 站点(例如,默认 Web 站点),然后在出现的快捷菜单上单击属性
     
      单击性能 选项卡,然后单击启用带宽限制复选框,将其选中。
     
      在最大网络使用框中,键入所需的值,然后单击确定。
     
      退出“Internet 信息服务管理单元。

    4.2.1.12 限制处理器使用

    限制 Web 站点对处理器的占用量。方法是:
     
      启动“Internet 服务管理器
     
      展开“*服务器名,其中服务器名 Web 服务器的名称。
     
      右键单击所需的 Web 站点(例如,默认 Web 站点),然后在出现的快捷菜单上单击属性
     
      单击性能 选项卡,然后单击启用进程限制复选框,将其选中。
     
      在最大程度使用 CPU”框中,键入所需的值。
     
      单击强制性限制复选框,将其选中,然后单击确定。
     
    备注:如果不启用强制性限制 选项,则不会强制执行最大程度使用 CPU”的限制。在 Web 站点超过其允许的 CPU 使用限制时,即会在事件日志中写入事件。
     
      退出“Internet 信息服务管理单元。

     4.2.1.13限制 Web 站点连接

    限制各 Web 站点可用的连接数量。方法是:
     
      启动“Internet 服务管理器
     
      展开“*服务器名,其中服务器名 Web 服务器的名称。
     
      右键单击所需的 Web 站点(例如,默认 Web 站点),然后在出现的快捷菜单上单击属性
     
      在连接下,单击限于。
     
      在连接框中,键入要允许的连接数量。
     
     
      备注:连接的每个客户端大约同时使用四个连接。例如,将连接数限制在 200 大约允许 50 名用户访问 Web 站点。
     
      单击确定,然后退出“Internet 信息服务管理单元。

    4. 2.1.14 使用保持 HTTP 连接

    默认情况下,能够使用保持 HTTP 连接。要验证是否启用了保持 HTTP 连接,请按以下步骤操作:
     
      启动“Internet 服务管理器
     
      展开“*服务器名,其中服务器名 Web 服务器的名称。
     
      右键单击所需的 Web 站点(例如,默认 Web 站点),然后在出现的快捷菜单上单击属性
     
      在连接下,确认已启用保持 HTTP 连接复选框已被选中,然后单击确定。
     
      退出“Internet 信息服务管理单元。

     

    4.2.2 优化配置DBServer

    4.2.2.1 SQLServer

    内存是影响Microsoft SQL Server系统性能的一个重要因素。

    SQL Server数据库安装时将为具有32MB物理内存的机器缺省配置16MB可用内存,16MB物理内存的机器缺省配置4MB可用内存。应在Microsoft SQL Server数据库安装后进行内存选项(Memory)设置。为了确定SQL Server系统最适宜的内存需求,可以从总的物理内存中减去Windows 2000 Server需要的内存以及其它一些内存需求后综合确定。
     以下是SQL Server内存选项(Memory)设置方法

     (1)Microsoft SQL Server程序集中启动SQL Enterprise Manager

     (2)Server Manager窗口中选择“Server”菜单选项;
     (3)在“Server”菜单中选择“Configurations”选项;

     (4)在“Server Configuration”对话框中选择”Configuration”标签,

     (5)选中“Memory”项目,在“Current”栏填入新值;
     (6)停止并重新启动SQLServer服务,使设置生效。

     

    合理扩充虚拟内存、增大SQL Server可用内存
      SQL Server系统确实需要扩大可用内存时,应在磁盘空间充足的情况下扩充供虚拟

    内存,并相应增大 SQL Server可用内存。具体做法是,系统管理员首先扩充服务器的虚拟内存,然后再参考上表增大SQL Server可用内存,关键是要根据系统的负载情况综合决定是否扩充。

    使用tempinRAM
     SQL Server使用tempdb临时数据库作为一些查询连接操作时排序或创建临时表的工作

    空间。将tempdb创建在RAM中可以使系统操作性能有较大提高,而且因为tempdb在每次重启动服务器时都重建,这样即使有非正常的关闭也是较为安全的,例如停电故障。要将tempdb创建在RAM中,可以使用sp_configure进行设置,具体用法请参阅有关资料。
     由于tempdbinRAM使用的内存是由系统从内存体单独分配的,与SQL Server的内存选
    项设置的可用内存池是分开的,使用tempdbin RAM将减少整个系统的可用内存,应根据SQL Server和服务器运行情况进行配置,否则就可能适得其反,影响系统性能。另外,适当增加tempdb数据库空间,即使不使用tempdbin RAM,也可以提高数据库的运行速度。
     注意事项:在生产环境中SQL Server不要设置小于32MB内存,而且数据库服务器上尽量扩充供虚拟内存、增大SQL Server可用内存,应考虑物理内存使用状况和磁盘空间;在可能的情况下,要为系统留有部分额外的内存,这样在服务器上打开一个服务或添加一个进程且不改变SQL Server内存配置时,不致于使NT服务器的运行速度受到影响(变得很慢),一般认为最小为2MB最大为20MB

     

    4.2.3硬件提升

    4.2.3.1 CPU/内存

    如果测试确定存在处理器问题,您的第一个选择当然就是将处理器升级或切换到多处理器计算机。如果确定要升级处理器,应确保它有最大的 L2 缓存,IIS 将因此而受益,因为它的许多指令路径都包括多个组件,它们在高速缓存中运行时速度会大大加快。

    计算机名\内存\可用内存 - 该计数器跟踪系统中的可用内存总量。操作系统尝试将该值保持在 4 MB 以上。为了达到最佳性能,该值最好为内存总量的 5%

    4.2.3.2 硬盘

    不要将日志文件与 Web 页存储在同一个硬盘上。这将阻止硬盘日志记录线程干预检索 Web 页的线程。

    优化 Web 页存储。站点上的所有相关 Web 页应该存储在同一个逻辑分区,这样可以提高文件系统缓存的性能。同时,Web 页文件不应有任何碎片,这样可以极大地加快读取单个文件的速度。

    如果使用Ultra2SCSI硬盘,可以显著提高IIS的性能。网络接口卡,内存的升级自然不用多言。

     


     

    5 Session管理篇

    HTTP 协议之所以能够获得如此大的成功,其设计实现的简洁性和无状态连接的高效率是很重要的原因。而为了在无状态的 HTTP 请求和有状态的客户端操作之间达到平衡,产生了服务器端会话 (Session) 的概念。Session的引入极大地方便了Web编程,但与之对应的Session管理变得异常重要。目前ASP.NET可以通过“进程内”、“进程外专用状态管理服务”和“SQL Server状态服务管理”三种方式来进行状态管理。对于默认的“进程内”管理方式只实现了一个进程内的基于内存的状态管理,故而存在很多问题:

    1.所有的 Session 数据都保存在 Web 服务的进程中,会造成服务器支持会话数量受到服务器内存资源的限制问题,同时也因为大量非活动会话导致内存被无效占用。

    2.服务器进程崩溃会导致所有的会话数据丢失。

    回到我们的实际系统,目前我们使用Session变量大致有四种用途:

    5-1 Session变量使用范围

     

    显然,前三种方式都是小数据量的,我们这里主要关注第四种方式——Session数据集变量。

    把整个数据集存放在Session中,主要是为了用于后续处理或二次加工或用户翻页时重新绑定,一般情况下我们在编码时会忽略数据集的大小给Web-Server和交互时间带来的影响。实际上,一个超大数据集(记录数在10万条以上)所占用的空间是相当可观的,如果有数个并发,Web-Server的内存会急剧紧张。下表是实际测试的关于SQL执行时间的统计。

     

    记录数(万)

    执行时间(秒)

    10

    4

    11

    6

    15

    10

    20

    11

    30

    12

    40

    16

    50

    19

    5-1 数据查询执行时间统计表

    有一种解决方法是将复杂查询的查询条件存于Session中。这种方法简洁又轻便,但是也会造成由于频繁查询导致db-server繁忙的局面(50万条记录的查询时间大于15s);理想的解决办法是实现在数据库查询时可进行分页或者说可以按页查询,这时Session中完全可只存放查询条件,因为交互数据量也不大。OracleSQLServer2005中可以比较方便地实现此功能,但SQLServer2000中实现起来比较麻烦,一般都会用存储过程。

    考虑到已有系统在实现上并没有考虑大数据量而且也不是每个页面或逻辑都会出现大数据量,所以不应该采用单一的Session管理方案。实际上,我们可以构造具有自适应性的数据访问执行器和Session管理器,动态地去按不同的方式返回和存储执行结果。由于目前系统的Session管理模式为“进程内”(INPROC)模式且由于IIS没有提供平滑的可配置二级(内存/硬盘)缓存介质切换 ,所以可自行构造虚拟存储空间,缓解并发压力。下面是该方案的总体结构图:

    5-2 全局Session管理结构图

     

    首先,我们来看一下数据访问执行的流程图(图5-3)。

    由图5-3可知,我们在执行查询时会设定一个时间阀值,如果在规定时间内执行完毕说明数据量不是很大那么直接将结果集返回给前台;如果超时了,则会返回一个小数据集(比如 Top 1000),然后在后台另辟线程继续查询动作并将最终结果集保存到Session,注意这时的数据集在一般情形下是很大的但也可能由于服务器繁忙造成等待,所以我们会通过Session Manager去动态按适合的方式保存。

    5-3 数据访问执行器流程图

     

    下面是SessionManager类结构的简单示意图,

    5-4 PageSessionManager类结构简单示意图

    必须说明这只是一个简单示意图,在具体实现时这个结构会大大丰富。比如,要加上当前Session的保存方式和保存数量等。实现PageSessionManager的目的是为了规范Session的使用尤其是Session数据集变量的使用,我们会根据数据集的大小来自动选择存储方式,下面是存储Session数据集变量的流程图。

    5-5 保存数据集变量流程图

    可以看到,我们在SessionManager中引入了一种新的存储方式——虚拟存储(Virtual Store)。其目的显然是为了缓解Web-Server内存压力,提高并发度。经检测,这种方式还是比较快的;如果把XML保存到数据库,则在获取XML或读取XML时会发生超时异常。实际上,我们是自行构造了一种进程外Session管理器,那么也自然需要进行Session的清除和失效管理,我们可以在后台运行专门的失效管理进程,具体实现方法可参考下图。

    5-6 虚拟存储示意图

    另一个问题是虚拟存储文件与Http进程的对应关系如何建立。这并不难,我们只要创建一个GUID存放在同名的实际Session中,虚拟Session的文件名以此GUID为标识即可。

    与存储相对应的,在通过SessionManager获取Session值的时候,SessionManager也要自动根据当前存储方式反馈相应结果,其实现过程并不复杂,这里就不赘述了。

    总的来说,这套解决方案的特点是提高并发度和保证快速响应,但对某些问题的处理也有不便。比如,查询需要二次加工的记录集时希望一次得到全部数据集(即使很大),这时必须设定相应属性值告诉AdaptiveExecutor,使之按照指定方式执行;还有就是大数据量时,分页控件在查询结束时不能瞬时得到总页数。

     

     


     

    6 代码篇

    这里的代码级优化是指对具体的代码实现特别是某个业务逻辑的算法的改进。在前言中举的一个例子就属于代码优化。代码优化是深层次的,需要非常熟悉业务逻辑和数据流,所以难度也是最大的。但在除去业务逻辑之后,我们还是可以对编码技巧或者算法结构达成共识的。本篇主要列举一些实际编码过程中基于性能考虑应当掌握的方法和注意点。

     

              不要使用不必要的Session,和ASP中一样,在不必要的时候不要使用Session

              不使用不必要的Server Control

              不使用不必要的ViewState

              不要用Exception控制程序流程

              禁用VBJscript动态数据类型

              使用存储过程完成数据访问

              只读数据访问不要使用DataSet

              关闭ASP.NETDebug模式

              使用ASP.Net Output Cache缓冲数据

              尽量用SQL返回DataGrid需要绑定的DataSet,尽量不要对DataSet进行二次加工,特别不要对DataSet进行大量删除,实践证明这很慢。不如复制部分数据。

              尽量不要对DataSet二次加工或者在通过DataSet拼成对象集;显然,若有40000条记录就意味着要拼>=40000次的对象

              尽量把查询数据的数据库操作次数压缩到最少,尽量1-2次数据库操作就可完成;如果对查询得到的DataSet的每项数据再进行查询,那么意味着如果有40000条记录,至少要执行400001次数据库操作,加上遍历DataSet、生成对象的时间,是相当惊人的

              注意优化数据库查询操作,比如无条件查询时不要通过离散值一个一个取;

              注意限制大数据量查询操作,比如预计一个页面如果一个条件都不加会出现很多数据,则强制至少加一个查询条件;

              不要在页面加载时默认选择全部数据,尽管可以方便后续操作,但用户会以为还没有操作就这么慢

              建议尽量用比较高效的SQL代替后续复杂的DataSet二次加工

              仅在需要的时候打开数据库连接

              一旦数据库操作完毕,一定关闭连接

              在关闭连接时记得删除临时对象

              在关闭连接前,确保关闭任何用户定义事务

              若要利用连接池,不要使用应用角色(application roles)

              显示非交互性数据,使用SQLDataReader可以获得最佳性能

              通过在SQL中得到html码比用DataGrid Component格式化数据显示具有更好的性能

              一般而言,在循环中使用索引(index)比使用集合(collection)具有更好的性能。因为CLR (Common Language Runtime)有时可以根据数据索引进行优化,而集合则不然

              注意共享那些经过复杂处理或漫长查询才得到的数据

              在页面跳转时记得终止当前页面的处理

              如果页面加载或后台计算中有一些数据不相关的处理逻辑,可以考虑采用多线程;页面加载也可以考虑逐步加载(Response.Flush())

              有大量连接的字符串操作不要使用+,改用StringBuilder

     


     

    7 Reference

    1. http://www.microsoft.com/technet/prodtechnol/windows2000serv/technologies/iis/maintain/optimize/perflink.mspx

    2.       http://www0.ccidnet.com/tech/web/2001/09/28/58_3369.html

    3.       http://msdn.microsoft.com/library/chs/default.asp?url=/library/CHS/cpguide/html/cpconaspoptimization.asp

    4.       http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnpag/html/scalenetchapt06.asp

    5.       http://www.microsoft.com/china/technet/itsolutions/net/maintain/netopsgd.asp

    6.       http://www.programfan.com/showarticle.asp?id=2548

    7.       http://www.microsoft.com/china/msdn/library/webservices/asp.net/CachingNT2.mspx

    8.       http://www.programfan.com/showarticle.asp?id=2548

    9.       http://www.microsoft.com/china/msdn/library/webservices/asp.net/CachingNT2.mspx

    10.   http://www.SQL-server-performance.com/asp_net_performance.asp

    11.   http://www.cnblogs.com/flier/archive/2004/08.html

    12.   http://soft.yesky.com/SoftChannel/72342380468043776/20050223/1914105.shtml

    13.   http://jibbering.com/2002/4/httprequest.html

     


  • 相关阅读:
    算法视频库下载常用网址(转载)
    Python study 1
    $X-Real-Ip和$X-Forwarded-For的区别
    python装饰器
    python迭代器和生成器
    python函数动态参数详解
    python常用模块
    python 正则re模块
    pycharm5新版注册
    老男孩python自动化运维作业2
  • 原文地址:https://www.cnblogs.com/dagon007/p/143196.html
Copyright © 2020-2023  润新知