设为首页收藏本站

LUPA开源社区

 找回密码
 注册
文章 帖子 博客
LUPA开源社区 首页 业界资讯 技术文摘 查看内容

Web 开发人员需知的 Web 缓存知识

2013-6-14 09:58| 发布者: 红黑魂| 查看: 2804| 评论: 0|来自: 张鑫旭

摘要: 原文出处:mnot译文出处:张鑫旭最近的译文距今已有4年之久,原文有一定的更新。今天踩着前辈们的肩膀,再次把这篇文章翻译整理下。一来让自己对web缓存的理解更深刻些,二来让大家注意力稍稍转移下,不要整天HTML5, ...

实现需注意的:Web服务器端

一般说来,应该选择最新版本的Web服务器程序来部署。不仅因为它们包含更多利于缓存的功能,新版本往往在性能和安全性方面都有很多的改善。

Apache HTTP服务器
Apache使用可选模块包含头信息,头信息ExpiresCache-Control一并包含。这些模块在1.2版本以上都支持。

这些模块需要编译到Apache中,虽然包含,但是默认并未开启。为了确定相应模块已经被启用,找到httpd⑬程序,运行httpd -l, 它会列出可用的模块(注意,仅有内部编译的模块列表才会显示,在较新版本的Apache中,使用httpd -M可以包含动态加载的模块N),我们需要关注的是expires模块(expires_module)和headers模块(headers_module)。

⑬httpd:httpd是Apache超文本传输协议(HTTP)服务器的主程序。被设计为一个独立运行的后台进程,它会建立一个处理请求的子进程或线程的池。

  • 如果这些模块不可用,你需要联系管理员,重新编译以包含这些模块。这些模块可以通过取消配置文件中的注释掉启用,或者在编译的时候增加-enable -module=expires-enable-module=headers参数(apache 1.3+). 参开Apache中的INSTALL文件。

一旦你的Apache有了相应的模块,你可以使用mod_expires指定过期的时间,要么在.htaccess文件,要么在服务器的access.conf文件。你可以设置过期时间是从访问时间开始还是文件修改时间开始,并应用到特定类型文件上或设为默认配置。查看官方该模块文档获得更多信息,或者遇到问题的时候向你身边的apache专家讨教。

为应用Cache-Control头,你需要使用mod_headers模块,其允许你为资源指定任意的头信息。可参考mod_headers官方文档

下面是.htaccess文件展示了如何使用头信息:

  • .htaccess文件允许Web发布者使用配置文件中的指定。可以影响目录以及子目录内容。和你的服务器管理员沟通下,看看它们是否可用。
    ### activate mod_expires
    ExpiresActive On
    ### Expire .gif's 1 month from when they're accessed
    ExpiresByType image/gif A2592000
    ### Expire everything else 1 day from when it's last modified
    ### (this uses the Alternative syntax)
    ExpiresDefault "modification plus 1 day"
    ### Apply a Cache-Control header to index.html
    <Files index.html>
    Header append Cache-Control "public, must-revalidate"
    </Files>
  • 注意,在有些情况下,mod_expires会自动计算并插入Cache-Control:max-age头信息。

Apache 2′s的配置和1.3类似,更多信息可以参考2.2Nmod_expiresmod_headers文档。

微软IIS
微软的IIS有一些灵活的方式可以很容易得设置头信息,不过似乎只针对IIS 4.0服务器,并且只能在NT服务器上运行。

为了给网站某区域指定头信息,需要进入Administration(管理员)工具面板,然后再设置属性。选择HTTP Headers选项卡后,你会看到两个有意思的区域:Enable Content ExpirationCustom HTTP headers, 第一个含义一目了然,第二个用来应用Cache-Control头。//zxx: 此处的操作描述很过时了,看看window7下,操作界面早就大变样了!

设置ASP页面(Active Server Pages)的头信息可以参考后面的ASP章节,也可以通过ISAPI模块设置头信息,细节请参考MSDN。

Netscape/iPlanet企业服务器
3.6版本以后,企业版服务器已经不能以任何方式设置Expires头信息了。然而,其从3.0版本开始支持HTTP 1.1的功能。这意味着HTTP 1.1的缓存(代理服务器/浏览器)利用你对Cache-Control的设置来获得。

为了使用Cache-Control头,在管理员服务器中选择Content Management | Cache Control Directives(内容管理|缓存控制指令)。然后,使用资源选择器(Resource Picker),选择你希望设置头信息的目录。设置完头信息后,点击”确定”。更多信息请参考NES手册

