企业宣传,产品推广,广告招商,广告投放联系seowdb

阅历分享 提高ASP.Net运行程序性能的方法

如今写一个的web运行程序变得十分的繁难,许多的程序员都不愿花时期去构建一共性能良好的运行程序。本文将要讨论提高web运行程序性能的十慷慨法。我将不限于只讨论asp.net运行程序的内容,由于它们只是web运行程序的一个子集。本文也不能提供一个完整提高web运行程序性能的指南,由于这要求一本书的篇幅。本文只提供一个提高web运行程序性能的良好的开始。(剩下的只要咱们自己缓缓钻研了)。

在上班这外,我经常去攀岩,在每次攀岩之前,我都会重温一下攀岩线路图及看一下前面的成功的攀岩者的倡导。由于咱们要求它们的成功阅历。雷同的,当你要求修正某个有性能疑问的程序或许是要开发一个高性能的站点时,你也要求学习怎样样写一个高性能的web运行程序。

你兴许会想到把你的运行程序划分红不同的逻辑层。你也或许听过三层物理架构或N层架构,这是最罕用的架构形式,它把不同的程序性能物理的调配给各个配件来口头。这样,假设咱们想提高运行程序的性能的话,加一些配件就可以到达目的了。按理说这种方法能提高运行程序的性能,但是咱们应该防止经常使用这种方法。所以,只需有或许,咱们都应该把asp.net页面和它用到的组件放到一个运行程序中运转。

由于散布式的布署,要用到webservices或许Remoting,它将使运行程序的性能降低20%或许更多。

关于数据层有点不同,最好还是把它独立进去布署,用一个独自的配件来运转它。只管这样,但是数据库依然是运行程序性能的瓶颈。因此,当你想优化你的程序的时刻,首先想到的中央就应该是优化数据层了。

在修正运行程序的出现性能疑问的中央之前,你要先确认出疑问的中央的程序看起来很严密,性能剖析器关于查找运行程序哪些中央破费了多长时期十分有用。这些中央是咱们用直觉觉得不到的。

本文讨论两种类型的性能优化:一种是大的性能优化(bigoptimizations),如用asp.net的Cache;另一种是小的性能优化(tinyoptimizations)。小幅的性能优化有时刻十分有用。你只对你的代码作一个小的改到,然后一次性调用它一千或一万次。作一次性大的性能优化,你会出现你的运行程序的速度会有一个很大的优化。作一次性小的性能优化,兴许每次恳求只能提高一微秒,但是假设每天的恳求量很大的话,那么运行程序就有很清楚的性能优化。

数据层的性能

当你要优化一个运行程序的性能的时刻,你可以按上方的顺序上班:你的代码要访问数据库?假设要,访问数据库频率怎样样?雷同,这种测试方法也可以用在用webservices或Remoting的程序代码中。本文将不讨论用Webservices和Remoting的程序优化的疑问。

假设在你的代码中有一段必定访问数据库的恳求,而你在其它的中央又看到成功雷同的性能的代码,那么你首先要优化它。修正和完善继续测试,除非你有一个十分大的性能疑问,你的时期最好花在优化查问,衔接数据库,前往数据集的大小,以及一次性查问往前往的时期上。

依据阅历的总结,让咱们来看看十个能协助你优化你的运行程序性能的阅历,我将按将它们优化效率的多少从大到小小依次说明。

一、前往多个数据集

审核你的访问数据库的代码,看能否存在着要前往屡次的恳求。每次往复降低了你的运行程序的每秒能够照应恳求的次数。经过在单个数据库恳求中前往多个结果集,可以缩小与数据库通讯的时期,使你的系统具备裁减性,也可以缩小数据库主机照应恳求的上班量。

假设你是用灵活的SQL语句来前往多个数据集,那我倡导你用存储环节来代替灵活的SQL语句。能否把业务逻辑写到存储环节中,这个有点争议。但是我以为,把业务逻辑写到存储环节外面可以限度前往结果集的大小,减小网络数据的流量,在逻辑层也不用在过滤数据,这是一个善报情。

