首页 > 代码库 > http缓存机制
http缓存机制
在web开发过程中,缓存是老生常谈的一个话题。本文从缓存的定义、作用、分类、机制等方面介绍http缓存及其原理。希望能对大家有所帮助,如有纰漏,还请提出指正。
什么是web缓存
根据MDN上的解释,缓存是指存储指定资源的一份拷贝,并在下次请求该资源的时候提供这份拷贝而非源文件的技术。当 web 缓存发现请求的资源已经被存储,它会拦截请求,返回该资源的拷贝,而不会去源服务器重新下载。
缓存的作用
1、减少网络带宽消耗,降低运营成本
2、降低服务器压力。给网络资源设定有效期之后,用户可以重复使用本地的缓存,减少对源服务器的请求,间接降低服务器的压力。同时,搜索引擎的爬虫机器人也能根据过期机制降低爬取的频率,也能有效降低服务器的压力
3、减少网络延迟,加快页面打开速度,提升用户体验。
缓存类型
1、数据库缓存
在大型web应用开发过程中,会对数据库进行频繁查询,容易导致数据库不堪重负,我们一般会将首次查询出的数据放入内存中进行缓存,下次查询时,直接从内存中获取,而不用再次查询数据库,从而提升响应效率。常用的数据库缓存方案有memcached和redis。二者的区别本次不做讨论
2、服务器端缓存
代理服务器缓存:当代理服务器转发源服务器返回的响应时,将保存一份资源的副本。可以把它理解成一个共享缓存,共享缓存存储的响应能够被多个用户使用。缓存服务器的优势在于利用缓存可以避免多次从源服务器转发资源,客户端可以就近从缓存服务器获取资源,源服务器也就不必多次处理相同的请求了。
cdn缓存:也叫网关缓存或者反向代理缓存。从浏览器的角度来看,整个cdn就是一个源服务器。
3、客户端缓存
也叫浏览器缓存或者是私有缓存,浏览器缓存根据一套与服务器约定的规则进行工作,在同一个会话过程中会检查一次并确定缓存的副本足够新。这些规则是在HTTP协议头和HTML页面的Meta标签中定义。需要注意的是meta标签的http-equiv属性只有部分浏览器可以支持,而且所有缓存代理服务器都不支持,因为代理不解析HTML内容本身。浏览器会在你的硬盘上专门开辟一个空间专门为你存储资源副本。这些缓存为浏览过的文档提供向后/向前导航,保存网页,查看源码等功能,可以避免再次向服务器发起多余的请求。它同样可以提供缓存内容的离线浏览。如果你浏览过程中,比如前进或后退,访问到同一个图片,这些图片可以从浏览器缓存中调出而即时显现。
缓存策略
1、缓存存储策略
通过http响应头Cache-Control 头里的 public、private、no-cache、max-age 、no-store来决定http响应内容是否可以被客户端缓存,前4个都会缓存数据到本地,而no-store则不会在客户端缓存任何响应数据(需要明白的是no-cache只是不缓存过期资源,而并不是不缓存)。数据缓存到本地后浏览器并不是直接使用,而是先要确定缓存是否过期(见下文)。
2、缓存过期策略
Cache-Control、Expires指明当前资源的有效期,控制客户端是否直接从浏览器缓存取数据还是重新发请求到服务器取数据。客户端通过这两个字段确认存储在本地的缓存数据是否已过期(比较max-age和age或者Expires和Date),从而决定是否要发送请求到服务器重新下载一份资源。需要注意的是Cache-Control的优先级高于Expires,同时存在时前者会覆盖后者。如果Cache-Control不存在,则会检查是否包含Expires,如果Expires不存在,那么缓存寿命就是Date的值减去Last-Modified的值除以10。缓存过期只是告诉客户端先不要从本地读取缓存,并不是从此就没用了,等到发送请求到源服务器确认后,如果文件没有被修改,那么还会接着使用(见下文)。
3、缓存校验策略
客户端检测到数据过期或浏览器刷新后,会重新向源服务器发送一个http请求,服务器并不急于返回响应,而是先通过Last-Modified与ETag来判断资源是否有被更改。
Last-Modified/If-Modified-Since
Last-Modified: 缓存的弱校验器,标示这个响应资源的最后修改时间。web服务器在响应请求时,告诉浏览器资源的最后修改时间。
If-Modified-Since:当资源过期时,发现资源具有Last-Modified声明,则再次向web服务器请求时带上头 If-Modified-Since,表示请求时间。web服务器收到请求后发现有头If-Modified-Since 则与被请求资源的最后修改时间进行比对。若最后修改时间较新,说明资源又被改动过,则响应整片资源内容(写在响应消息包体内),HTTP 200;若最后修改时间较旧,说明资源无新修改,则响应HTTP 304 (无body,节省浏览),告知浏览器继续使用所保存的cache。
Etag/If-None-Match
Etag:缓存的强校验器,web服务器响应请求时,告诉浏览器当前资源在服务器的唯一标识。Apache中,ETag的值,默认是对文件的索引节(INode),大小(Size)和最后修改时间(MTime)进行Hash后得到的。
If-None-Match:当资源过期时(使用Cache-Control标识的max-age),发现资源具有Etage声明,则再次向web服务器请求时带上头If-None-Match (Etag的值)。web服务器收到请求后发现有头If-None-Match 则与被请求资源的相应校验串进行比对,决定返回200或304。
Last-Modified与ETag
Last-Modified已经足以让浏览器知道本地的缓存副本是否足够新,为什么还需要Etag(实体标识)呢?HTTP1.1中Etag的出现主要是为了解决几个Last-Modified比较难解决的问题
Last-Modified标注的最后修改只能精确到秒级,如果某些文件在1秒钟以内,被修改多次的话,它将不能准确标注文件的修改时间
如果某些文件会被定期生成,当有时内容并没有任何变化,但Last-Modified却改变了,导致文件没法使用缓存
有可能存在服务器没有准确获取文件修改时间,或者与代理服务器时间不一致等情形
Etag是服务器或者由开发者生成的对应资源在服务器端的唯一标识符,能够更加准确的控制缓存。Last-Modified与ETag是可以一起使用的,服务器会优先验证ETag,一致的情况下,才会继续比对Last-Modified,最后才决定是否返回304。
总结
重用已获取的资源能够有效的提升网站与应用的性能。Web 缓存能够减少延迟与网络阻塞,进而减少显示某个资源所用的时间。借助 HTTP 缓存,Web 站点变得更具有响应性。
http缓存机制