缓冲教程系列

原文:http://hmyblog.vmmatrix.net/drupal/node/150


 

一. 什么是网页缓冲,有什么作用?

一个网页缓冲服务器存在于一个(多个)网页服务器和一个(多个)客户端(浏览器)之间,并且观察经过的请求(浏览器到网页服务器),保存一个应答(网页服务器到浏览器)的拷贝。比如一个HTML页面,图片和文件(统称为应答内容)。然后,如果有另一个到同一资源(URL)的请求,缓冲服务器可以使用这个存在于本地的这个资源的拷贝。代替原始服务器返回给浏览器。
这里有两个主要的理由使用网页缓冲:
1. 减少延迟,因为让缓冲处理进来的请求替代原始服务器处理请求是一个不错的选择,它花更少的时间来应答浏览器。这样可以让原始的web服务器处理更多的新的请求。
2. 减少网络传输,因为应答内容是被再次利用,它减少客户端的带宽流量(浏览器缓冲的情况)。也减少了缓冲服务器和原始服务器之间的网络流量。

二. 网页缓冲的类型

浏览器缓冲

如果你检查任何流行浏览器的参数设置对话框,你将会注意到一个“缓冲”(cache)设置.你可以选择设置用多大的磁盘空间来做为缓存空间1。这只针对你个人有用。浏览器缓冲根据非常简单的规则工作。它会检查确认“应答内容”是否“新鲜”,通常是一个会话周期内新鲜。
这个缓存非常有用,比如当用户点击后退按钮或者点击一个联接看一个刚看过的页面的时候。同样,如果你利用同一站点的同样的导航图片(比如一本书籍里面的“上一页”或者“下一页”箭头),它们将会立即利用浏览器缓冲里的内容作为应答。

代理缓冲(proxy cache)

网页代理缓冲用类似于浏览器缓冲的原理工作,但是有更大的柔韧性和更多的控制。代理给成百上千的用户提供服务。大公司和ISP经常设置在防火墙上设置代理服务器。
因为代理服务器不是客户端或者原始服务器的一部分,而是在他们之间。请求可以由不同的方法被路由到缓冲。一个方法是在你的浏览器里面设置代理服务器;另一个方法是利用中途截取(interception,也称为透明代理)。web请求被代理缓冲前面的防火墙重定向到缓冲。所以客户不需要在浏览器设置代理缓冲,甚至根本就不用知道它们的存在。
代理缓冲是共享缓冲的一种;经常有大量的用户使用,所以它们对减少网络延迟络和节省网络传输非常好。因为一个流行的应答被多次重复使用。

网关缓冲(gateway cache , or reverse proxy cache)

或者叫做 “反向代理缓冲 ”,网络管理员设置反向代理来减少到原始网页服务器的带宽。让他们的网站具有高可用性,高扩展性,和更高的性能。
请求可以有多种方法被路由到网关缓冲(DNS),但是典型的作法是利用负载均衡调度器让一个或者多个网关代理看起来更想一个原始服务器(对于客户端来说)。

三. 网页缓冲对我没有坏处吗,为什么我需要帮助它?

网页缓冲是因特网中不容易理解的技术之一。网站管理员尤其害怕对他的站点失去控制,因为代理缓冲可以"隐藏"从它哪里来的客户,不容易观察到谁在访问这个站点。
不幸的是,就算网页缓冲不存在,因特网上也有很多不确定的因素干扰管理员得到准确的访问站点的用户信息。如果这是你主要关心的事情,本教程将教你如何得到统计而你没必要让你站点对缓冲不友好。
另一个需要关心的是缓冲可以提供过期的内容,或者说不新鲜内容。不过,本教程将给你展示如何控制你的被缓冲的内容。