用SqlCommand对象的ExecuteReader方法前往一个强类型的业务对象,再调用NextResult方法来移动数据集指针来定位数据集。示例一演示了一个前往多个ArrayList强类型对象的例子。只从数据库中前往你要求的数据可以大大的减小你的主机所耗用的内存。

二、对数据启动分页

ASP.NET的DataGrid有一个十分有用的性能:分页。假设DataGrid准许分页,在某一时辰它只下载某一页的数据,另外,它有一个数据分页的济览导航栏,它让你可以选用阅读某一页,而且每次只下载一页的数据。

但是它有一个小小的缺陷,就是你必定把一切的数据都绑定到DataGrid中。也就是说,你的数据层必定前往一切的数据,然后DataGrid再依据页过滤出页所要求的数据显示进去。假设有一个一万条记载的结果集要用DataGrid启动分页,假定DataGrid每页只显示25条数据,那就象征着每次恳求都有9975条数据都是要摈弃的。每次恳求都要前往这么大的数据集,对运行程序的性能影响是十分大的。

一个好的处置打算是写一个分页的存储环节,例子2是一个用于对Northwind数据库orders表的分页存储环节。你只要求传页码,每页显示的条数两个参数出去,存储环节会前往相应的结果。

在主机端,我专门写了一个分页的控件来处置数据的分页,在这里,我用了第一个方法,在一个存储环节外面前往了两个结果集:数据记载总数和要求的结果集。

前往的记载总数取决于要口头查问,例如,一个where条件可以限度前往的结果集的大小。由于在分页界面中必定要依据数据集记载的大小来计算总的页数,所以必定要前往结果集的记载数。例如,假设一共有1000000条记载,假设用where条件就可以过滤成只前往1000条记载,存储环节的分页逻辑应该知道前往那些要求显示的数据。

三、衔接池

用TCP来衔接你的运行程序与数据库是一件低廉的事情(很费时的事情),微软的开发者可以经过用衔接池来重复的经常使用数据库的衔接。比起每次恳求都用TCP来连一次性数据库,衔接池只要在不存在有效的衔接时才新建一个TCP衔接。当封锁一个衔接的时刻,它会被放到池中,它依然会坚持与数据库的衔接,这样就可以缩小与数据库的TCP衔接次数。

当然,你要留意那些遗记关的衔接,你应在每次用完衔接后马上封锁它。我要强调的是:无论什么人说.netframework中的GC(渣滓搜集器)总会在你用完衔接对象后调用衔接对象的Close或许Dispose方法显式的封锁你的衔接。不要希冀CLR会在你构想的时期内关掉衔接,只管CLR最终都要销毁对象和封锁边接,但是咱们并不能确定它究竟会在什么时刻做这些事情。

要用衔接池优化,有两条规定,第一,关上衔接,处置数据,然后封锁衔接。假设你必定在每次恳求中屡次关上或封锁衔接,这好过不时关上一个边接,然后把它传到各个方法中。第二,用相反的衔接字符串(或许用相反的用户标识,当你用集成认证的时刻)。假设你没有用相反的衔接字符串,如你用基于登录用户的衔接字符串,这将不能应用衔接池的优化性能。假设你用的是集成的论证,由于用户很多,所以你也不能充沛应用衔接池的优化性能。.NETCLR提供了一个数据性能计数器,它在咱们要求跟踪程序性能特性的时刻十分有用,当然也包括衔接池的跟踪了。

无论你的运行程序什么时刻要连在另一台机子的资源,如数据库,你都应该重点优化你连资源所花的时期,接纳和发送数据的时期,以及往前往之间的次数。优化你的运行程序中的每一个处置点(processhop),它是提高你的运行的性能的登程点。

