HTTP缓存机制与CDN

2023-05-16

前提:周末看视频了解到一个关键词,http缓存,然后顺带这了解了一下cdn

web应用程序的缓存大致分为数据库缓存,服务器端缓存(redis以及CDN 等缓存)、本地缓存。
本地缓存还包含很多内容:http缓存,indexdb,cookie,localstorage 等,我主要介绍http缓存相关内容,其他的后期在介绍

http缓存主要是针对图片,css以及js等不经常更新的静态文件

http缓存机制

http缓存请求头

1.Cache-Control
请求/响应头,缓存控制字段,可以说是控制http缓存的最高指令,要不要缓存也是它说了算。
它有以下常用值
  1.1 no-store:所有内容都不缓存
  1.2 no-cache:缓存,但是浏览器使用缓存前,都会请求服务器判断缓存资源是否是最新,它是个比较高贵的存在,因为它只用不过期的缓存。
  1.3  max-age=x(单位秒) 请求缓存后的X秒不再发起请求,属于http1.1属性,与下方Expires(http1.0属性)类似,但优先级要比Expires高。
  1.4 s-maxage=x(单位秒) 代理服务器请求源站缓存后的X秒不再发起请求,只对CDN缓存有效(这个在后面会细说)
  1.5 public 客户端和代理服务器(CDN)都可缓存
  1.6 private 只有客户端可以缓存
2.Expires
响应头,代表资源过期时间,由服务器返回提供,GMT格式日期,是http1.0的属性,在与max-age(http1.1)共存的情况下,优先级要低。
3.Last-Modified
响应头,资源最新修改时间,由服务器告诉浏览器。
4.if-Modified-Since
请求头,资源最新修改时间,由浏览器告诉服务器(其实就是上次服务器给的Last-Modified,请求又还给服务器对比),和Last-Modified是一对,它两会进行对比。
5.Etag
响应头,资源标识,由服务器告诉浏览器。
6.if-None-Match
请求头,缓存资源标识,由浏览器告诉服务器(其实就是上次服务器给的Etag),和Etag是一对,它两会进行对比

为什么要用http缓存

假设我们请求一次服务器,请求头大小1kb,响应头大小1kb,请求文件10kb。

1次请求流量:12kb
这么看没多少,但是如果有几千或者是几万的并发的时候呢,这个时候问题就出来,小带宽不够用了,大带宽有可能会出来浪费的情况。
然后,服务器每次都得去寻找资源文件,下载,服务器的也会出现较大的压力
每次请求,页面都得重新渲染,用户体验也比较差

浏览器缓存主要是 HTTP 协议定义的缓存机制。HTML meta 标签,例如

<META HTTP-EQUIV="Pragma" CONTENT="no-store">

含义是让浏览器不缓存当前页面。但是代理服务器不解析 HTML 内容,一般应用广泛的是用 HTTP 头信息控制缓存。	

使用缓存
1.让服务器与浏览器约定一个文件过期时间——Expires(GMT时间格式)
服务器与浏览器客户端,日常请求对话
第一次请求
浏览器说:服务器老大哥,我现在要上次你给我的那个图,去斗图,给我发一下呗!
服务器:每次跟别人斗图都来跟我要图,你烦不烦人啊,我们约定个时间(Expires),时间没到,别来烦我,最后一次给你,如果时间(Expires)没到还来跟我要图,我把你腿打折!
在这里插入图片描述
之后浏览器每次跟人斗图(请求)都得去对比Expires,判断文件是否失效,不失效不请求,直接使用本地缓存

但是这个时候会出现一个问题,就是Expires已过期,浏览器再次请求服务器,但是文件未发生改变,如何规避掉这个问题

