Web开发人员需知的Web缓存知识
导读:本文转自张鑫旭博客,文章较长,干货满满,主要讲到了Web缓存知识,对Web开发人员很值得一看,暂时没时间看的小火伴,优优建议先转发或收藏,以备后看。
目录:
1、什么是Web缓存,为何要使用它?
2、缓存的类型:
1.浏览器缓存;
2.代理服务器缓存;
3.关缓存;
3、Web缓存无害吗?为何要鼓励缓存?
4、Web缓存如何工作
5、如何控制缓存和不缓存:
MLMeta标签TP头信息;
agmaHTTP头信息(和为何不起作用);
3.使用ExpiresHTTP头信息控制不过期;
che-Control(缓存控制)HTTP头信息;
5.验证器和验证;
6、创建支持缓存站的小技能;
7、编写支持缓存的脚本;
8、常见问题解答;
9、实现需注意的:Web服务器端;
10、实现需注意的:服务端脚本;
11、参考文档和拓展浏览;
12、关于本文档;
1、什么是Web缓存,为何要使用它?
Web缓存游走于服务器和客户端之间。这个服务器可能是源服务器(资源所驻留的服务器Add),数量可能是1个或多个;这个客户端也可能是1个或多个。Web缓存就在服务器-客户端之间弄监控,监控要求,并且把要求输出的内容(例如html页面、图片和文件)(统称为副本)另存一份;然后,如果下一个请求是相同的URL,则直接要求保存的副本,而不是再次麻烦源服务器。
使用缓存的2个主要原因:
下降延迟:缓存离客户端更近,因此,从缓存要求内容比从源服务器所用时间更少,出现速度更快,站就显得更灵敏。
下降络传输:副本被重复使用,大大下降了用户的带宽使用,其实也是一种变相的省钱(如果流量要付费的话),同时保证了带宽要求在一个低水平上,更容易保护了。Web缓存的类型
2、缓存的类型
1.浏览器缓存
在任何现代浏览器上(如IE,FireFox,Chrome)折腾清除隐私数据(//zxx:原文说的是首选项,明显out了,这里有改动)的对话框,你极可能会注意到“缓存”这个设置项。
浏览器会在你的硬盘上专门开辟一个空间专门为你存储资源副本。浏览器缓存的工作规则很简单:检查以确保副本是最新的,通常只要一次会话(就是当前浏览器调用的这次N)。
浏览器缓存在用户触发“后退”操作或点击一个之前看过的链接的时候很管用。一样,如果你在站上访问同一张图片,该图片可以从浏览器缓存中调出并几近立即显现出来。
2.代理服务器缓存
Web代理服务器使用一样的缓存原理,只是范围更大。代理以一样的方式服务千万用户,大公司和ISP(InterServerProvider,Inter服务提供商Add)常常在他们的防火墙或单独的装备(也被称为中介(intermediaries))上架设代理缓存。
由于代理服务器缓存并不是客户端或源服务器的一部分,而是处于络中,要求需要以某种方式路由到它们。一种方法是手动设置,告知浏览器的你经常使用的代理服务器(//zxx:翻墙的时候经常使用的),另外就是使用拦截。拦截代理(Interceptionproxies)把Web要求根据自己的底层络重定向,因此,客户端无需配置,乃至都不需要知道它们。//zxx:维基百科上提供的几种检测拦截代理服务器存在的方法add,您若有兴趣,可以打开连接地址()。
代理缓存属于一种同享缓存;常常有大量的用户使用,因此,其在下降延时和络流量上很有用,毕竟每一个副本都被大量重用。//zxx:这里我有疑问:就算是放在代理服务器上,每次获得还是要通过络的啊,如何下降了络流量呢?希望谁可以帮忙解惑下。
3.关缓存
也被称为“反向代理缓存”或“替换缓存”。关缓存一样是起中介作用的,不过不是(素不相识、不曾谋面的Add)络管理员部署的,而多半是站管理员(公司专门的运维工程师、或UED或程序组某人Add)他们自己部署,这样更容易扩大与保护。
可以有多种方法把要求路由到关缓存,但通常使用某种情势的负载均衡器①,使它们中的一个或多个看起来像是源服务器。内容分发络②(CDNs)为全部络(或部份)分配关缓存,然后把这些缓存卖给需要的站。Speedera③和Akamai④就是代表性的络内容发布商。
①负载均衡器:是一种采取各种分配算法把络要求分散到一个服务器集群中的可用服务器上去,通过管理进入的Web数据流量和增加有效的络带宽,从而使络访问者取得尽量最好的联体验的硬件装备。
②内容分发络:即CDN,基本思路是尽量避开互联上有可能影响数据传输速度和稳定性的瓶颈和环节,使内容传输的更快、更稳定。通过在络各处放置节点服务器所构成的在现有的互联基础之上的一层智能虚拟络,CDN系统能够实时地根据络流量和各节点的连接、负载状态和到用户的距离和响应时间等综合信息将用户的要求重新导向离用户最近的服务节点上。其目的是使用户可就近获得所需内容,解决Inter络拥堵的状态,提高用户访问站的响应速度。
③Speedera:是一家全球性的内容服务提供商,它与北美、欧洲和亚太地区的多家大型运营商都有联系,并为那些不想在自己服务器上寄存内容的公司提供软件下载、媒体及其它服务管理等业务。05年的时候被下面要介绍的Akamai以$m的价格给收购了。
④Akamai:美国Akamai是国际上最大的CDN服务商,它巨大的络分发能力在峰值时可到达15Tbps。Akamai公司是为数不多的旨在消除Inter瓶颈和提高下载速度的几家新公司之一,是一个致力于络交通提速的”内容发布”公司,是波士顿高技术区最卓着的新兴企业之一。Akamai公司向全球企业提供发送互联内容,汇流媒体和应用程序的服务(目前,该公司为15个国家的企业管理着多台服务器)。年,丹尼尔。L和麻省理工学院的一些研究人员一起创建了这家公司,他在麻省理工学院的硕士论文构成了Akamai公司最初的”自由流”(Freeflow)技术的核心。
本教程重点在浏览器和代理缓存,虽然有些信息对关缓存感兴趣的人也适用。
3、Web缓存无害吗?为何要鼓励缓存?
Web缓存是互联中最容易被误解的技术之一。站管理员特别希望知道站的一举一动,比方说多少人访问啦,访问时间啊什么的,而缓存会“隐藏”他们的用户,他们就无从得知到底谁访问了这个站点。
捡了芝麻丢西瓜,自认为放弃缓存可以精确跟踪用户,实际上,互联中有太多的变数,想精确得到一张用户查看站的图片?没那末简单的,亲!如果你很重视这个问题,恭喜你,本文正好提供了解决之道,即保证缓存友好,同时又能取得统计。
另外需要注意的是,缓存的内容都是旧的过时的。因此,如何准确更新就成了一个问题。不过不要担心,本文会向你展现如何配置服务器,让缓存就像你的女仆——随意调教。
CDN算是个挺有意思的技术,不同于代理缓存,CDN的关缓存和被缓存的Web站点的利益是一致的,因此,上面提到的问题对CDN而言是没有的。不过,即便你使用了CDN,你仍要顾虑下游的代理和浏览器缓存。
以上为缓存可能的“糟粕”,那他好的地方呢?缓存可以让你的Web站点加载更快,让你的服务器和互联链接间负担更小。这类差异会致使一些类似质的变化,一个站要几秒钟才能加载出来,而另外一个充分发挥缓存的优势,几近瞬间显示。用户自然更喜欢那个加载迅速的站点,访问也更多。
再说个现实示例,许多大型互联公司花费了数百万美元,在世界各地设立服务器集群来复制他们的内容,以使其尽量快被他们的用户访问。缓存为你做一样的事情,而且他们更接近最终用户。最重要的是,你不要花银子。
实际上呢,不管你喜欢与否,代理和浏览器缓存都会被使用。如果你站点的缓存配置不正确,你只能听天由命了。
4、Web缓存如何工作?
所以的缓存都有一套自己的规则,可以用来决定什么时候跟缓存暗昧来往。其中部份规则设定在协议中(HTTP1.0和1.1),部份由缓存管理员⑤设置。
⑤缓存管理员:如果指的是浏览器缓存,则有可能就是我们服务器专家同事,在服务器上配置一些缓存规则;如果是代理缓存,则指的就是处理代理服务器这块的管理人员。
一般而言有以下经常使用规则N:
响应头明确说明,偶不想被缓存,则不会被缓存;
如果要求信息是需要认证或安全加密的(如,HTTPS),相应内容也不会被缓存;
缓存如果有以下表现,则认为是fresh新鲜的(无需检查源服务器,直接发送给客户端):则内容缓存直取,绕过源服务器。
含有完全的过期时间和寿命控制头信息,并且内容仍在保鲜期内,或
缓存最近已展现,并且在不久前修改。
4.若内容陈腐,则会要求源服务器做验证validate,或告知缓存其拷贝副本是不是是OK的。
5.特定情况下——例如,断了,之前有过的响应缓存直取而不检查源服务器。
响应如果没有类似ETag或Last-Modified头这样的校验器,也没有明确的更新信息,通常(其实不绝对)认为是不可缓存的。
总而言之,新鲜度freshness和校验validation是肯定缓存内容是不是可用的最重要途径。如果要展现的足够新,直接缓存取;如果检测发现展现内容并未变化,则不会再来一次完全的传输。
5、如何控制缓存和不缓存
有很多工具可以帮助设计师和站管理员调剂服务器缓存站的方式,这或许需要你亲自动手对服务器的配置进行一些调剂,但绝对值得。了解如何使用这些工具请参考本文后面的章节。
MLMeta标签TP头信息
HTML重构人员可以在文档的head中添加标签进行描写。这些meta标签通常用来标记不可缓存或过期时间。
Meta标签使用简单,但效果一般。由于只被少数几个浏览器宠幸,而代理缓存基本上就不访问HTML文档。虽然我们可以在页面上试图添加no-cachemeta标签让页面一直是最新的,但其实没必要。
如果你的站托管在ISP或主机托管商那里,并且他们没有赋予您任意设置HTTP头信息的能力(比如Expires和Cache-Control),你要投诉争取,由于在你的工作中这些是必须的。
另外一方面:HTTP头信息可以让你对浏览器和代理服务器如何处理你的副本进行更多的控制。他们在HTML代码中是看不见的,一般由Web服务器自动生成。但是,根据你使用的服务器,你可以在某种程度上进行控制。在下文中:你将看到一些有趣的HTTP头信息,和如何在你的站点上运用部署这些特性。
HTTP头信息发送在HTML代码之前,只能被浏览器和一些中间缓存能看到,一个典型的HTTP1.1协议返回的头信息看上去像这样:
HTTP/Date:Fri,30Oct13:19:41GMTServer:Apache/1.3.3(Unix)Cache-Control:max-age=,must-revalidateExpires:Fri,30Oct14:19:41GMTLast-Modified:Mon,29Jun02:28:12GMTETag:3e86--fbbcContent-Length:Content-Type:text/html
头信息空一行后是HTML代码的输出,关于如何设置HTTP头信息请参考对应章节。
agmaHTTP头信息(和为何不起作用)
很多人认为在HTTP头信息中设置了Pragma:no-cache后会让内容没法被缓存。但事实并非如此:HTTP的规范中,响应型头信息没有任何关于Pragma属性的说明,只说明了要求头信息(浏览器发送给服务器的头信息)中的Pragma属性。虽然有少部份缓存会买账,但大部分疏忽,使用Pragma没作用。若要使用,试试下面的头信息。
3.使用ExpiresHTTP头信息控制不过期
ExpiresHTTP头是控制缓存的基本手段,Expires的中文意思是“有效期”,明显,就是告知浏览器缓存的有效期。如果过期,缓存会检查源服务器以肯定文件是不是改变了。Expires头几近每一个缓存都支持。
大部分的服务器允许你以多种方式设置Expires响应头。通常,他们允许设置一个绝对过期时间,然后比较最后一次访问的时候或最后一次文档修改的时候决定客户端内容的获得方式。
对静态图片(如导航或按钮的图片)而言,Expires头信息是相当有用的,由于图片不怎么修改,您可以给图片设置一个相当长的过期时间,这回让你的用户感觉站变快了。Expires对控制有改变规律的页也很有用,例如:你有一个聚合页面,每天早上6点钟准时更新,您可以设置缓存的过期时间也是这个点,因而缓存就可以很聪明地知道什么时候该去重载新的内容,什么时候睡大觉。
Expires头唯一的有效值是HTTP时间,其他值都会被认为是“前男朋友前女友”之类,不会去缓存的。注意:时间是格林威治时间(GMT),而不是本地时间。以下所示:
Expires:Fri,30Oct14:19:41GMT
明显,如果你要使用Expires头,确保你的Web服务器时间的准备就非常重要了。使用络时间协议⑥(NetworkTimeProtocol–NTP)不失为一个号方法。如果你的身旁有本地系统管理员,可以向他咨询,或查看下面的百科Add。
虽然Expires头很有用,但它有一定的局限性。首先,由于牵扯到时间,Web服务器端的时钟必须和缓存的同步,否则极可能实现不了预期的结果——缓存把前女友当初现女友,把现女友当作过去式——那就悲剧了。
另外一个问题是,你很容易忘记给某内容设置了一个特定时间,如果返回内容的时候没有更新这个过期时间,则每一个要求都是上访到服务器,反而增加了负载和响应时间。
⑥络时间协议(NTP):以封包交换把两台电脑的时钟同步化的络协议。NTP使用UDP端口作为传输层。它是用作抵销可变延迟的影响。NTP是仍在使用中的最古老的络协议之一(在年前开始)。NTP最初由德拉瓦州大学的DaveMills设计,他与一群志愿者仍在保护NTP。
che-Control(缓存控制)HTTP头信息
HTTP1.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,除只能应用于代理缓存。
举个板栗:
Cache-Control:max-age=,must-revalidate
如果Cache-Control和Expires同时存在,Cache-Control说了算N。如果你打算使用Cache-Control头,你应当好好看看”HTTP1.1规范“,详见参考文章和拓展浏览。
5.验证器和验证
在缓存如何工作这段译文中,我们说过,服务器和缓存通过验证来判断内容是不是改变,在不确定内容是不是过期的时候,可以避免本地已存在副本的时候下载全部内容。
验证器是很重要的,如果一个都没有,同时没有可用的新鲜度信息(Expires或Cache-Control),缓存一点儿都不会存储内容。
最常见的验证是通过Last-Modified头信息通讯肯定文档最后的修改时间,如果缓存有内容存储,会包括Last-Modified信息的,辅助If-Modified-Since要求,我们可以询问服务器内容是不是改变了。
HTTP1.1引入了一个新的验证器,称为Etag⑦.Etag是每次展现内容改变时候由服务器生成的唯一标识符,由于服务器控制ETag如何生成,当缓存发起If-None-Match要求的时候,如果Etag匹配,就可以肯定展现内容其实是一样的。
⑦Etag:HTTP协议规格说明定义ETag为”被要求变量的实体值”。另一种说法是,ETag是一个可以与Web资源关联的记号(token)。典型的Web资源可以一个Web页,但也可能是JSON或XML文档。服务器单独负责判断记号是什么及其含义,并在HTTP响应头中将其传送到客户端,以下是服务器端返回的格式:ETag:”50b1c1d4fc61:df3″客户端的查询更新格式是这样的:If-None-Match:W/“50b1c1d4fc61:df3″如果ETag没改变,则返回状态然后不返回,这也和Last-Modified一样。测试Etag主要在断点下载时比较有用。
几近所有的缓存使用Last-Modified时间作为验证器,Etag验证也开始变得流行。
所有新一代的Web服务器都对静态内容(如:文件)自动生成ETag和Last-Modified头信息,而你没必要做任何设置。但是,服务器对动态内容(例如:CGI,ASP或数据库生成的站)其实不知道如何生成这些信息,参考一下编写支持缓存的脚本章节;
6、创建支持缓存站的小技能
除使用新鲜度信息和验证,还有其他一些技能可以让你站的缓存更加友好:
保持URL稳定:这是缓存的金科玉律,如果你为不同页面,不同用户或不同站提供相同的内容,他们应当使用相同的URL.这是简单却非常行之有效的方法。例如,你的HTML中的某个援用地址是/ml,则要一直使用这个地址。
不同地方的图片和其他元素使用同一库。
对不常常改变的图片/页面启用缓存,通过将Cache-Control:max-age头信息的值设大一点。
对定期更新的内容通过指定max-age或过期时间实现缓存。
如果资源改变了(特别下载文件),改变其名字。由于一般这类资源会有很长的过期时间,而服务器上一直是正确的版本;因此,链接这个下载资源的页面需要要比较短的过期时间(//zxx:我司页面5分钟过期)。否则,会出现服务器的资源是新的,但页面被缓存了,其中的链接地址还是旧的,就会出现新旧版本冲突的可能Add。
万不得已不要变动文件:否则你要设置一个新的Last-Modified值。另外,当你更新站点的时候,只要上传改动的那些文件,而不要把全部站点都覆盖过去。
Cookie能不用就不用:Cookie难以被缓存,且大多情境下是没有必要的。如果你非得使用Cookie,建议用在动态页面上。
减少SSL⑧的使用:由于同享缓存不能存储认证页面,只在必要的时候使用,并且在SSL页面上减少图片的使用。
使用REDbot⑨检查你的站:可以帮助你运用本文所介绍的一些概念。
⑧SSL:全称SecureSocketLayer–安全套接层,为Netscape所研发,用以保障在Inter上数据传输之安全,利用数据加密(Encryption)技术,可确保数据在络上之传输进程中不会被截取及窃听。目前一般通用之规格为40bit之安全标准,美国则已推出bit之更高安全标准,但限制出境。只要3.0版本以上之I.E.或Netscape浏览器便可支持SSL。
⑨REDbot:REDbot=RED+robot,是个机器人,检查HTTP资源,看他们如何会表现,指出常见的问题,并提出改进建议。虽然它属于HTTP一致性测试仪,但却可以找到很多HTTP相干问题。
7、编写支持缓存的脚本
默许情况下,大多数的脚本不会返回验证器(Last-Modified或Etag响应头)或新鲜度信息(Expires或Cache-Control)。虽然有些脚本的确是动态的(意味着每次要求都有不同的响应),还是有很多(如搜索引擎或数据库驱动的)站可以从缓存中受益。
一般来说,对同一个要求(无论是几分钟还是几天以后),如果脚本产生的内容是可重复的,则可以缓存。脚本内容的改变仅仅依赖于URL,则可以缓存。如果是依赖于Cookie,认证信息或其他外部条件,极可能不缓存。
最利于缓存的脚本就是在内容改变时导出成静态文件,服务器会想对待其他Web一样对待它的,生成和使用验证器,因而你可以好好地喝杯咖啡了。记住,只有文件更改的时候才写入,这样Last-Modified时间就会被保存下来。
另外的脚本缓存之道就是使用age相干的头部,相比Expires,Cache-Control:max-age更容易些,由于是相对时间,每次新要求完成后重新设置,时间到了,再重新要求,再设置新的相对过期时间。
如果上面的做法你弄不定,你还可以试试通过脚本生成一个校验器,然后回应If-Modified-Since和/或If-None-Match要求。通过分析HTTP头信息,在合适的时候回应NotModified.不幸的是,这不是个打打酱油就能搞定的任务。
其他一些技能
不要使用POST:若是获得数据,尽可能不使用POST模式,由于POST方式返回内容大部分不会被缓存,相对的,通过GET以路径和查询发送的信息被缓存存储下来供后续使用。
URL地址中不要嵌入特定的用户信息,除非生成的内容对用户而言是唯一的。
不要期望同一用户的所有要求来自同一主机,由于缓存常常协同工作。//zxx:嘛意思?
生成Content-Length⑩头信息。实现不难,可让你的脚本以持久连接(persistentconnection)情势响应。这允许客户端在一个TCP/IP要求上要求多个内容,而不是为每次要求单独建立连接,这样你的站相应会快很多。
详见实现注意事项。
⑩Content-Length:指明实体正文的长度,以字节方式存储的十进制数字来表示。在数据下行的进程中,Content-Length的方式要预先在服务器中缓存所有数据,然后所有数据再一股脑儿地发给客户端。
8、常见问题解答
缓存可用的最重要事情是?
其中一个不错的策略是找出经常使用的、范围较大的内容(特别图片),然后优先处理之。
我该如何利用缓存让我的页面尽量的快?
最应当缓存的内容设置一个较长的过期时间。验证有助于减少查看内容的时间,不过缓存仍会连接源服务器查看是否是过期了。如果缓存已知道内容是新鲜的,直接返回。
我知道缓存是个好东西,但是我想随时知道多少人访问了我的页!如果你必须知道每一次页面被访问的情况,可以选择页面上的一个小元素(或页面本身),然后给这个元素一个适当的头信息使它是不可缓存。比如,你可以在每个页面上援用一个1像素×1像素的不可缓存(如scr地址后面加个随机数Add)的透明图片。Referer头信息将会包括调用它的页面信息。
请注意,即便这样也不能给出你用户的精确统计,并且对通过互联访问的用户也不是很友好:产生不必要的流量,并强制用户等待未被缓存的内容从络上下载回来。更多的信息可参见拓展浏览中的“解读访问统计”对应内容。
我该如何查看HTTP头?
许多浏览器可以查看Expires和Last-Modified头信息,如右键→查看页面信息或类似面板。例如,在Firefox浏览器下Add:
表示要看到完全的头,您可以使用Tel?客户端手动连接到Web服务器上。
为此,你可能需要用一个字段指定端口(默许是80),或连接到或80(注意是空格),更多设置请参考一下tel客户端的文档。
一旦连接到该站,输入要求。比如,你想查看
哪家医院治白癜风有效哪里医院看白癜风较好