欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

http缓存 cdn缓存

程序员文章站 2022-06-08 18:39:23
...

一、ETag

初识HTTP缓存-ETag

http缓存 cdn缓存

第一次请求


第一次请求时候请求参数中并没有 If-None-Match 字段但是却有个Pragma;同时在请求的Response中有一个 ETag: W/"a-QFZ79AprHeNlMfPMKXyEUV+lyOg"字段。

http缓存 cdn缓存

第二次请求

 

刷新页面后再次请求在请求头中却有个 If-None-Match: W/"a-QFZ79AprHeNlMfPMKXyEUV+lyOg" ,If-None-Match 的值和第一次请求的ETag的值相同。

也就是说,浏览器会根据HTTP请求的ETag验证请求的资源是否发生了改变,如果它未发生变化,服务器将返回“304 Not Modified”响应,并且资源从浏览器缓存中读取,这样就不必再次下载请求。

为了验证查证的结果,我又添加一个请求处理。这个过程是,客户端明确返回一个ETag, 但是这里每次请求的的返回值都不相同,这里简单的使用了个etag++。

// app.js
const express = require('express');
const app = express();

app.get('/', (req, res) => {
  res.send('hello http');
})


// 验证ETag
let etag = 0;
app.get('/test', (req, res) => {
  etag++;
  res.set('ETag', etag);
  res.send('ETag');
})

app.listen(3000, () => {
  console.log('The server is running at http://127.0.0.1:3000/')
})

查看下 /test 地址的请求结果,会发现If-None-Match 的值和 Response中的 ETag值每次都不相同,并且是 浏览器会将每次的 ETag 值都缓存起来在下次请求的时候发送给服务器。这样一来,每次服务器每次校验的值都是不相同的,所以这种就没有做缓存,因此每次请求 /test 地址都是 200 的状态。

http缓存 cdn缓存

image.png

二、Last-Modified

http响应Last-Modified和ETag
http协议 - 浅谈ETag
Etag是在HTTP 1.1中引入的,为了解决一些Last-Modified无法解决的问题,比如:

  • 一些文件也许会周期性的更改,但是他的内容并不改变(仅仅改变的修改时间),这个时候我们并不希望客户端认为这个文件被修改了,而重新GET;
  • 某些文件修改非常频繁,比如在秒以下的时间内进行修改,(比方说1s内修改了N次),If-Modified-Since能检查到的粒度是s级的,这种修改无法判断(或者说UNIX记录MTIME只能精确到秒)
  • 部分服务器不支持精确时间;

为此,HTTP/1.1引入了Etag(Entity Tags).Etag仅仅是一个和文件相关的标记,可以是一个版本标记,比如说v1.0.0或者说"2e681a-6-5d044840"这么一串看起来 很神秘的编码。但是HTTP/1.1 标准并没有规定Etag的内容是什么或者说要怎么实现,唯一规定的是Etag需要放在""内。

ETag和Last-Modified的作用和用法也是差不多,说一说他们的区别。首先在精确度上,Etag要优于Last-Modified。Last-Modified的时间单位是秒,如果某个文件在1秒内改变了多次,那么他们的Last-Modified其实并没有体现出来修改,但是Etag每次都会改变确保了精度;如果是负载均衡的服务器,各个服务器生成的Last-Modified也有可能不一致。第二在性能上,Etag要逊于Last-Modified,毕竟Last-Modified只需要记录时间,而Etag需要服务器通过算法来计算出一个hash值。第三在优先级上,服务器校验优先考虑Etag。

知乎 关于浏览器的缓存,有了Etaglast-Modified 还有必要存在吗???

三、强缓存和协商缓存

HTTP 缓存机制一二三
一文读懂前端缓存
HTTP 头信息控制缓存大致分为两种:强缓存和协商缓存。强缓存如果命中缓存不需要和服务器端发生交互,而协商缓存不管是否命中都要和服务器端发生交互,强制缓存的优先级高于协商缓存。

http缓存 cdn缓存

匹配流程(已有缓存的情况下)

 

1.Expires

这是 HTTP 1.0 的字段,表示缓存到期时间,是一个绝对的时间 (当前时间+缓存时间),如Expires: Thu, 10 Nov 2017 08:45:11 GMT。在响应消息头中,设置这个字段之后,就可以告诉浏览器,在未过期之前不需要再次请求。但是,这个字段设置时有两个缺点:

  • 由于是绝对时间,用户可能会将客户端本地的时间进行修改,而导致浏览器判断缓存失效,重新请求该资源。此外,即使不考虑自行修改,时差或者误差等因素也可能造成客户端与服务端的时间不一致,致使缓存失效。
  • 写法太复杂了。表示时间的字符串多个空格,少个字母,都会导致非法属性从而设置失效。