运行程序层蕴含与数据层衔接,传送数据到相应的类的实例以及业务处置的逻辑。例如,在CommunityServer中,要组装一个Forums或许Threads汇合,然后运行业务逻辑,如授权,更关键的,这里要成功缓存逻辑。

四、ASP.NET缓存API

在写运行程序之前,你要做的第一件事是让运行程序最大化的应用ASP.NET的缓存性能。

假设你的组件是要在Asp.net运行程序中运转,你只需把System.Web.dll援用到你的名目中就可以了。然后用HttpRuntime.Cache属性就可访问Cache了(也可以经过Page.Cache或HttpContext.Cache访问)。

有以下几条缓存数据的规定:

第一,数据或许会被频繁的被经常使用,这种数据可以缓存。

第二,数据的访问频率十分高,或许一个数据的访问频率不高,但是它的生活周期很长,这样的数据最好也缓存起来。

第三是一个经常被疏忽的疑问,有时刻咱们缓存了太少数据,通常在一台X86的机子上,假设你要缓存的数据超越800M的话,就会出现内存溢出的失误。

所以说缓存是有限的。换名话说,你应该预计缓存集的大小,把缓存集的大小限度在10以内,否则它或许会出疑问。在Asp.net中,假设缓存过大的话也会报内存溢出失误,特意是假设缓存大的DataSet对象的时刻。

这里有几个你必定了解的关键的缓存机制:

首先是缓存成功了“最近经常使用”准则(aleast-recently-usedalgorithm),当缓存少的时刻,它会智能的强迫肃清那些无用的缓存。

其次“条件依赖”强迫肃清准则(expirationdependencies),条件可以是时期,关键字和文件。以时期作为条件是最罕用的。在asp.net2.0中参与一更强的条件,就是数据库条件。当数据库中的数据出现变动时,就会强迫肃清缓存。

五、预恳求缓存

在前面,我提到过即使咱们只对某些中央作了一个小小的性能改良也可以取得大的性能优化,我十分青睐用预恳求缓存来优化程序的性能。

只管CacheAPI设计成用来保留某段时期的数据,而预恳求缓存只是保留某个时期的某个恳求的内容。假设某个恳求的访问频率高,而且这个恳求只要求提取,运行,修正或许更新数据一次性。那么就可以预缓存该恳求。咱们举个例子来说明。

在CS的论坛运行程序中,每一个页面的主机控件都要求获取用于选择它的皮肤(skin)的自定义的数据,以选择用哪个样式表及其它的一些共性化的物品。这外面的某些数据或许要长时期的保留,有些时期则不然,如控件的skin数据,它只要求运行一次性,然后就可以不时经常使用。

要成功预恳求缓存,用Asp.net的HttpContext类,HttpContext类的实例在每一个恳求中创立,在恳求时期的任何中央都可以经过HttpContext.Current属性访问。HttpContext类有一个Items汇合属性,在恳求时期一切的对象和数据都被参与到这个汇合中缓存起来。和你用Cache缓存访问频率高数据一样,你可以用HttpContext.Items缓存那些每个恳求都要用到的基础数据。它面前的逻辑很繁难:咱们向HttpContext.Items中参与一个数据,然后再从它外面读出数据。

六、后盾处置

经过上方的方法你的运行程序应该运转得很快了,是不是?但是在某些时刻,程序中的一次性恳求中或许要口头一个十分耗时的义务。如发送邮件或许是审核提交的数据的正确性等。

当咱们把asp.netForums1.0集成在CS中的时侯,发现提交一个新的帖子的时刻会十分的慢。每次新增一个帖子的时侯,运行程序首先要审核这个帖子是不是重复提的,然后用“badword”过滤器来过滤,审核图片附加码,作帖子的索引,把它参与到适合的队列中,验证它的附件,最后,发邮件到它的订阅者邮件箱中。显然,这个上班量很大。

结果是它把少量的时期都花在做索引和发送邮件中了。做帖子的索引是一项很耗时的操作,而发邮件给订阅都要求衔接到SMTP服务,然后给每一个订阅者都发一封邮件,随着订阅用户的参与,发送邮件的时期会更长。