换句话说,如果你想让你的的站点运行良好,缓冲可以让你的站点访问快速,并且节省你的服务器负载和网络流量。这个变化将是激动人心的;一个难被缓冲的站点可能需要花几秒来访问到,同时能缓冲的站点可能立即就被访问到。用户欣赏访问快速的站点,并且经常访问。
想象一下,许多大的网络公司花上亿的美元设置全球范围内的服务器群来复制他们的内容,目的是让他们的客户访问尽量的快。缓冲为你做同样的事情,同时他们离最终客户更近。最好的是,这是免费的。
事实上不管你喜不喜欢,代理和浏览器缓冲总是在使用。如果你没有正确的设置的站点的缓冲控制,内容将被按照缓冲管理员设置的规则被缓冲。

四. 网页缓冲如何工作

所有的缓冲有一组规则来决定什么时候把缓冲中的内容提供出去,如果它可用。大部分规则在http(1.0,1.1)协议里被设置,另外一些规则被缓冲管理员设置。或者是浏览器缓冲的用户,或者是代理服务器管理员。
一般说来,这里有如下一些共同的规则:(不要担心你不能理解细节,下面将会解释)

1.如果应答头里指定本内容不被缓冲,它将不被缓冲
2.如果没有validator(a Etag or a Last-Modified header)出现在应答头里,这个内容被考虑成不能缓冲
3.如果这个请求是认证过的,或者是安全联接,应答将不被缓冲
4.一个被缓冲的应答符合下列条件的时候,认为它是新鲜(将直接返回给客户端,而不去原始服务器验证)的:
4.1 有一个过期时间或者年龄控制头被设置,并且在新鲜周期内
4.2 如果浏览器缓冲已经有应答内容,并且设置在一个会话内只检查一次
4.3 如果一个代理缓冲最近刚访问过这个应答内容,并且相对来说,这个内容的修改时间已经很久(最近一次修改出现在过去很长一个时间)
* 新鲜的应答内容直接被提供出去,而不用去原始服务器验证。
5.如果这个应答内容是过期的,将去原始服务器验证,或者寻问原始服务器,那个应答内容的拷贝是否依然是正确可用的。

总的说来,"新鲜" 和 "验证" 是用来控制缓冲内容的最重要的方法。一个新鲜的应答内容将被从这个缓冲立即访问。一个不新鲜的内容将被验证过的新鲜内容完全覆盖。

五. 怎样控制缓冲

这里有几个工具提供给网页设计者和网站管理者来调整缓冲设置。这可能会让你的服务配置文件变”脏“,不过这是值得的。

HTML Meta Tags 和 HTTP Headers

HTML作者可以在文章的段放标签来设置它的属性。这些元标签(meta tags)可以指定一个文档不能被缓冲,或者一个明确的过期时间。

元标签很容易使用,但是不是很有效果。因为它仅仅被几个浏览器缓冲支持。而不是代理缓冲(proxy cache),代理缓冲不会去读HTML.诱人的是可以放一个 Pragma: no-cache 元标签到一个网页里,它将保持最新。

另外,HTTP 头给你许多控制条件来调整浏览器和代理缓冲对你的应答内容的处理。而这些不能在HTML里实现,通常自动由网页服务器生成这些头。然而,你可以在不同的层次控制它们。这依赖你所使用的网页服务器。随后的章节你将发现HTTP 头很有趣,并且怎样运用它们在你的站点里面。
HTTP 头在HTML之前被服务器被发送,并且只能被浏览器和中途的缓冲看到,典型的应答头可能看起来是这个样子:

HTTP/1.1 200 OK
Date: Fri, 30 Oct 1998 13:19:41 GMT
Server: Apache/1.3.3 (Unix)
Cache-Control: max-age=3600, must-revalidate
Expires: Fri, 30 Oct 1998 14:19:41 GMT
Last-Modified: Mon, 29 Jun 1998 02:28:12 GMT
ETag: "3e86-410-3596fbbc"
Content-Length: 1040
Content-Type: text/html

HTML 将跟在这个头后面,被2个空行分开。

Pragma HTTP Headers

