ntwo

导航

ASP.NET站点性能提升-缩短首页生成时间

以下瓶颈影响首页生成时间:

  • 内存压力
  • 缓存
  • CPU利用率
  • 线程利用率
  • 外部资源等待时间

如何查明瓶颈

内存

首先确定服务器是否耗尽了内存,如果是将会增加CPU使用率和磁盘I/O。因为,内存耗尽后,将会导致使用磁盘上的交换文件。因此,解决内存压力问题也能减少CPU和磁盘压力。

在命令行提示中运行perfmon,在性能监视器中增加Memory->Pages/sec计数器。这个计数器统计每秒使用的页面数量。如果频繁使用页面文件,说明内存存在瓶颈。

缓存

缓存会提高程序运行效率,但会占用内存。

CPU

perfmon中使用Processor->% Processor Time计数器。

线程

线程池中的线程数量是有限制的。.NET2.0线程数是CPU数量的12倍。3.5、4.0在IIS7经典模式下是CPU数量的12倍,在集成模式下是CPU数量的100倍。

可以使用ASP.NET->Request Execution Time(处理每个请求的毫秒数)、Requests Current(请求数量,包括排队的请求和正在执行的请求),ASP.NET Applications->Requests Executing(正在执行的请求)计数器。

如果Requests Current持续远远大于Requests Executing,表示有很多请求在等待线程。

长等待

如果Request Execution数值很高,而CPU和内存压力又不高,每个执行线程可能需要等待外部资源,例如数据库。

其它措施

有一些其它措施可以减少服务器负载

部署

使用release模式生成项目

release模式可以减少CPU和内存的使用

发布网站

如果使用了网站而没有使用网站应用程序项目,发布网站会以release模式编译网站。

禁止debug模式

在web.config中禁止debug模式。

减少程序集的数量

发布网站时一个文件夹生成一个程序集,以下两个链接中程序可以减少程序集数量。

http://msdn.microsoft.com/en-us/library/aa479568.aspx

http://www.microsoft.com/downloads/en/details.aspx?FamilyId=0AA30AE8-C73B-4BDD-BB1B-FE697256C459&displaylang=en

减少往返时间

使用Server.Transfer代替Response.Redirect

使用Server.Transfer的缺点是两个不同的页面具有同一个URL。这可能会使访问者迷惑,特别是他们收藏或与他人分享这个URL。

因此,只transfer与进入页面明确相关的页面。例如,访问者提交了一个表单,你可以transfer一个页面,显示表单提交的结果。而不要转向一个完全不相关的页面。如果你知道一个页面的post back始终会转向另一个页面,考虑使用PostBackUrl直接post back到这个页面。

在URL中指定默认页面

IIS会自动将http://mydomain/myfolder转向到http://mydomain/myfolder/。而且http.sys也不会缓存默认页面。使用http://mydomain/myfolder/default.aspx,可以防止转向并进行缓存。

永久转向

使用永久转向浏览器和代理会更新它们的缓存,搜索引擎也会使用它。这样,就可以减少对旧页面的访问。

编程实现301转向:

Response.StatusCode = 301;
Response.AddHeader("Location", "NewPage.aspx");
Response.End();

.NET4及更高版本:

Response.RedirectPermanent("NewPage.aspx");

你也可以设置IIS,进行永久转向。

减少CNAME记录

在DNS中,A记录优于CNAME记录。CNAME可能需要另一个往返进行解析。

SSL

使用SSL会对小的静态页面有比较大的影响,因为服务器和浏览器交互的时间相对于生成和传输页面的时间的比例比较大。而对于生成大页面,比如牵涉到数据库访问的页面,影响就不那么大了。

在使用SSL时,在加密页面引用非加密页面或在非加密页面引用加密页面时,使用绝对链接地址。或者在全站使用绝对链接地址。

在加密页面上如果有图片,图片也需要使用HTTPS,否则,访问者会收到一个警告。

不需要的访问请求