2.Cache-control

已知Expires的缺点之后,在HTTP/1.1中,增加了一个字段Cache-control,该字段表示资源缓存的最大有效时间,在该时间内,客户端不需要向服务器发送请求。这两者的区别就是前者是绝对时间,而后者是相对时间。如下:Cache-control: max-age=2592000。Cache-control 的优先级高于 Expires,为了兼容 HTTP/1.0 和 HTTP/1.1,实际项目中两个字段我们都会设置。

Cache-Control 可以由多个字段组合而成,主要有以下几个取值:

(1)max-age
指定一个时间长度,在这个时间段内缓存是有效的,单位是s。例如设置 Cache-Control:max-age=31536000,也就是说缓存有效期为(31536000 / 24 / 60 * 60)天,第一次访问这个资源的时候,服务器端也返回了 Expires 字段,并且过期时间是一年后。

(2)s-maxage
同 max-age,覆盖 max-age、Expires,但仅适用于共享缓存,在私有缓存中被忽略。

(3)public
表明响应可以被任何对象(发送请求的客户端、代理服务器等等)缓存。

(4)private
表明响应只能被单个用户(可能是操作系统用户、浏览器用户)缓存,是非共享的,不能被代理服务器缓存。

(5)no-cache
强制所有缓存了该响应的用户,在使用已缓存的数据前,发送带验证器的请求到服务器。不是字面意思上的不缓存。

(6)no-store
禁止缓存,每次请求都要向服务器重新获取数据。

(7)must-revalidate
如果超过了 max-age 的时间,浏览器必须向服务器发送请求,验证资源是否还有效。

这里有一个疑问:max-age=0 和 no-cache 等价吗?从规范的字面意思来说,max-age 到期是 应该(SHOULD) 重新验证,而 no-cache 是 必须(MUST) 重新验证。但实际情况以浏览器实现为准,大部分情况他们俩的行为还是一致的。(如果是 max-age=0, must-revalidate 就和 no-cache 等价了)

顺带一提,在 HTTP/1.1 之前,如果想使用 no-cache,通常是使用 Pragma 字段,如 Pragma: no-cache(这也是 Pragma 字段唯一的取值)。但是这个字段只是浏览器约定俗成的实现,并没有确切规范,因此缺乏可靠性。它应该只作为一个兼容字段出现,在当前的网络环境下其实用处已经很小。

四、HTTP 缓存实际应用

HTTP 缓存机制一二三
一文读懂前端缓存

1.首先要明确哪些内容适合被缓存哪些不适合

考虑缓存的内容:

  • css样式文件
  • js文件
  • logo、图标
  • html文件
  • 可以下载的内容

一些不应该被缓存的内容:

  • 业务敏感的 GET 请求

2.可缓存的内容又分为几种不同的情况

(1)不经常改变的文件
给 max-age 设置一个较大的值,一般设置 max-age=31536000
比如引入的一些第三方文件、打包出来的带有 hash 后缀 css、js 文件。一般来说文件内容改变了,会更新版本号、hash 值,相当于请求另一个文件。

标准中规定 max-age 的值最大不超过一年,所以设成 max-age=31536000。至于过期内容,缓存区会将一段时间没有使用的文件删除掉。

(2)可能经常需要变动的文件:
Cache-Control: no-cache / max-age=0
比如入口 index.html 文件、文件内容改变但名称不变的资源。选择 ETag 或 Last-Modified 来做验证,在使用缓存资源之前一定会去服务器端做验证,命中缓存时会比第一种情况慢一点点,毕竟还要发请求进行通信。

五、cdn缓存

http缓存与cdn缓存配置指南
闲话 CDN
从HTTP响应头看各家CDN缓存技术

【CDN学习笔记1】CDN基本概念和原理
【CDN学习笔记2】如何判断CDN缓存是否生效
【CDN学习笔记3】CDN缓存规则错误导致网页显示错误和预热失败的案例
【CDN学习笔记4】CDN缓存刷新与预热的区别
【CDN学习笔记5】源站IP变更后导致图片显示不出来的案例
【CDN学习笔记6】CDN回源到阿里云主机被拒绝的案例
【CDN学习笔记7】CDN几种常见的组网方式

