网站性能指南(三):奠基石-基础建设

网络技术    2012-08-16 13:11  

  【概述】

  在这一章节,我们的主题聚焦在基础设施建设上。

  1.Http Compression(压缩)

  2.Content Expirations (内容过期)

  3.Content Distribution Networks - CDN(内容分发网络)

  4.Etags (E标签)

  5.去掉没必要的Http header

  【Compression】

  我们前边提到过,性能规则中的一条就是在服务器和浏览器之间传输的数据越少越好。介于此规则,我们可以使用一个比较成熟的技术:Http Compression。

  1.Server 端会评估客户端发来的http request中header里的“Accept-Encoding”。来确定客户端是否能处理压缩过的数据。如果支持,server端会去对数据进行压缩并返回结果到客户端。

  2.在keynote这个第三方服务评估的结果是,可以平均节省53%的带宽,,网站平均快了25%。

  3.现在IIS也提供这种技术的支持(免费的)

  IIS7 对 compression 的支持

  1.支持配置当cpu占用率过高时,自动停止使用

  2.默认最小的文件大小是256k。

  3.默认启动静态内容的压缩

  如果你对IIS 使用compression 感兴趣。可以参见:http://weblogs.asp.net/owscott/archive/2004/01/12/57916.aspx

  【在IIS中配置Compression】

  打开IIS。选中一个你的网站。在右边选项卡里选择压缩(compression)

  也许有的朋友会发现,动态压缩是灰色的。其实是我们没安装动态压缩模块。我使用的是win7。安装方法如下:

  控制面板-》程序-》开启或关闭windows功能-》Internet 信息服务-》万维网服务-》性能功能(猥琐)-》动态内容压缩

  如果是win server版本的朋友需要:

  1.Administrative Tools | Server Manager。

  2.展开Roles,点击Web Server(IIS)。

  3.滚动到Role Services,点击Add Role Services,打开Add Role Services向导。

  4.在Select Role Services页面,滚动到Performance,选择Dynamic Content Compression,选择下一步。

  现在我们还用第一章里用到的那个网站做测试。打开fiddler。

  记下每个文件的大小。返回到IIS,开启动态压缩和静态压缩。现在IIS 再接收到请求我的js和css文件时。它先会判断是否已经压缩过呗请求的文件。如果没有它会进行压缩,并且存储到某一个目录。其他用户同样请求相同的文件时,它直接获取压缩过的文件即可。

  现在我们回到fiddler看看结果吧。

  jquery 文件从236K被压缩到90k。其他js和css文件也都受到相应的压缩。

  现在我们再使用上一章的另一把利器microsoft network monitor观察压缩前和压缩后 来看看发生了什么变化。

  压缩前:

  压缩后:

  非常容易使用 MS Network monitor 对比出。压缩前后,frame的数目明显的减少了,从40条减少到9条。

  由于95%以上的请求都会被询问是否启用compression。所以主流的浏览器都支持compression。

  启用compression会占用少许的cpu。IIS7 对这一块做了优化。

  为了确保压缩没有使CPU超载,IIS7每30秒计算平均CPU利用率。当CPU利用率超过一个限制时,它会自动关闭压缩。当CPU利用率低于限制时, 它会重新启用压缩。

  限制的默认值是:

  注意这意味着如果服务器上的CPU一直在50%以上,但偶然高于90%,动态文件压缩会被关闭,但再也不会重新开启了。

  可以通过修改applicationHost.config文件修改这些限制,通常它在C:\Windows\System32\inetsrv\config文件夹下。

  找到<httpCompression>节。

  2.修改httpdynamicCompressionEnableCpuUsage属性:<httpCompressiondynamicCompressionEnableCpuUsage="70"...>

  3.重启IIS。

  

  【Content Expirations】

  回顾一下我们第一张讲过的性能规则。有一条是尽可能不经常地传输数据。

  一个用户访问我网站的首页,他会得到我的js,css和图片等文件。浏览器则替他保存到本地的缓存中。过了几天用户又来访问我的网站了。服务器还会看看浏览器缓存中有木有他要的文件。如果有的话,它会告诉server。我有这个文件。但是我想知道它的版本是不是最新的。服务器会看看这个文件到底改没改。如果改了,服务器会发送新的文件。如果没,服务器会返回给浏览器状态码304。涛声依旧。

  304.没改。

  利用浏览器缓存:

  1.对于content folder 设置过期时间

  2.尽量避免请求不经常改动的文件

  3.重命名文件,如果需要重写浏览器缓存(版本号/时间戳)

  【在IIS中配置Content Expirations】

  打开IIS。选中你的站点。选中scripts文件夹(装js的地方。如果有的话)在视图选项卡里找到HTTP 响应标头并进入。

  右上角,设置常用标头-》使web内容过期。我们设置5天吧。这时候访问我们的网站。使用fiddler 观察结果如下:

  那个max-age 我们算算 。正好是5天:)现在我们再打开IE。internet选项-》浏览历史记录-》设置-》查看文件

  找到我们的js文件。查看属性,8月7号过期,正好5天:)

  【CDN】

  另一个对于提高网站性能有效的办法就是使用CDN了。

  CDN的全称是Content Delivery Network,即内容分发网络。其基本思路是尽可能避开互联网上有可能影响数据传输速度和稳定性的瓶颈和环节,使内容传输的更快、更稳定。通过在网络各处放置节点服务器所构成的在现有的互联网基础之上的一层智能虚拟网络,CDN系统能够实时地根据网络流量和各节点的连接、负载状况以及到用户的距离和响应时间等综合信息将用户的请求重新导向离用户最近的服务节点上。其目的是使用户可就近取得所需内容,解决 Internet网络拥挤的状况,提高用户访问网站的响应速度。

  在这里我只做简单介绍,需要了解更详细信息,请参见:http://en.wikipedia.org/wiki/Content_delivery_network

  看到这里读者肯定会说我屌丝了。不解释还废话那么多干什么?CDN都是大公司用的和我们有关系么?

  下面我来讲讲我们可以利用到的CDN:

  JQuery是现在最流行的js library之一。google、microsoft、jquery.com都免费host了jquery库在它们的cdn上。请看下图:

  我在这里可以使用我们自己的服务器上的jquery文件。也可以选择从google、微软和jquery官网的cnd来读。即可以给自己服务器减少压力。也可以利用cnd加快读取速度。

  【ETags】

  什么是ETags?Etag的全称是 entity tag。ETag实际上是一个hash+changeNumber组成的值。hash由文件内容生成。IIS7中changeNumber默认是0;

  本章前边内容提到,我们通过设置内容过期,利用浏览器缓存达到性能优化的效果,会使用expires headers告诉浏览器,不用再发送条件GET请求给服务器啦,直接用缓存里面的数据就可以啦,从而加快访问速度。

  Etags 使用过程如下:

  1.客户端请求一个资源source 。

  2.服务器返回页面souce,并在给source加上一个ETag。

  3.客户端展现该页面,并将页面连同ETag一起缓存。

  4.客户再次请求资源source,并将上次请求时服务器返回的ETag一起传递给服务器。

  5.服务器检查该ETag,并判断出该页面自上次客户端请求之后还未被修改,直接返回响应304(未修改——Not Modified)和一个空的响应体。

  从此看来Etag有可能会误导浏览器,让浏览器忽略缓存重复下载相同的文件。

  我们试着从删除ETAG。

  先看看没删除之前ETAG长什么样?

  using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

  /// <summary>
/// Summary description for ETagRemoveModule
/// </summary>
public class ETagRemoveModule : System.Web.IHttpModule
{
    public ETagRemoveModule()
    {
        //
        // TODO: Add constructor logic here
        //
    }
    public void Dispose()
    {

      }
    public void Init(HttpApplication context)
    {
        context.EndRequest += new EventHandler(HandlerEndRequest);
    }
    public void HandlerEndRequest(Object sender, EventArgs e)
    {
        System.Web.HttpContext.Current.Response.Headers.Remove("ETag");
    }
}

  ETags就没啦:)

  【去掉没必要的Http header】

  我们使用fiddler 可以看到,http response header 包含了很多信息。

  但是有些信息是没必要展示给用户看的。比如我们使用了.netframework 4.0.我们使用IIS7.5。

  首先它是多余的信息。其次它也有可能被一些骇客利用。

  所以我们修改一下我们的代码:

  现在我们的header干净多了,也安全多了。

在线留言

我要留言