实现需注意的:服务端脚本

时刻谨记,在Web服务器上设置HTTP要比通过脚本设置轻松些。你可以两者都试试。

因为服务器端的脚本主要是为了动态内容,所以即使实际上内容可以被缓存的,其也不会生成缓存很强的页面。如果你的页面内容经常变动,但不是每个页面都中枪,可以考虑设置Cache-Control: max-age头信息,大部分用户是在相对端的时间内再次访问这个页面。例如:用户点击“后退”按钮,如果没有任何验证或新鲜度信息,他们将不得不等待,直到从服务器页面重新下载才能看到它。

CGI
CGI脚本是生成内容最常用的技术之一。你可以轻轻松松在请求发送给主体之前添加HTTP请求信息。大部分CGI实现都需要添加Content-Type头信息,例如这个Perl脚本://zxx: 还是挺好懂的

<#!/usr/bin/perl
print "Content-type: text/htmln";
print "Expires: Thu, 29 Oct 1998 17:04:19 GMTn";
print "n";
### the content body follows.../pre>

由于都是文本,你可以很容易通过内置函数生成Expires和其他日期相关的头信息。如果你使用Cache-Control: max-age会更简单:

print "Cache-Control: max-age=600n";

上面脚本可以让请求完成后缓存10分钟,因此,当用户点击“后退”按钮的时候,就不会重新涂胶请求了。

CGI的规范同时也允许在脚本环境中,客户端发送请求头信息,每个头信息都有一个’HTTP_’的前缀。于是乎,如果一个客户端发送一个If-Modified-Since请求,就是这样的:

HTTP_IF_MODIFIED_SINCE

可观摩cgi_buffer库,其可以自动实现Etag生成和验证,Content-Length生成及gzip内容,而所有这些实现,只需要一行include,就可以为Perl和Python写CGI脚本。Python版本还可以包装任意的CGI脚本。

服务器端包含
SSI(扩展名通常是.shtml)最早可以生成动态内容的网站发布方案。通过在页面中使用特定的标签,有一定限制的内HTML脚本就可以使用了。大部分的SSI实现不设置验证器,故无法缓存。不过Apache服务器允许通过设置让SSI文件可缓存,通过适当的文件并结合XbitHack full指令设置组执行权限。欲了解更多信息,请参阅mod_include文档

PHP
PHP为服务器端脚本语言,在服务器内置的时候,可以在HTML页面中内嵌使用,很像SSL,不过有更多的可选项。PHP可以在任何Web服务器(Unix或Windows)或Apache模块上作为CGI使用。

默认情况下,PHP生成的内容没有分配验证器,因此,不能缓存。不过,开发人员可以通过Header()函数设置HTTP头信息。例如,创建Cache-Control头,过期时间为3天:

<?php
 Header("Cache-Control: must-revalidate");

 $offset = 60 * 60 * 24 * 3;
 $ExpStr = "Expires: " . gmdate("D, d M Y H:i:s", time() + $offset) . " GMT";
 Header($ExpStr);
?>

记住Header()需要在所有的输出之前。

正如你看到的,你可以手工创建HTTP日期。PHP没有专门的函数(新版本已改进,请参考PHP的日期相关函数文档)。当然,最简单的还是设置Cache-Control: max-age头信息,适用于大部分情况。

更多内容,请参阅header手册

还是cgi_buffer库,只要一行包含,就能以PHP脚本形式自动实现Etag生成和验证,Content-Length生成及gzip内容。

Cold Fusion
Cold Fusion是Macromedia的商业服务器端脚本引擎,并且支持多种Windows平台,Linux平台和多种Unix平台。//zxx: 看到Macromedia心亮了半截,几百年前就被收购的公司……此文未免太过时了点了~~大家这段可以跳过了,几乎没有任何价值……

Cold Fusion通过CFHEADER标记设置HTTP头信息相对容易。可惜的是,以下的Expires头信息的设置有些容易误导:

<CFHEADER NAME="Expires" VALUE="#Now()#">

它并不像你想像的那样工作,因为时间(本例中为请求发起的时间)并不会被转换成一个符合HTTP时间,而且打印出副本的Cold fusion的日期/时间对象,大部分客户端会忽略或者将其转换成1970年1月1日。

