昨天的性能优化与今天的网站故障

     为了面对博客园越来越大的访问量的挑战,这几天我专心于博客园网站的性能优化。
     前天试验了用空间换时间的生成静态html文件的方法,感觉整体性能提高不是很明显,而且增加了程序的复杂度,并带来了一些新问题。
     昨天,我又回到了对网站程序本身的优化。性能优化的目标是减少内存消耗。博客园的程序与数据库运行在同一台在服务器上,内存只有2G。节省内存是提高性能的重要因素。内存的两个大用户当然是Web应用程序与数据库, 所以性能优化从两方面着手,一是减少Web应用程序的内存占用,二是减少数据库查询,从面减少数据库占用的内存。昨天优化时,我发现了数据库中一张表的索引有问题。在代码中,发现了一处地方应该使用缓存减少数据库查询,却没有使用。我纠正了这两个问题。
     同时,我也对machine.config的设置进行了调整,调整时参考了:
     1、Contention, poor performance, and deadlocks when you make Web service requests from ASP.NET applications
     2、IIS 6.0 Tuning for Performance
     需要修改的参数如下:
 Configuration setting             Default value (.NET Framework 1.1)     Recommended value
maxconnection 2 12 * #CPUs
maxIoThreads 20 100
maxWorkerThreads 20 100
minWorkerThreads   50
minFreeThreads 8 88 * #CPUs
minLocalRequestFreeThreads 4 76 * #CPUs

     maxWorkerThreads、maxIoThreads、minWorkerThreads是processModel的属性,maxconnection是connectionManagement中的一个属性,minFreeThreads 、minLocalRequestFreeThreads是httpRuntime 的属性。 
     这里我遇到一个问题,博客园的服务器算一个CPU还是两个CPU(你也许会想这算什么问题),物理CPU的确只有一个,可这不是一个普通的CPU, 是超线程CPU(超线程现在也很普通,呵呵)。从操作系统的任务管理器、设备管理器以及SQL Server企业管理器中看到的都是两个CPU。所以以前我是按照两个CPU来设置的,并且没有设置minWorkerThreads。昨天,我改成了单CPU设置,并且设置了minWorkerThreads,但设置成了一个不推荐的值:100。(我设置时看错了推荐值,不知是否是这个设置引起了今天的服务器故障)
     
     继续优化,在网上看到一篇Tips for ASP.NET Application Performance Enhancement ,其中提到一点“Avoid Throwing Exceptions.”,这让想到在博客园程序中,当用户访问一个不存在的地址时,会抛出异常BlogDoesNotExistException,然后在Error.aspx页面显示异常信息,这个地方我一直觉得不存在性能问题,但我突然想到,假如网上有什么软件大量访问博客园不存在的地址,会产生很多异常,这时可能会带来性能问题,处理这些异常,需要消耗一些资源,仅仅为了显示异常信息而消耗昂贵的资源,太不值得了。 对于这样的情况,直接重定向到一个错误提示页面就行了,没必要抛出异常。博客园网站占用内存过多的问题可能这也是罪魁祸首之一。我立刻对代码进行改进,在重定向时,我没有指向错误页面,而是指向了博客园首页(在解决一个性能问题时,来了另外一个性能问题,博客园首页是访问量最大的页面,将无效地址访问重定向到首页,给首页带来更大的压力)。 
      
     做这些优化之后,我更新了服务器上的程序。更新后,系统运行正常,让我惊喜的是,内存占用降了下来,原来w3wp进程正常需要占用600多M内存,高的时候甚至800多M,现在基本上在500M左右。 
     
     今天早上,当我准备享受优化的成果时,现实却跟我开了个玩笑,9:00左右,有人反映不能访问自己的Blog, 而访问博客园首页正常,我查看了一下错误信息内容为: 
     CS1595: 已在多处定义“_ASP.Calendar_ascx”;使用“c:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\Temporary ASP.NET Files\blog\49be8ecb\4a239ba\ejndjhfs.dll”中的定义。 

     这个错误是在加载Blog页面上的日历控件时出现的。奇怪,这里的代码昨天没有修改,以前也没出现过这个问题,在另外一目录中并且是另外的命名空间,的确有一个同名的控件,可以前一直运行正常,怎么今天就会出现问题? 后来我把该日历控件Codebehind中的类改名才解决问题(两个同名的类在不同命名空间, 怎么会有问题?奇怪)。

     而这个时候,服务器CPU一直100%负荷运行,大部分CPU被数据库占用了,访问网站很慢,经常出错。用SQL Server的事件查看器跟踪,很多存储过程执行时间很长。重启IIS、数据库索引优化、重启服务器,都没能解决问题,后来恢复了以前的程序, 还是没解决问题,接着我将machine.config按照两个CPU进行设置,并删除了minWorkerThreads设置。最后,我修改了程序,将无效地址访问重定向到一个静态页面,并更新服务器,经常两个多小时的奋战,在11:30左右才让博客园恢复运行。
     究竟是什么原因引起这次故障?我现在也搞不明白,进行了那么多处理,究竟是哪个因素是关键?现在也无法判断。我需要投入更多精力对网站进行性能优化。就写到这吧,继续研究博客园网站的性能优化。有兴趣的朋友,欢迎在博客园一起研究高性能Web应用程序开发。
posted @ 2005-10-12 15:52  dudu  阅读(...)  评论(...编辑  收藏