Web 缓存大致可以分为:数据库缓存、服务器端缓存(代理服务器缓存、CDN 缓存)、浏览器缓存。浏览器缓存也包含很多内容: HTTP 缓存、indexDB、cookie、localstorage 等等。

cdn缓存是一种服务端缓存,CDN服务商将源站的资源缓存到遍布全国的高性能加速节点上,当用户访问相应的业务资源时,用户会被调度至最接近的节点最近的节点ip返回给用户,在web性能优化中,它主要起到了,缓解源站压力,优化不同用户的访问速度与体验的作用。

1.流程

http缓存 cdn缓存

image.png

 

客户端访问网站的过程:没有CDN:

  • 用户在浏览器访问栏中输入要访问的域名;
  • 浏览器向DNS服务器请求对该域名的解析;
  • DNS服务器返回该域名的IP地址给浏览器
  • 浏览器使用该IP地址向服务器请求内容。
  • 服务器将用户请求的内容返回给浏览器。

使用了CDN:

  • 用户在浏览器中输入要访问的域名。
  • 浏览器向DNS服务器请求对域名进行解析。由于CDN对域名解析进行了调整,DNS服务器会最终将域名的解析权交给CNAME指向的CDN专用DNS服务器。
  • CDN的DNS服务器将CDN的负载均衡设备IP地址返回给用户。
  • 用户向CDN的负载均衡设备发起内容URL访问请求。
  • CDN负载均衡设备会为用户选择一台合适的缓存服务器提供服务。选择的依据包括:根据用户IP地址,判断哪一台服务器距离用户最近;根据用户所请求的URL中携带的内容名称,判断哪一台服务器上有用户所需内容;查询各个服务器的负载情况,判断哪一台服务器的负载较小。基于以上这些依据的综合分析之后,负载均衡设置会把缓存服务器的IP地址返回给用户。
  • 用户向缓存服务器发出请求。
  • 缓存服务器响应用户请求,将用户所需内容传送到用户。如果这台缓存服务器上并没有用户想要的内容,而负载均衡设备依然将它分配给了用户,那么这台服务器就要向它的上一级缓存服务器请求内容,直至追溯到网站的源服务器将内容拉取到本地。

2.缓存规则

在用户第一次访问网站后,网站的一些静态资源如图片等就会被下载到本地,作为缓存,当用户第二次访问该网站的时候,浏览器就会从缓存中加载资源,不用向服务器请求资源,从而提高了网站的访问速度,而若使用了CDN,当浏览器本地缓存的资源过期之后,浏览器不是直接向源站点请求资源,而是向CDN边缘节点请求资源,CDN边缘节点中也存在缓存,若CDN中的缓存也过期,那就由CDN边缘节点向源站点发出回源请求来获取最新资源。

CDN节点缓存机制在不同服务商中是不同的,但一般都遵循HTTP协议,通过http响应头中的Cache-Control:max-age的字段来设置CDN节点文件缓存时间。当客户端向CDN节点请求数据时,CDN会判断缓存数据是否过期,若没有过期,则直接将缓存数据返回给客户端,否则就向源站点发出请求,从源站点拉取最新数据,更新本地缓存,并将最新数据返回给客户端。CDN服务商一般会提供基于文件后缀、目录多个维度来指定CDN缓存时间,为用户提供更精细化的缓存管理。CDN缓存时间会对“回源率”产生直接的影响,若CDN缓存时间短,则数据经常失效,导致频繁回源,增加了源站的负载,同时也增大了访问延时;若缓存时间长,数据更新时间慢,因此需要针对不同的业务需求来选择特定的数据缓存管理。

以腾讯云举例,打开cdn加速服务配置,面板如下。

 

http缓存 cdn缓存

image.png

 

可以看到,提供给我们的配置项只有文件类型(或文件目录)和刷新时间,意义也很简单,针对不同文件类型,在cdn节点上缓存对应的时间。

六、推荐阅读 知乎 大公司里怎样开发和部署前端代码?

大公司的静态资源优化方案,基本上要实现这么几个东西:

  • 配置超长时间的本地缓存 —— 节省带宽,提高性能
  • 采用内容摘要作为缓存更新依据 —— 精确的缓存控制
  • 静态资源CDN部署 —— 优化网络请求
  • 更资源发布路径实现非覆盖式发布 —— 平滑升级

 

相关标签: 综合学习