但是:Cold Fusion另外提供了一套日期格式化函数-GetHttpTimeSTring. 结合DateAdd函数,就很容易设置过期时间了,这里我们设置一个头信息,声明内容在1个月以后过期:

<cfheader name="Expires" 
  value="#GetHttpTimeString(DateAdd('m', 1, Now()))#">

你也可以使用CFHEADER标签设置Cache-Control: max-age以及其他头信息。

记住,Web服务器也会将头信息设置转给Cold Fusion(做为CGI运行的时候),检查你的服务器设置并确定你是否可以利用服务器设置代替Cold Fusion.

ASP和ASP.NET

在asp中设置HTTP头信息时,确保Response方法调用在HTML内容输出之前,或者使用Response.Buffer暂存输出。同时,注意某些版本的IIS默认设置会输出Cache-Control: private头信息,必须声明成public才能被共享缓存服务器缓存。

ASP(Active Server Pages),IIS内置,也可用于其他Web服务器,同样允许你设置HTTP头。例如设置过期时间,你可以使用Response自带属性:

<% Response.Expires=1440 %>

指定内容过期的分钟数。Cache-Control头添加如下:

<% Response.CacheControl="public" %>

在ASP.NET中,Response.Expires已经不推荐使用了,正确的方法是通过Response.Cache设置缓存相关的头信息,如下:

1Response.Cache.SetExpires ( DateTime.Now.AddMinutes ( 60 ) ) ;
2Response.Cache.SetCacheability ( HttpCacheability.Public ) ;

参考文档和拓展阅读

HTTP 1.1规范
HTTP 1.1的规范对页面缓存以及权威的接口实现指南有了大量的扩展,参考章节:13, 14.9, 14.21以及14.25 .

Web-Caching.com
对缓存概念有很好的介绍,并且有很多其他在线资源的链接。

解读访问统计
Jeff Goldberg这篇内容丰富叙述会告诉你为什么不应该过度依赖访问统计和计数器。//zxx 上世纪的复古页面…

REDbot
检查HTTP资源,以确定它们如何与Web缓存交互,以及通常如何使用该协议。

cgi_buffer库
只要包含一行Perl CGI, Python CGI以及PHP脚本,就能自动实现Etag生成以及验证,Content-Length生成以及Gzip内容的正确编码。Python版本还可以包装任意的CGI脚本。

关于本文档

本文版权属于Mark Nottingham © 1998-2013 邮箱为mnot@pobox.com.

本作品遵循知识共享署名 – 非商业性使用 – 禁止演绎3.0声明页面许可证N

所有的商标版权为其持有人所有。

内容在发布时是可以确保其正确性,但是,随着时间推移,就不能保证正确无误了。因此,如有链接404,描述错误或其他需要纠正的问题请尽快告知作者。

本文最新版本可以从http://www.mnot.net/cache_docs/获得

可用翻译:白俄罗斯中国捷克德国法国

文档说明:含有上标N的表示与前辈翻译时候相比新增的;上标Add表示作为译者的我为了便于理解自己添加的;上标数字(①-⑬)是对一些可能不熟悉的名词的百科解释。

虽然原作语言不生动,教科书般一板一眼⑭;有些可能过时了。不过,还是学到了很多东西。还是很值的!欢迎分享,欢迎传播,以后面试之前来这里看看,可能会有帮助哦!

⑭ 如果我介绍缓存,我可能就这么讲:缓存是什么?顾名思意,就是缓慢的存钱。为什么要缓慢的存钱,因为工资卡都上交老婆了,为了攒点零花钱又不能被老婆发 现,只能慢慢存了。那缓存有什么用呢?你想啊,自己有点小钱,做事情就方便快捷了,比方说我想买个鱼竿,就不要去向老婆要(给不给先不谈),自己从自己这 边取,大大提高了执行的速度。

那什么时候可以存什么时候不能存呢?老婆给零花钱的时候,可能会有过期时间头,例如,周一甩了100块钱,拿去,这是一周的伙食!这个一周就是过期时间头(Expires Header),在这个时间内,你的钱可以从缓存,也就是自己这里取……


酷毙
1

雷人

鲜花

鸡蛋

漂亮

刚表态过的朋友 (1 人)

  • 快毕业了,没工作经验,
    找份工作好难啊?
    赶紧去人才芯片公司磨练吧!!

最新评论

关于LUPA|人才芯片工程|人才招聘|LUPA认证|LUPA教育|LUPA开源社区 ( 浙B2-20090187 浙公网安备 33010602006705号   

返回顶部