很多人认为赋值一个 no-cache 控制给一个应答的HTTP header将会让它不能被缓冲。实际上那不一定完全正确;HTTP协议不设置任何强制的规定到一个应答头;替代的方法是,请求头(浏览器发到服务器)是被协商的。尽管有些缓冲可能会尊重这个header,大多数却不会。同时它没有任何效果。用下面的头来替代将会是好的选择。

利用Expires HTTP 头来控制新鲜度

Expires HTTP 头是最基本的控制缓冲的方法;它告诉所有的缓冲这个应答内容在那个时间之前是新鲜的。一旦超过那个时间,缓冲将总是去原始服务器检查这个内容是否已经修改。Expire 头几乎被所有的缓冲所支持。
许多网页服务器允许你通过几种方法设置Expires 应答头。通常,允许设置一个过期的绝对时间,一个基于最后客户看到这个内容的时间(last access time)。或者是一个基于最后内容被修改的时间(last modification time)。

Expires 头尤其适合做静态图片的缓冲。因为它们不经常改变,你可以给它们设置一个很长的时间,让你的站点有能力应答更多的用户。这也经常用来控制有规律改变内容的页面。假设,你每天早上6点更新一个页面,你可以设置这个应答的时间是那个时间,所以缓冲将知道什么时候去得到一个新鲜的拷贝,不需要用户点击浏览器上的"reload"。

唯一允许在Expires头里面的值是一个HTTP时间;其他任何内容被当成是”过去时间“(in the past),所以这个应答内容不能被缓冲,同时,记住,HTTP时间是GMT(Greenwich Mean Time),而不是本地时间。
比如:

Expires: Fri,30 Oct 1998 14:19:41 GMT

尽管Expires头是有用的,它有一些限制。首先,在网页服务器和在缓冲服务器上的时间必须同步;如果这两个时间直接有差异,想要达到的目的就不能达到。并且缓冲可能会把新鲜的内容当成是不新鲜的。
另外一个关于Expires的问题就是你容易忘记已经给某个内容指定了一个过期时间。如果你没有在过期时间之前更新一个过期时间,每一个请求都会到你的网页服务器,增加负载和延迟。

Cache-Control HTTP 头

HTTP 1.1 引进了一个新的类型的头,Cache-Control 应答头,给网页发布者更多方法来控制发布的内容,同时补充Expires的不足。
有用的Cache-Control应答头包括:

max-age=[seconds] 指定一个认为应答内容是新鲜的最大时间。类似于Expires,这个命令和请求的时间有关系,不是绝对的。[seconds]是从请求时间到你认为这个应答内容是新鲜的时间的秒数。
s-maxage=[seconds] 类似于max-age,只是它只针对共享(e.g.,proxy)缓冲。
public 指定认证过的应答可以被缓冲;正常情况下,如果HTTP 请求是认证过的,应答自动编成不可缓冲。
no-cache 任何时候,在使用一个缓冲内容之前,强制缓冲提交一个到原始服务器的验证。当尊重认证的时候,这很有用,或者是管理严格的更新。
no-store 要求缓冲在任何情况下都不能保留应答内容的备份。
must-revalidate 告诉缓冲它必须服从任何应答里的刷新信息。HTTP允许缓冲在特殊的情况下返回不新鲜的内容(比如原始服务器挺机);通过设置这个头,你告诉缓冲你想按照你的规则严格执行。
proxy-revalidate 类似鱼must-revalidate,但是它只在代理缓冲里用。
例子:
Cache-Control: max-age=3600,must-revalidate
如果你计划使用Cache-Control 头,你应该仔细的看一下HTTP 1.1 RFC文档。

Validators and Validation

