Web层:浏览器缓存、代理服务器缓存、网关缓存
使用技术:HTTP头信息控制、代理服务器或CDN、反向代理或间接代理
浏览器缓存是最靠近用户的缓存,如果启用缓存,用户在访问同一个页面时,将不再从服务器下载页面,而是从本机的缓存目录中读取页面,然后再浏览器中展现这个页面。
网关或代理服务器缓存是将网页缓存在网关服务器上,多用户访问同一个页面时,将直接从网关服务器把页面传送给用户。
什么是Web缓存,为什么要使用它?
Web缓存游走于服务器和客户端之间。这个客户端也可能是1个或多个。Web缓存就在服务器-客户端之间搞监控,监控请求,并且把请求输出的内容(例如html页面、 图片和文件)(统称为副本)另存一份;然后,如果下一个请求是相同的URL,则直接请求保存的副本,而不是再次麻烦源服务器。
使用缓存的2个主要原因:
- 降低延迟:缓存离客户端更近,因此,从缓存请求内容比从源服务器所用时间更少,呈现速度更快,网站就显得更灵敏。
- 降低网络传输:副本被重复使用,大大降低了用户的带宽使用,其实也是一种变相的省钱(如果流量要付费的话),同时保证了带宽请求在一个低水平上,更容易维护了。
Web缓存的类型
1. 浏览器缓存
在任何现代浏览器上(如IE, FireFox, Chrome)折腾清除隐私数据的对话框,你很可能会注意到“缓存”这个设置项。浏览器会在你的硬盘上专门开辟一个空间专门为你存储资源副本。浏览器缓存的工作规则很简单:检查以确保副本是最新的,通常只要一次会话。
浏览器缓存在用户触发“后退”操作或点击一个之前看过的链接的时候很管用。同样,如果你在网站上访问同一张图片,该图片可以从浏览器缓存中调出并几乎立即显现出来。
2. 代理服务器缓存
Web代理服务器使用同样的缓存原理,只是规模更大。代理以同样的方式服务千万用户,大公司和Internet服务提供商经常在他们的防火墙或者单独的设备上架设代理缓存。由于代理服务器缓存并非客户端或者源服务器的一部分,而是处于网络中,请求需要以某种方式路由到它们。一种方法是手动设置,告诉浏览器的你常用的代理服务器(//zxx: 翻墙的时候常用的),另外就是使用拦截。拦截代理(Interception proxies)把Web请求根据自己的底层网络重定向,因此,客户端无需配置,甚至都不需要知道它们。
代理缓存属于一种共享缓存;往往有大量的用户使用,因此,其在降低延时和网络流量上很有用,毕竟每个副本都被大量重用。
3. 网关缓存
也被称为“反向代理缓存”或“替代缓存”。网关缓存同样是起中介作用的,不过不是网络管理员部署的,而多半是网站管理员(公司专门的运维工程师、或UED或程序组某人Add)他们自己部署,这样更容易扩展与维护。可以有多种方法把请求路由到网关缓存,但通常使用某种形式的负载均衡器,使它们中的一个或多个看起来像是源服务器。内容分发网络(CDNs)为整个网络(或部分)分配网关缓存,然后把这些缓存卖给需要的网站。和就是代表性的网络内容发布商。
①负载均衡器:是一种采用各种分配算法把网络请求分散到一个服务器集群中的可用服务器上去,通过管理进入的Web数据流量和增加有效的网络带宽,从而使网络访问者获得尽可能最佳的联网体验的硬件设备。
②内容分发网络:即CDN, 基本思路是尽可能避开互联网上有可能影响数据传输速度和稳定性的瓶颈和环节,使内容传输的更快、更稳定。通过在网络各处放置节点服务器所构成的在现有的互联网基础之上的一层智能虚拟网络,CDN系统能够实时地根据网络流量和各节点的连接、负载状况以及到用户的距离和响应时间等综合信息将用户的请求重新导向离用户最近的服务节点上。其目的是使用户可就近取得所需内容,解决 Internet网络拥挤的状况,提高用户访问网站的响应速度。
③Speedera:是一家全球性的内容服务提供商,它与北美、欧洲以及亚太地区的1000多家大型运营商都有联系,并为那些不想在自己服务器上寄存内容的公司提供软件下载、媒体及其它服务管理等业务。05年的时候被下面要介绍的Akamai以$130m的价格给收购了。
④Akamai:美国Akamai是国际上最大的CDN服务商,它巨大的网络分发能力在峰值时可达到15Tbps。Akamai公司是为数不多的旨在消除Internet瓶颈和提高下载速度的几家新公司之一,是一个致力于网络交通提速的”内容发布”公司,是波士顿高技术区最卓越的新兴企业之一。Akamai公司向全球企业提供发送互联网内容,汇流媒体和应用程序的服务(目前,该公司为15个国家的企业管理着8000多台服务器)。1998年,丹尼尔。L和麻省理工学院的一些研究人员一起创立了这家公司,他在麻省理工学院的硕士论文构成了Akamai公司最初的”自由流”(Freeflow)技术的核心。
本教程重点在浏览器和代理缓存,尽管有些信息对网关缓存感兴趣的人也适用。
Web缓存无害吗?为什么要鼓励缓存?
Web缓存是互联网中最容易被误解的技术之一。网站管理员特别希望知道网站的一举一动,比方说多少人访问啦,访问时间啊什么的,而缓存会“隐藏”他们的用户,他们就无从得知到底谁访问了这个站点。
捡了芝麻丢西瓜,自认为放弃缓存可以精确跟踪用户,实际上,互联网中有太多的变数,想精确得到一张用户查看网站的图片?没那么简单的,亲!如果你很重视这个问题,恭喜你,本文正好提供了解决之道,即保证缓存友好,同时又能获得统计。
另外需要注意的是,缓存的内容都是旧的过时的。因此,如何准确更新就成了一个问题。不过不要担心,本文会向你展示如何配置服务器,让缓存就像你的女仆——随便调教。
CDN算是个挺有意思的技术,不同于代理缓存,CDN的网关缓存和被缓存的Web站点的利益是一致的,因此,上面提到的问题对于CDN而言是没有的。不过,即使你使用了CDN,你仍要顾虑下游的代理和浏览器缓存。
以上为缓存可能的“糟粕”,那他好的地方呢?缓存可以让你的Web站点加载更快,让你的服务器和互联网链接间负担更小。这种差异会导致一些类似质的变化,一个网站要几秒钟才能加载出来,而另外一个充分发挥缓存的优势,几乎瞬间显示。用户自然更喜欢那个加载迅速的站点,访问也更多。
再说个现实示例,许多大型互联网公司花费了数百万??美元,在世界各地设立服务器集群来复制他们的内容,以使其尽可能快被他们的用户访问。缓存为你做同样的事情,而且他们更接近最终用户。最重要的是,你不要花银子。
实际上呢,无论你喜欢与否,代理和浏览器缓存都会被使用。如果你站点的缓存配置不正确,你只能听天由命了。
Web缓存如何工作
所以的缓存都有一套自己的规则,可以用来决定何时跟缓存暧昧往来。其中部分规则设定在协议中(HTTP 1.0 以及 1.1),部分由缓存管理员设置。
⑤缓存管理员:如果指的是浏览器缓存,则有可能就是我们服务器专家同事,在服务器上配置一些缓存规则;如果是代理缓存,则指的就是处理代理服务器这块的管理人员。
一般而言有如下常用规则N:
- 响应头明确说明,偶不想被缓存,则不会被缓存;
- 如果请求信息是需要认证或者安全加密的(如, HTTPS),相应内容也不会被缓存;
- 缓存如果有以下表现,则认为是fresh新鲜的(无需检查源服务器,直接发送给客户端):
- 含有完整的过期时间和寿命控制头信息,并且内容仍在保鲜期内,或者
- 缓存最近已展现,并且在不久前修改。
则内容缓存直取,绕过源服务器。
- 若内容陈旧,则会要求源服务器做验证 validate ,或者告诉缓存其拷贝副本是否是OK的。
- 特定情况下——例如,断网了,之前有过的响应缓存直取而不检查源服务器。
响应如果没有类似ETag或Last-Modified头这样的校验器,也没有明确的更新信息,通常(并不绝对)认为是不可缓存的。
总而言之,新鲜度freshness和校验validation是确定缓存内容是否可用的最重要途径。如果要展示的足够新,直接缓存取;如果检测发现展示内容并未变化,则不会再来一次完整的传输。
如何控制缓存和不缓存
有很多工具可以帮助设计师和网站管理员调整服务器缓存网站的方式,这也许需要你亲自动手对服务器的配置进行一些调整,但绝对值得。了解如何使用这些工具请参考本文后面的章节。
HTML Meta标签 vs. HTTP头信息
HTML重构人员可以在文档的<head>
中添加标签进行描述。这些meta标签通常用来标记不可缓存或过期时间。 Meta标签使用简单,但效果一般。因为只被少数几个浏览器宠幸,而代理缓存基本上就不访问HTML文档。尽管我们可以在页面上试图添加no-cache
meta标签让页面一直是最新的,但其实没必要。
如果你的网站托管在ISP或者主机托管商那里,并且他们没有赋予您任意设置HTTP头信息的能力(比如Expires和Cache-Control),你要投诉争取,因为在你的工作中这些是必须的。
另外一方面: HTTP头信息可以让你对浏览器和代理服务器如何处理你的副本进行更多的控制。他们在HTML代码中是看不见的,一般由Web服务器自动生成。但是,根据你使用的服务器,你可以在某种程度上进行控制。在下文中:你将看到一些有趣的HTTP头信息,以及如何在你的站点上应用部署这些特性。
HTTP头信息发送在HTML代码之前,只能被浏览器和一些中间缓存能看到,一个典型的HTTP 1.1协议返回的头信息看上去像这样:
HTTP/1.1 200 OKDate: Fri, 30 Oct 1998 13:19:41 GMTServer: Apache/1.3.3 (Unix)Cache-Control: max-age=3600, must-revalidateExpires: Fri, 30 Oct 1998 14:19:41 GMTLast-Modified: Mon, 29 Jun 1998 02:28:12 GMTETag: "3e86-410-3596fbbc"Content-Length: 1040Content-Type: text/html
头信息空一行后是HTML代码的输出,关于HTTP头信息请参考对应章节。
Pragma HTTP头信息(以及为什么不起作用)
很多人认为在HTTP头信息中设置了Pragma: no-cache
后会让内容无法被缓存。但事实并非如此:HTTP的规范中,响应型头信息没有任何关于Pragma属性的说明,只说明了请求头信息(浏览器发送给服务器的头信息)中的Pragma属性。虽然有少部分缓存会买账,但大部分无视,使用Pragma没作用。若要使用,试试下面的头信息。 使用Expires HTTP头信息控制不过期
Expires HTTP头是控制缓存的基本手段,Expires的中文意思是“有效期”,显然,就是告诉浏览器缓存的有效期。如果过期,缓存会检查源服务器以确定文件是否改变了。Expires头几乎每个缓存都支持。大部分的服务器允许你以多种方式设置Expires响应头。通常,他们允许设置一个绝对过期时间,然后对比最后一次访问的时候或者最后一次文档修改的时候决定客户端内容的获取方式。
对于静态图片(如导航或按钮
的图片)而言,Expires头信息是相当有用的,因为图片不怎么修改,您可以给图片设置一个相当长的过期时间,这回让你的用户感觉网站变快了。Expires对于控制有改变规律的网页也很有用,例如:你有一个新闻聚合页面,每天早上6点钟准时更新,您可以设置缓存的过期时间也是这个点,于是缓存就可以很聪明地知道什么时候该去重载新的内容,什么时候睡大觉。
Expires头唯一的有效值是HTTP时间,其他值都会被认为是“前男友前女友”之类,不会去缓存的。注意:时间是格林威治时间(GMT),而不是本地时间。如下所示:
Expires: Fri, 30 Oct 1998 14:19:41 GMT
显然,如果你要使用Expires头,确保你的Web服务器时间的准备就非常重要了。使用网络时间协议(Network Time Protocol – NTP)不失为一个号方法。如果你的身边有本地系统管理员,可以向他咨询,或者查看下面的百科Add 。
尽管Expires头很有用,但它有一定的局限性。首先,因为牵扯到时间,Web服务器端的时钟必须和缓存的同步,否则很可能实现不了预期的结果——缓存把前女友当初现女友,把现女友当作过去式——那就悲剧了。
另外一个问题是,你很容易忘记给某内容设置了一个特定时间,如果返回内容的时候没有更新这个过期时间,则每个请求都是上访到服务器,反而增加了负载和响应时间。
⑥网络时间协议(NTP): 以封包交换把两台电脑的时钟同步化的网络协议。NTP使用UDP端口123作为传输层。它是用作抵销可变延迟的影响。NTP是仍在使用中的最古老的网络协议之一(在1985年前开始)。NTP最初由德拉瓦州大学的Dave Mills设计,他与一群志愿者仍在维护NTP。
Cache-Control(缓存控制)HTTP头信息
HTTP 1.1引入了新的头信息:Cache-Control
响应头信息,让网站的发布者可以更全面的控制他们的内容,更好地处理Expires的些限制。Cache-Control
有用的响应头包括: - max-age=[秒]:表示在这个时间范围内缓存是新鲜的无需更新。类似Expires时间,不过这个时间是相对的,而不是绝对的。也就是某次请求成功后多少秒内缓存是新鲜的。
- s-maxage=[秒]:类似
max-age
, 除了仅应用于共享缓存(如代理)。 - public:标记认证的响应才能够被缓存。一般而言,需要认证HTTP请求内容会自动私有化(不会被缓存Add)。
- privateN:允许缓存专门为某一个用户存储响应,比方说在浏览器中;共享缓存一般不会,例如在代理中。
- no-cache:每次在释放缓存副本之前都强制发送请求给源服务器进行验证,这在确保认证有效性上很管用(和
public
结合使用)或者保证内容必须是即时的,不得无视缓存的所有优点,如国内的微博、twitter等的刷新显示Add。 - no-store:强制缓存在任何情况下都不要保留任何副本。
- must-revalidate:告诉缓存,我给你准备了一些关于新鲜度的信息,在表现的时候要严格遵循之。HTTP允许缓存在某些特定情况下返回过期数据,指定了这个属性,相对于告诉缓存,你丫必须严格遵循我的规则。
- proxy-revalidate:类似
must-revalidate
,除了只能应用于代理缓存。