Java

http缓存 cdn缓存

2019-05-10  本文已影响0人  合肥黑
一、ETag

初识HTTP缓存-ETag

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

刷新页面后再次请求在请求头中却有个 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 的状态。

image.png
二、Last-Modified

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

为此,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 头信息控制缓存大致分为两种:强缓存和协商缓存。强缓存如果命中缓存不需要和服务器端发生交互,而协商缓存不管是否命中都要和服务器端发生交互,强制缓存的优先级高于协商缓存。

匹配流程(已有缓存的情况下)
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.首先要明确哪些内容适合被缓存哪些不适合

考虑缓存的内容:

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

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.流程
image.png

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

使用了CDN:

2.缓存规则

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

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

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


image.png

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

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

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

上一篇下一篇

猜你喜欢

热点阅读