所有的请求都会加重服务器的负载,特别是牵涉到例如数据库访问等昂贵的操作。你可能希望阻止那些你不需要的访问请求。

搜索引擎

有搜索引擎爬你的网站是一件好事。但你不需要它访问与搜索列表无关,或者你希望保持私有的文件。这些文件可能包括:

  • 图片
  • JavaScript,CSS
  • 需要认证的页面

阻止搜索引擎访问网站的某些部分,在网站的根目录上放一个名为robots.txt的纯文本文件。

完全阻止搜索引擎访问,使用:

User-agent: *
Disallow: /

阻止搜索引擎访问指定文件夹:

User-agent: *
Disallow: /images/
Disallow: /js/
Disallow: /css/
Disallow: /private/

一些主流搜索引擎允许減少它们的爬虫的访问率:

User-agent: *
Crawl-delay: 10

另一个方法是提供site map。site map是一个放置在网站根目录的XML文件,它包括网站的每一个文件。

完整的site map规范:http://www.sitemaps.org/

盗链

防止盗链的模块:http://www.iis.net/community/default.aspx?tabid=34&i=1288&g=6

验证码

如果网站中有一些表单是更新数据库或执行其它昂贵的动作,就要确保是人提交了表单,而不是机器人。

确保是从提交了表单的一个方法是使用验证码。

可以插入表单的验证码库:

刮板程序

如果网站有很多有用内容的网站,就有可能有人用刮板程序自动读取这些内容。例如,他们可以使用这些内容发布自己的网站上,并发布广告。

因为刮板程序不修改来源IP地址,并且它们读取的频率也很高。这样一些简单的代码就可以屏蔽这些访问。

这些代码并不能防止拒绝服务攻击,在这些攻击中,来源IP会被修改,使得攻击检测很困难。

下面的代码会阻止简单的刮板程序:

public class BotDefence {
    private const int intervalSeconds = 5;
    private const int maxRequestsInterval = 100;
    private const int blockedPeriodSeconds = 20;

    public static bool IsBotAttack() {
        string visitorIP = HttpContext.Current.Request.UserHostAddress;
        VisitorInfo visitorInfo = (VisitorInfo)HttpContext.Current.Cache[visitorIP] as VisitorInfo;
        if(visitorInfo == null) {
            HttpContext.Current.Cache.Insert(visitorIP, new VisitorInfo(), null, DateTime.Now.AddSeconds(intervalSecods), System.Web.Caching.Cache.NoSlidingExpiration);
        }
        else {
            if(visitorInfo.blocked) {
                return true;
            }

            visitorInfo.nbrHits++;

            if(visitorInfo.nbrHits > maxRequestsInterval) {
                visitorInfo.blocked = true;
                HttpContext.Current.Cache.Insert(visitorIP, visitorInfo, null, DateTime.Now.AddSeconds(blockedPeriodSeconds), System.Web.Caching.Cache.NoSlidingExpiration);
                
                return true;
            }
        }

        return false;
    }

    private class VisitorInfo {
        public int nbrHits;
        public bool blocked;
        public VisitorInfo() {
            nbrHits = 1;
            blocked = false;
        }
    }
}
 
在页面的onload事件中加入判断:
 
protected void Page_Load(object sender, EventArgs e) {
    if(BotDefence.IsBotAttack()) {
        Response.End();
        return;
    }
}
 

这只是一个简单的示例代码。不要将它加入到生产环境中。你可能需要一个白名单,不希望阻止Google爬虫或其它搜索引擎。

最后,牢记IP地址不是标识访问的可靠证据:

  • ISP或公司可能使用代理或防火墙,这样,所有的访问者都具有一样的IP地址。
  • 一些ISP给拨号用户动态IP,然后,另一个用户可能会使用这个IP。

可用性测试

另一个不需要的流量的来源是访问者没有找到他们想要的,或者不知道你想让他们做什么。如果你的网站更容易使用,就会减少流量。

 

posted on 2010-11-15 15:36  9527  阅读(610)  评论(0编辑  收藏  举报