本文已参与「新人创作礼」活动,一起开启掘金创作之路。
DNS 缓存
DNS 全程:Domain Name System,即域名系统。
万维网上作为域名和 IP 地址相互映射的一个分布式数据库。
DNS 解析,即通过域名最终得到该域名对应的 IP 地址的过程。
有 DNS 的地方就有缓存。浏览器、操作系统、local DNS、根域名服务器,它们都会对 DNS 结果做一定程度的缓存。
DNS 查询过程:
- 搜索浏览器自身的 DNS 缓存,如果存在,则域名解析到此完成;
- 如果浏览器自身缓存未找到,则会尝试读取操作系统的 hosts 文件看是否存在映射关系,如果存在,则域名解析到此完成;
- 如果 hosts 文件不存在映射关系,则查找本地 DNS 服务器,如果存在,则域名解析到此完成;
- 本地 DNS 服务器还没有找到,它就会向根服务器发出请求,进行递归查询。
CDN 缓存
CDN 全称:content Delivery Network,即内容分发网络。
用户在浏览网站的时候,CDN 会选择一个离用户最近的 CDN 边缘节点来响应用户的请求。
在浏览器本地缓存失效后,浏览器会向 CDN 边缘节点发起请求。当浏览器向 CDN 节点请求数据时,CDN 节点判断缓存数据是否过期,若缓存数据并没有过期,则直接将缓存数据返回客户端;否则 CDN 节点就会向服务器发出回源请求,从服务器拉去最新数据,更新本地缓存,并将最新数据返回给客户端。
CDN 优势:
- CDN 节点解决了跨运营商和跨地域访问的问题,访问延时大大降低;
- 大部分请求在 CDN 边缘节点完成,CDN 起到了分流作用,减轻了源服务器的负载。
浏览器缓存
浏览器缓存其实就是浏览器保存通过 HTTP 获取的所有资源,是浏览器将网络资源存储在本地的一种行为。
-
memory cache:将资源 haunch 则内存中,等待下次访问时不需要重新下载资源,而直接从内存中获取。
-
disk cache:将资源缓存到磁盘中,等待下次访问时不需要重新下载资源,而直接从磁盘中获取。
两者异同:
- 相同点:只能存储一些派生类资源文件;
- 不同点:memory cache 退出进程时数据会被清除;disk cache 退出进程时数据不会被清除;
存储资源:
- memory cache 存储一般为脚本、字体、图片会存在内存当中;
- disk cache 存储一般为非脚本文件(如 css 等)
三级缓存原理:
- 先在内存中查找,如果有,直接加载;
- 如果内存中不存在,则在硬盘中查找,如果有直接加载;
- 如果硬盘中也没有,则进行网络请求;
- 请求到的网络资源缓存到硬盘和内存中。
浏览器的缓存分类:
- 强缓存
- 协商缓存:浏览器在向服务器请求资源时,首先会判断是否命中强缓存,如果没命中,则再判断是否命中协商缓存。
浏览器缓存的优点:
- 减少了冗余的数据传输;
- 减少了服务器的负担,大大提升了网站的性能;
- 加快了客户端加载网页的速度。
强缓存
浏览器在加载资源时,会先根据本地缓存资源的 header 中的信息来判断是否命中强缓存,如果命中则直接使用缓存中的资源,不会再向服务器发送请求。这里 header 中的信息指的是 expires 和 cache-control
- expires
该字段是 http1.0 时的规范,它的值是一个绝对时间(GMT 格式的时间字符串),这个时间代表这个资源的失效时间,在此时间之前,即命中缓存。这个方法缺点明显,即当服务器与客户端时间偏差较大时,就会导致缓存混乱。
- cache-control
cache-control 是 http1.1 时出现的 header 信息,主要是利用该字段的 max-age 值进行判断,它是一个相对时间。(该字段的可选值有很多,基本上就是使用 max-age=多少秒 和 no-cache 两个)
以上两者可以则服务端配置时同时启用,同时启用时 cache-control 的优先级高。
协商缓存
当强缓存没有命中的时候,浏览器就会发送请求到服务器,服务器根据 header 中的部分信息来判断是否命中缓存。如果命中返回 304,告诉浏览器资源未更新,可使用本地缓存。这里的 header 中的信息指的是 Last-Modify/If-Modify-Since 和 ETag/If-None-Match
- Last-Modify/If-Modify-Since
浏览器第一次请求一个资源时,服务器返回的 header 中会加上 Last-Modify,Last-Modify 是一个时间标识该资源的最后修改时间。
当浏览器再次请求该资源时,请求头中会包含 If-Modify-Since,该值为缓存之前返回的 Last-Modify.服务器收到 If-Modify-Since 后,根据资源最后修改时间判断是否命中缓存。如果命中,则返回 304,并且不会返回资源内容,不会返回 Last-Modify。
这种方法的缺点在于:时间精度不够,短时间内资源发生改变,Last-Modify 并不会发生改变。
- ETag/If-None-Match
与上面方法不同的是,ETag/If-None-Match 返回的是一个验证码。ETag 可以保证每一个资源是唯一的,资源变化都会导致 ETag 变化。服务器根据浏览器请求的 If-None-Match 值来判断是否命中缓存。
当服务器返回 304 Not Modified 的响应时,由于 ETag 重新生成过,response header 中还会把这个 ETag 返回,即使这个 ETag 跟之前没有变化。
Last-Modified 与 ETag 可以一起使用,服务器会优先验证 ETag,验证一致才会继续比对 Last-Modified,最后决定是否返回 304.
总结
当浏览器再次访问一个已经访问过的资源时,它会走这样一个流程:
- 看看是否命中强缓存,如果命中,就直接使用缓存;
- 如果没有命中强缓存,就发请求到服务器检查是否命中协商缓存;
- 如果命中协商缓存,服务器会返回 304 告诉浏览器使用本地缓存;
- 否则返回最新资源。