索引和发邮件并不要求在每次恳求时触发,现实形态下,咱们想要批量的处置这些操作,每次只发25封邮件或许每隔5分钟把一切的要发的新邮件发一次性。咱们选择经常使用与数据库原型缓存一样的代码,但是失败了,所以又不得不回到VS.NET2005。

咱们在System.Threading命名空间下找到了Timer类,这个类十分有用,但却很少有人知道,Web开发人员则更少有人知道了。一旦他建了该类的实例,每隔一个指定的时期,Timer类就会从线程池中的一个线程中调用指定的回调函数。这象征着你的asp.net运行程序可以在没有恳求的时刻也可以运转。这就是后以处置的处置打算。你就可以让做索引和发邮件上班在后盾运转,而不是在每次恳求的时刻必定口头。

后盾运转的技术有两个疑问,第一是,当你的运行程序域卸载后,Timer类实例就会中止运转了。也就是不会调用回调方法了。另外,由于CLR的每个进程中都有许多的线程在运转,你将很难让Timer取得一个线程来口头它,或许能口头它,但会延时。Asp.net层要尽量少的经常使用这种技术,以缩小进程中线程的数量,或许只让恳求用一小局部的线程。当然假设你有少量的异步上班的话,那就只能用它了。

这里没有足够的空间有贴代码,你可以从中下载示例程序,请下载BlackbeltTechEd2004的示例程序。

七、页面输入缓存和代理服务

Asp.net是你的界面层(或许说应该是),它蕴含页面,用户控件,主机控件(HttpHandlers和HttpModules)以及它们生成的内容。假设你有一个Asp.net页面用来输入html,xml,imgae或许是其它的数据,对每一个恳求你都用代码来生成相反的输入内容,你就很有必要思考用页面输入缓存了。

你只需繁难的把上方的这一行代码复制到你的页面中就可以成功了:

你就可以有效的应用第一次性恳求里生成的页面输入缓存内容,60秒后重重生成一道页面内容。这种技术其实也是运用一些低层的CacheAPI来成功。用页面输入缓存有几个参数可以性能,如上方所说的VaryByParams参数,该参数示意什么时刻触发重输入的条件,也可以指定在HttpGet或HttpPost恳求形式下缓存输入。例如当咱们设置该参数为VaryByParams=”Report”的时刻,default.aspx?Report=1或许default.aspx?Report=2恳求的输入都会被缓存起来。参数的值可以是多个用分号隔开参数。

许都没无看法到当用页面输入缓存的时刻,asp.net也会生成HTTP头集(HTTPHeader)保留在下游的缓存主机中,这些信息可以用于MicrosoftInternet安保性中以及减速主机的照应速度。当HTTP缓存的头被重置时,恳求的内容会被缓在网络资源中,当客户端再次恳求该内容时,就不会再从源主机上取得内容了,而间接从缓存中取得内容。

只管用页面输入缓存不提高你的运行程序性能,但是它能缩小了从的主机中加载已缓存页面内容的次数。当然,这仅限于缓存匿名用户可以访问的页面。由于一旦页面被缓存后,就不能再口头授权操作了。

八、用IIS6.0的KernelCaching

假设你的运行程序没用运转在IIS6.0(windowsserver2003)中,那么你就失去了一些很好的提高运行程序性能的方法。在第七个方法中,我讲了用页面输入缓存提高运行程序的性能的方法。在IIS5.0中,当一个恳求到到来IIS后,IIS会把它转给asp.net,当运行了页面输入缓存时,ASP.NET中的HttpHandler会接到该恳求,HttpHandler从缓存中把内容取进去并前往。

