Asp.net教程:提高ASP.Net应用程序性能的方法二
五、 预请求缓存
虽然Cache API设计成用来保存某段时间的数据,而预请求缓存只是保存某个时期的某个请求的内容。如果某个请求的访问频率高,而且这个请求只需要提取,应用,修改或者更新数据一次。那么就可以预缓存该请求。我们举个例子来说明。
在CS的论坛应用程序中,每一个页面的服务器控件都要求得到用于决定它的皮肤(skin)的自定义的数据,以决定用哪个样式表及其它的一些个性化的东西。这里面的某些数据可能要长时间的保存,有些时间则不然,如控件的skin数据,它只需要应用一次,而后就可以一直使用。
要实现预请求缓存,用Asp.net 的HttpContext类,HttpContext类的实例在每一个请求中创建,在请求期间的任何地方都可以通过HttpContext.Current属性访问。HttpContext类有一个Items集合属性,在请求期间所有的对象和数据都被添加到这个集合中缓存起来。和你用Cache缓存访问频率高数据一样,你可以用HttpContext.Items缓存那些每个请求都要用到的基础数据。它背后的逻辑很简单:我们向HttpContext.Items中添加一个数据,然后再从它里面读出数据。
六、 后台处理
通过上面的方法你的应用程序应该运行得很快了,是不是?但是在某些时候,程序中的一次请求中可能要执行一个非常耗时的任务。如发送邮件或者是检查提交的数据的正确性等。
当我们把asp.net Forums 1.0集成在CS中的时侯,发现提交一个新的帖子的时候会非常的慢。每次新增一个帖子的时侯,应用程序首先要检查这个帖子是不是重复提的,然后用“badword”过滤器来过滤,检查图片附加码,作帖子的索引,把它添加到合适的队列中,验证它的附件,最后,发邮件到它的订阅者邮件箱中。显然,这个工作量很大。
结果是它把大量的时间都花在做索引和发送邮件中了。做帖子的索引是一项很耗时的操作,而发邮件给订阅都需要连接到SMTP服务,然后给每一个订阅者都发一封邮件,随着订阅用户的增加,发送邮件的时间会更长。
索引和发邮件并不需要在每次请求时触发,理想状态下,我们想要批量的处理这些操作,每次只发25封邮件或者每隔5分钟把所有的要发的新邮件发一次。我们决定使用与数据库原型缓存一样的代码,但是失败了,所以又不得不回到VS.NET 2005。
我们在System.Threading命名空间下找到了Timer类,这个类非常有用,但却很少有人知道,Web开发人员则更少有人知道了。一旦他建了该类的实例,每隔一个指定的时间,Timer类就会从线程池中的一个线程中调用指定的回调函数。这意味着你的asp.net应用程序可以在没有请求的时候也可以运行。这就是后以处理的解决方案。你就可以让做索引和发邮件工作在后台运行,而不是在每次请求的时候必须执行。
后台运行的技术有两个问题,第一是,当你的应用程序域卸载后,Timer类实例就会停止运行了。也就是不会调用回调方法了。另外,因为CLR的每个进程中都有许多的线程在运行,你将很难让Timer获得一个线程来执行它,或者能执行它,但会延时。Asp.net层要尽量少的使用这种技术,以减少进程中线程的数量,或者只让请求用一小部分的线程。当然如果你有大量的异步工作的话,那就只能用它了。
这里没有足够的空间有贴代码,你可以从http://www.rob-howard.net/中下载示例程序,请下载Blackbelt TechEd 2004的示例程序。
七、 页面输出缓存和代理服务
Asp.net是你的界面层(或者说应该是),它包含页面,用户控件,服务器控件(HttpHandlers 和HttpModules)以及它们生成的内容。如果你有一个Asp.net页面用来输出html,xml,imgae或者是其它的数据,对每一个请求都用代码来生成相同的输出内容,就很有必要考虑用页面输出缓存了。
许多人都没有意识到当用页面输出缓存的时候,asp.net也会生成HTTP头集(HTTP Header)保存在下游的缓存服务器中,这些信息可以用于Microsoft Internet安全性中以及加速服务器的响应速度。当HTTP缓存的头被重置时,请求的内容会被缓在网络资源中,当客户端再次请求该内容时,就不会再从源服务器上获得内容了,而直接从缓存中获得内容。
虽然用页面输出缓存不提高你的应用程序性能,但是它能减少了从的服务器中加载已缓存页面内容的次数。当然,这仅限于缓存匿名用户可以访问的页面。因为一旦页面被缓存后,就不能再执行授权操作了。
八、 用IIS6.0的Kernel Caching
如果你的应用程序没用运行在IIS6.0(windows server 2003)中,那么你就失去了一些很好的提高应用程序性能的方法。在第七个方法中,我讲了用页面输出缓存提高应用程序的性能的方法。在IIS5.0中,当一个请求到来到IIS后,IIS会把它转给asp.net,当应用了页面输出缓存时,ASP.NET中的HttpHandler会接到该请求,HttpHandler从缓存中把内容取出来并返回。
如果用的是IIS6.0,它有一个非常好的功能就是Kernel Caching,而且你不必修改asp.net程序中任何代码。当asp.net接到一个已缓存的请求,IIS的Kernel Cache会从缓存中得到它的一份拷贝。当从网络中传来一个请求的时,Kernel层会得到该请求,如果该请求被缓存起来了,就直接把缓存的数据返回,这样就完工了。这就意味着当你用IIS的Kernel Caching来缓存页面输出时,你将获得不可置信的性能提升。在开发VS.NET 2005的 asp.net时有一点,我是专门负asp.net性能的程序经理,我的程序员用了这个方法,我看了所有日报表数据,发现用kernel model caching的结果总是最快的。它们的一个共同的特征就是网络的请求和响应量很大,但IIS只占用了5%的CPU资源。这是令人惊奇的。有许多让你使用用IIS6.0的理由,但kernel cashing是最好的一个;
九、 用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配置文件中修改它的配置。
十、 服务器控件的ViewState
ViewState是asp.net中的一个特性,它用于把生成页面要用的一状态值保存在一个隐藏域中。当页面被回传到服务器时,服务器要解析,校验和应用ViewState中的数据以还原页面的控件树。ViewState是一个非常有用的特性,它能持久化客户端的状态而不用cookie或者服务器的内存。大部分的服务器控件都是用ViewState来持久化那些在页面中与用户交互的元素的状态值。例如,用以保存用于分页的当前页的页码。
用ViewState会带来一些负面的影响。首先,它加大的服务器的响应和请求的时间。其次,每次回传时都增加了序列化和反序列化数据的时间。最后,它还消耗了服务器更多的内存。
许多的服务器控件很趋于使用ViewState,如众所周知的DataGrid,而有时候是没有必须使用的。默认情况下是允许使用ViewState的,如果你不想使用ViewState的话,你可以在控件或页面级别把关闭它。在控件中,你只要把EnableViewState属性设为False就可以了;你也可以在页面中设置,使它的范围扩展到整个页面中:
如果页面无需回传或者每次请求页面只是呈现控件。你就应该在页面级别中把ViewState关掉。
Word教程网 | Excel教程网 | Dreamweaver教程网 | Fireworks教程网 | PPT教程网 | FLASH教程网 | PS教程网 |
HTML教程网 | DIV CSS教程网 | FLASH AS教程网 | ACCESS教程网 | SQL SERVER教程网 | C语言教程网 | JAVASCRIPT教程网 |
ASP教程网 | ASP.NET教程网 | CorelDraw教程网 |