又一次服务器与浏览器客户端的对话
浏览器小弟:服务器大哥,我来要图去斗图了,找到了给我,顺便告诉我失效时间,不到时间我绝对不来打扰你,这次小弟懂事吧,
服务器大哥:小老弟,这次不错,但是吧这次我不仅仅是给你Expires(失效时间),还要给你一个图片最新修改时间(Last-Modified),到时候文件过期了,咱俩核对文件修改时间,对的上的话,
在这里插入图片描述
后续浏览器小老弟斗图(请求)
Expires未过期,小老弟默默的使用本地保存的图片,
Expires过期,服务器大哥带上了文件最新修改时间if-Modified-Since(也就是上次请求服务器返回的Last-Modified),服务器将if-Modified-Since与Last-Modified做了个对比。

if-Modified-Since 与Last-Modified不相等,服务器大哥找了最新的斗图原图,接着返回了新的Expires以及全新的Last-Modified

if-Modified-Since 与Last-Modified相等,服务器返回了状态码304,文件没修改过,你还是用你的本地缓存。

这个时候你是不是觉得万无一失,没有问题,可以安心的玩耍了,不要意思,还会发生一个极端情况。
浏览器小老弟可以自己随意修改Expires,导致失效时间不稳定,
Last-Modified只能精确到秒,假设文件是在1s内发生变动,Last-Modified无法感知到变化,这种情况下浏览器永远拿不到最新的图片

原有基础上再让服务器大哥与浏览器小老弟在过期时间Expires+Last-Modified的基础上,再增加一个文件内容唯一对比标记——Etag与If-None-Match。还有,我之前不是说了Expires有可能被篡改吗,这里我们再加入一个max-age来加以代替之前的(cache-control其中的一个值)

重演之前的对话,
浏览器小弟:之前的煎饼果子再来一套,嘿嘿
服务器,你嘿嘿个大粑粑,图片我给你,过期时间我给你,然后再给你一个max-age=60(单位秒),Last-Modified你也给我收好,再加一个文件内容唯一标识符Etag。
后续斗图(请求)
60s之内不请求,直接使用本地缓存
60s之后浏览器小弟正常要图(请求)并携带这(if-Modified-Since 与If-None-Match),服务器老大哥接着判断浏览器小老弟的请求信息以及携带的信息

If-None-Match与Etag不相等,说明a.js内容被修改过,服务器返回最新a.js与全新的Etag与max-age=60与Last-Modified与Expires

If-None-Match与Etag相等,说明a.js文件内容无任何改变,返回304,告诉浏览器继续使用之前的本地缓存。

虽然上面的思路解决了服务器与浏览器之间的文件差异,但是上面的思路有一个坑,就是在max-age或Expires不过期的时候,浏览器小老弟无法主动感知服务器文件发生改变,只能是用户自己手动强刷

http缓存方案

1md5或者是hash缓存,
之前的浏览器小老弟与服务器老大哥之间的缓存都是建立在每次请求的文件都是在相同的目录以及相同的文件名,如果目录或者是文件名发生改变的时候就会重新请求,管那些什么失效时间乱七八糟的花里胡哨的东西,所以这个时候就出现了新的解决办法。就是通过webpack来解决,每次打包的时候生成新的文件,嘿嘿,简单粗暴的解决了上面说的浏览器小老弟无法主动感知服务器文件发生改变的事情

CDN

我之前就一直听说过cdn的存在,但是一直没怎么了解过,然后今天仔细的了解了一下
先说说cdn是什么,cdn就是构建在网络之上的内容分发,依靠部署在各地的边缘服务器,通过不知道具体什么原理的中心平台的负载均衡,然后进行内容分发,调度等功能模块,使用户可以在就近的服务器获取图片等静态文件,
使用cdn的好处,通过cdn进行分流,使得服务器压力大大减轻,然后因为用户可以就近访问资源,大大的提高了访问速度
由于我没有用过cdn,但是大概可以猜到cdn可能会遇到一些坑就是源文件修改之后,cdn上的文件未更新的问题,大致有两种解决办法就是给静态文件增加版本号,或者是使用cdn提供商的强制刷新

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

HTTP缓存机制与CDN 的相关文章

随机推荐