在网页服务器如何工作中,我们说 validators是被网页服务器和缓冲服务器之间用来通讯,当一个应答内容被改变。通过使用它,缓冲服务器可以避免重复的下载一个本地已有的内容,当在不知道这个是否新鲜的时候。而是通过validators来同原始服务器验证。
Validators非常重要;如果没有出现一个,同时没有任何刷新信息(Expires or Cache-Control)提供,缓冲将不会存储一个应答内容。
最常用的validator是这个文档被最后修改的时间,表现为 Last-Modified头。当一个缓冲服务器存储一个应答内容包括一个Last-Modified 头,它可以问这个原始服务器自这个最好修改时间以来这个应答内容是否被修改过。这个过程通过一个If-Modified-Since 请求(IMS请求)来实现。
http 1.1引入了一个新的类型的叫做ETag的validator.ETags是由原始服务器给一个应答内容生成的独一无二的标识符(可以现象成是一个md5检测码)。因为原始服务器控制如何生成ETag,缓冲可以认为如果一个If-None-Math 请求符合Etag,可以考虑本地的应答内容和原始服务器上是一样的。
尽管所有的缓冲利用Last-Modified times 来判断一个应答内容是否新鲜;ETag现在也变的流行起来。

很多流行的网页服务器同时给静态内容生成ETag和Last-Modified 头。你不用手工去干预。然而,服务器对动态内容知道的不够多。

服务器实现

通常来讲,最好选择你使用的网页服务器的最新版本,不只是它们提供很多缓冲友好设置,更重要的是包括很多安全方面的更新和性能的提升。

Apache

Apache 利用选择性的模块来包括头信息,包括Expires和Cache-Control.两个模块都包含在1.2或者主要的发型版里。

这些模块需用编译进Apache;尽管它们包含在发型版里,但是默认的没有被打开。为了检查这个模块是否包含在你的服务器里面,找到httpd运行程序并且运行httpd -l;这样将会打印一个可用的模块列表。我们需用的模块是mod_expires 和 mod_headers.

如果它们不可用,同时你有管理权限,你可以重新编译apache来包含它们。可以在配置文件里取消这两个配置的注释。或者使用 -enable-module=expires 和 -enable-module=headers参数到configure.或者阅读Apache发型里的INSTALL文件。

一旦你的Apache有了合适的模块,你可以使用mod_expires 来指定应答内容的过期时间。在.htaccess文件或者在服务器的access.conf文件里配置。你可以指定从访问或者是修改时间算起。并且让这个规则应用到一个文件类型或者是默认。看模块的文档得到更多信息。

运用Cache-Control头,你将需用mod_headers模块,它允许你指定任意的HTTP头给一个资源。

这里有一个 .htaccess文件演示如何使用这些头。

.htaccess文件允许网页发布者利用和配置文件里一样的命令。作用范围是这个文件所在的目录和子目录。

### 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

Header append Cache-Control "public, must-revalidate"

* 注意: mod_expires 自动计算和插入 Cache-Control:max-age 头。

Apache 2.0’s configuration is very similar to that of 1.3; see the 2.0 mod_expires and mod_headers documentation for more information.
Apache 2.0的配置比起1.3非常简单;参考2.0的 mod_expires 和mod_headers文档得到更多的信息。

Microsoft IIS

微软的因特网信息服务器利用稍微变通的方法很容易设置头信息。注意,这只能在4.0服务器里实现,只能在NT服务器上运行。

为一个站点的一个区域指定一个头信息,选择管理员工具面板,打开属性。然后选择http头标签,你会看到两个有趣的区域;允许内容过期和定制HTTP头.第一个将自动选择。第二个用来控制Cache-Control头。

FAQ:
Q: 在原始服务器端如何得到真实的客户端的ip地址
由于在原始的网页服务器和浏览器之间有缓冲服务器,原始服务器得到的访问ip是缓冲服务器的ip地址。但是缓冲服务器通常会在HTTP 头里包含真实客户端的ip地址,在Squid(一个代理缓冲服务器) 里通常增加一个X-Forwarded-For头信息来包含原始的客户端ip.所以如果是要在Apache服务器的日志里得到这个ip,可以增加一个%{X-Forwarded-For}i 到相应LogFormat里面。
如果想在应用程序里得到这个值,可以通过所用语言的相关函数得到这个值,比如说在php里面,可以利用getevn函数得到。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值