假设你用的是IIS6.0,它有一个十分好的性能就是KernelCaching,而且你不用修正asp.net程序中任何代码。当asp.net接到一个已缓存的恳求,IIS的KernelCache会从缓存中获取它的一份拷贝。当从网络中传来一个恳求的时,Kernel层会获取该恳求,假设该恳求被缓存起来了,就间接把缓存的数据前往,这样就完工了。这就象征着当你用IIS的KernelCaching来缓存页面输入时,你将取得无法置信的性能优化。

在开发VS.NET2005的asp.net时有一点,我是专门负asp.net性能的程序经理,我的程序员用了这个方法,我看了一切日报表数据,发现用kernelmodelcaching的结果总是最快的。它们的一个独特的特色就是网络的恳求和照应量很大,但IIS只占用了5%的CPU资源。这是令人惊奇的。有许多让你经常使用用IIS6.0的理由,但kernelcashing是最好的一个。

九、用Gzip紧缩数据

除非你的CPU占用率太高了,才有必要用优化主机性能的技巧。用gzip紧缩数据的方法可以缩小你发送到服务端的数据量,也可以提高页面的运转速度,同时也缩小了网络的流量。怎样样更好的紧缩数据取决于你要发送的数据,还有就是客户端的阅读器支不支持(IIS把用gzip紧缩后的数据发送到客户端,客户端要支持gzip能力解析,IE6.0和Firefox都支持)。这样你的主机每秒能多照应一些恳求,雷同,你也缩小了发送照应的数据量,也就能多发送一些恳求了。

好信息,gzip紧缩曾经被集成在IIS6.0中了,它比IIS5.0中gzip更好。可怜的是,在IIS6.0中启用gzip紧缩,你不能在IIS6.0的属性对话中设置。IIS开发团队把gzip紧缩性能开收回来了,但他们却忘了在治理员窗口中让治理员能很繁难的启用它。要启用gzip紧缩,你只能深化IIS6.0的xml性能文件中修正它的性能。

除了阅读本文以外,只好再看看BradWilson写的<<IIS6紧缩>>一文();另外还有一篇引见aspx紧缩基础常识的文章,EnableASPXCompressioninIIS。但是要留意,在IIS6中灵活紧缩和kernelcashing是互斥的。

十、主机控件的ViewState

ViewState是asp.net中的一个特性,它用于把生成页面要用的一形态值保留在一个暗藏域中。当页面被回传到主机时,主机要解析,校验和运行ViewState中的数据以恢复页面的控件树。ViewState是一个十分有用的特性,它能耐久化客户端的形态而不用cookie或许主机的内存。大局部的主机控件都是用ViewState来耐久化那些在页面中与用户交互的元素的形态值。例如,用以保留用于分页的页的页码。

用ViewState会带来一些负面的影响。首先,它放大的主机的照应和恳求的时期。其次,每次回传时都参与了序列化和反序列化数据的时期。最后,它还消耗了主机更多的内存。

许多的主机控件很趋于经常使用ViewState,如妇孺皆知的DataGrid,而有时刻是没有必定经常使用的。自动状况下是准许经常使用ViewState的,假设你不想经常使用ViewState的话,你可以在控件或页面级别把封锁它。在控件中,你只需把EnableViewState属性设为False就可以了;你也可以在页面中设置,使它的范畴裁减到整个页面中:

假设页面无需回传或许每次恳求页面只是出现控件。你就应该在页面级别中把ViewState关掉。

总结

我只是提供我几个我以为有助于提高写高性能的asp.net运行程序的技巧,本文提到的提高asp.net性能的技巧只是一个起步,更多的信息请参考《ImprovingASP.NETPerformance》一书。只要经过自己的通常,你能力找到对你的名目最有协助的技巧。但是,在你的开发旅程中,这些技巧可以起一些指点性的作用。在软件开发中,这些都不是相对有用的,由于各个名目都不一样。

宿愿经过本文的引见,能够给你带来协助。

【编辑介绍】

© 版权声明
评论 抢沙发
加载中~
每日一言
不怕万人阻挡,只怕自己投降
Not afraid of people blocking, I'm afraid their surrender