浏览器缓存(Brower Caching)是浏览器在本地磁盘对用户最近请求过的文档进行存储,当访问者再次访问同一页面时,浏览器就能够直接从本地磁盘加载文档。php
咱们能够经过 chrome://view-http-cache/ 来查看chrome浏览器缓存了什么内容。 css
推荐阅读文章:大公司里怎样开发和部署前端代码?html
注意,通常,咱们缓存的都是css、js、图片之类的文件,这些文件的改动比较小,而html文件是不缓存的,由于html文件中经常包含动态的内容,好比引入a.css?v=1.0,最后是版本号,若是html也被缓存,那么咱们就没办法达到经过修改版本号进而使得用户获取新内容的目的了。前端
缓存类型分为强缓存和协商缓存。nginx
强缓存:在用户请求资源时,若是命中强缓存,则不向服务器请求,而直接从本地获取资源。咱们能够看到200状态码,并提示from disk cache或from memory cache(区别后面讲)。 redis
协商缓存: 在用户请求资源时,浏览器直接则向服务器发送请求,服务器根据 request header 来判断是否命中协商缓存,若是命中,则返回304和新的response header,使用本地资源;不然,返回新的资源。 chrome
强缓存和协商缓存的共同点:二者命中后都是从本地读取资源。数据库
强缓存和协商缓存的区别: 强缓存很强势,是没有向服务器发出请求的; 而协商缓存必需要向服务器发一个请求来协商。 apache
强缓存是利用http的响应头中的Expires字段和Cache-Control两个字段来控制的,用来表示使用缓存的有效时间。浏览器
Expires是http1.0规范的,表示缓存的过时时间。 如某个资源的response heade中的字段: Expires: Fri, 18 Aug 2017 07:57:17 GMT。 表示当浏览器再次加载这个资源时,若是时间没有超过,就命中强缓存,使用内存中缓存的资源。
之因此浏览器在再次加载时能够判断出时间是否超过,是由于浏览器在缓存资源时,不只缓存了资源,还缓存了response header相关的内容,好比这里Expires字段。
缺点:因为不能保证服务器和用户端的绝对时间保持一致,因此缓存有时可能会出现混乱的状况, 在HTTP1.1版本中开始使用Cache-Control的方法进行缓存。
Cache-Control是http1.1规范的,一样表示缓存的过时时间。 其中的max-age是做为判断是否过时的主要判据,它是一个相对时间,单位为s。 如知乎上的某一张图片的response header中的字段:cache-control: public, max-age=31536000。 public表明了这张图片是能够被任何用户缓存的,包括代理服务器等; 而max-age是表示在31536000s(一年)内,若是再次请求就使用本地资源。
Cache-Control除了max-age的使用以外,还有几个比较重要的字段:
相同点: 二者都是强缓存。
不一样点:
协商缓存通常是使用 if-modified-since/last-modified 和 if-none-match/etag 由服务器来决定浏览器缓存的资源是否可使用。
在用户请求到资源以后,会返回这个资源,而且在response header中返回一个 last-modifed 字段,这时浏览器就会缓存这个资源以及最后的修改时间, 能够是: last-modified: Fri, 18 Aug 2017 07:27:24 GMT。 接着,当用户再次请求相同的资源时,须要在请求头中添加 if-modified-since 字段,这个字段的值就是以前存储的 last-modifed 的值,服务器获得 if-modified 值以后,会和资源最近的修改时间做比较,若是命中,则返回304,让浏览器使用缓存的资源;不然,返回一个最新的资源而且在 last-modified 修改成最近的资源修改时间。
在用户请求到资源以后,会返回这个资源,而且在response heade 中返回一个 etag 字段,即 entity tag,这个字段的值是一个字符串,惟一的标识了这个资源,只要资源发生了变化,这个etag值就会发生变化。当用户再次请求资源时,会在request header中携带 if-none-match 字段,其值为上次缓存的 etag 值,若是命中,则返回304,使用缓存资源;不然,服务器返回最新的资源。
相同点: 都是为了协商缓存。
不一样点:
代码更新到线上后用户浏览器不能自行更新,咱们不能要求客户在系统更新后都进行一次缓存清理的操做。
在资源请求的URL中增长一个参数,好比:js/mian.js?ver=0.7.1。这个参数是一个版本号,每一次部署的时候变动一下,当这个参数变化的时候,强缓存都会失效并从新加载。这样一来,静态资源,部署之后就须要从新加载。这样就比较完美的解决了问题。
优势:
这是最省资源的方式,浏览器甚至都不须要发起请求。
缺点:
缓存脱离控制,若是缓存时间太长,用户没法访问最新的页面,特别是出现一个紧急的bug的时候,须要一段时间,才能平息。
使用:
在header头部添加Expires、Cache-Control、max-age、last-modified、etag的一个或者是多个,能够在meta中对缓存进行控制。
建议:
js、css、图片能够把缓存时间设置的久一些,永远不过时都是能够的,文件出现变化的时候,经过更换(添加)版本号就行更新。
根据智能DNS解析,用户访问到最近的一台机器,这样就能够减小网络延迟。
用户访问CDN,CDN上若是资源存在而且没有过时,直接返回给用户内容,不然须要先访问源站,而后保存到CDN服务器上面,而后返回用户。
优势:
(1)请求分散,削弱了高流量下的压力。
(2)减小了网络延迟。
缺点:
(1)节点资源可能缓存不一致,致使不一样的用户看到的结果不一样。
(2)若是设置过时时间短或者其余的不合理的回源策略(即又访问源服务器),会致使大量回源,致使访问速度变慢。
(3)高并发期间,一个资源,可能会有多个回源请求。
(4)刷新CDN,须要一段时间, 若是出现bug, 也得登上几分钟。
不少代理服务器都支持了缓存,好比Nginx,Apache。一些动态页面或者接口不怎么更新,好比产品列表等,能够把内容缓存到服务器里面,下次请求的时候,直接读取缓存,动态脚本都不须要执行。动态脚本若是要返回的话,可能须要访问数据库,以及一些其余的服务,这就增长了相应时间。
使用:
nginx,能够配置 proxy_cache
apache,能够配置 mod_cache、mod_disk_cache、mod_file_cache以及mod_mem_cache
是针对php代码。php执行的时候,须要先对php代码解释,生成中间代码,称为opcode,而后再执行。若是缓存住,就能够不须要每一次都解释,这样就能够节省很多资源,增长吞吐量。
优势:
节省资源,增长吞吐量。
缺点:
(1)代码更新,须要等待opcode失效,若是设置不过时,那就须要重启服务器。
(2)opcode主要节省了CPU和内存资源,若是时间消耗主要是磁盘或者是网络IO,那么做用不是太大。
会把计算或者从数据库,以及其余服务得到数据,放到一个文件里面,使用的时候取出来。常见的session就是这么作的。我看phpcms就大量使用这种缓存。
缺点:
1)多台服务器,数据缓存内容可能不一致。为了解决这个问题,曾经挂载共享代理,这就致使磁盘IO成为瓶颈。
2)设置过时时间,不太容易。
为了解决文件缓存存在的问题,就出现了分布式缓存。常见的有memcache,redis.能够搭建集群,设置过时时间。redis,百度都把它当作数据存储来使用。这种缓存在互联网行业当中,大量应用。缺点:须要人维护,消耗大量内存,须要设置过时时间