先看一些概念性的术语:

命中率:由缓存提供服务的请求所占的比例被称为缓存命中率;

缓存未命中:其实就是一些到达缓存的请求没有副本可用,而被转发给原始服务器;

再验证:原始服务器上内容可能会发生变化,缓存需要对副本进行检测,看是否为最新的,这种“新鲜度检测”叫HTTP再验证;

缓存主要分为两类:

一,私有缓存

私有缓存是用户个人的缓存,Web浏览器中有内建的私有缓存,大部分浏览器将内容缓存到个人电脑的磁盘和内存中。这些缓存用来提供浏览器向前/向后、保存网页、查看源代码、离线浏览等功能。

二,公有代理缓存

公有缓存是多个用户使用,它是特殊的共享代理服务器,被称为缓存代理服务器,或被称为代理缓存。

缓存的基本步骤:

1,接收;

2,解析:将请求报文解析为片段;

3,查找;

4,新鲜度检测;

5,创建响应;

6,发送;

7,日志;

一,判断缓存是否过期:

1,cache-control: max-age=15400

max-age表示多少时间后过期,单位秒,这里是相对时间,既可以作为请求头,也可以作为响应头,如果请求头中设置max-age=0,表示立即过期,会进行新鲜度的校验,详细见后文。

还有一个s-maxage,仅适用于共享(公共)缓存

2,expires: Tue, 30 Jul 2019 04:59:34 GMT

表示什么时间后过期,这里是绝对时间,取决于用户当前系统时间,因此不建议单以这个为过期标准。

一般情况下,建议使用cache-control: max-age头,相对时间更好一些,如果两个标识都有,那么必须两个都过期了才算过期。

二,如果过期了,会进行新鲜度的校验:

当缓存资源过期时,缓存会向原始服务器发送一个条件请求GET,因为虽然当前缓存资源已经过期,但也有可能资源依然没有变化,所以不一定需要重新去获取资源,这时候就要做新鲜度的校验,对比缓存资源是否需要更新。

1,If-Modified-Since/Last-modified:Thu, 30 May 2019 11:44:49 GMT

这两个是搭配使用的,前者是请求头,后者是响应头,第一次返回数据时,响应头里会包含Last-modified字段,用来表示最近一次更新时间,当缓存资源过期时,缓存就会发送一个条件请求GET,请求头里带有If-Modified-Since,值就是Last-modified之前返回的值,如果检测发现服务器上资源文件最近修改时间和请求头里的这个时间一致,则不需要更新缓存,返回304状态码,这时候响应主体里是不会带有资源内容的,因为不需要更新,所以不返回,并重新更新缓存时间,就是上面说的cache-control: max-age和expires。如果不一致,则重新返回新的资源内容以及最近修改时间,并设置过期时间,状态码200.

2,If-None-Match/Etags: W/"d343901e56dedb646942d7f8d2a7df87"

对于大部分场景,Last-modified是满足的,但是对于一些特殊场景,那么就有问题了:

1️⃣亚秒级别的资源更新,时间相关的,因为Last-modified只能精确到秒级,所以无法精准;

2️⃣对于一些资源的更新,如果只是更新了一些无关紧要的小内容,那其实没必要重新更新缓存资源,我们允许继续使用旧的缓存,那这时候实际上就是一种弱检查;

Etags会返回一段hash的字符串,用来标识当前资源,如果缓存过期,那么If-None-Match就会带上Etags第一次返回过来的值,然后去和服务器上的tag作对比,如果发现不一致,则重新返回资源并更新缓存,如果没有变化,则返回304,更新缓存过期时间。这里示例代码里加了一个W,就表示这是一条弱检查。

但是大部分场景,我们还是使用If-Modified-Since/Last-modified来判断是否需要更新过期资源。

三,强制更新或取消缓存

这里还是用到cache-control头,这里作为请求头

no-store:禁止使用缓存,清除缓存资源,重新去原始服务器上去获取资源;

no-cache:在进行新鲜度校验之前,不能使用缓存。和no-store不一样的是,no-cache并不是不缓存,而是缓存了但是不使用,在新鲜度校验成功后才可以使用缓存;

must-revalidate:在缓存资源过期之后,必须进行新鲜度校验,这里是必须过期之后才起作用;过期后强制校验;(没什么用)

再补充一个stale-while-revalidate: 它表示允许缓存过期后的一段时间内继续使用,同时会发起一个异步新鲜度二次校验,如果资源更改了,那么下次访问的时候就能拿到一个新鲜的,但如果过期时间没有超过stale-while-revalidate给出的时间,第一次的时候一定是取的缓存,这种策略是用速度换取了内容的新鲜程度,需要谨慎使用。

这里补充一个Chrome里的知识点:

我们一般打开一张图片,如果是首次打开,这里就是一个正常的请求,状态码200,图片大小正常,size有值。

但是当我们关掉这个浏览器,再重新打开一个,再次访问刚刚的图片地址,状态码200,会发现这里的size变成了from disk cache,这里表示已经缓存到本地硬盘里中了,所以会直接读取硬盘里的缓存图片,然后返回的报文也是之前缓存的时候的报文。

当我们刷新这个页面,会发现状态码变成了304,size有值了,但是和第一次打开的时候不一样,那么根据之前讲的,304说明浏览器进行了缓存的新鲜度二次校验,那么我们可以猜测,浏览器在刷新的时候,会发一个cache-control: no-cache的请求,进行一个二次新鲜度校验,这里发现图片资源未改变,所以不会重新获取资源,而是继续读取本地缓存,所以状态码为304,而大小为什么不是原图大小,因为二次校验的时候,条件请求如果为否,则不会返回完整资源。

这里应该还有一个size情况是from memory cache,表示是从内存里读取的缓存,这里我没有找到截图,它和from disk cache的区别就是内存里的缓存优先级更高一些,但是如果浏览器关闭,则会清掉,而disk cache是永久性的,除非手动删除硬盘上的缓存,不然一直存在,浏览器关掉也在。所以整个校验流程是:

1,浏览器内存中读取缓存;

2,本地硬盘上读取缓存;

3,从服务器拉取数据,并缓存到本地硬盘和内存中;

end

HTTP系列:缓存的更多相关文章

  1. 《吊打面试官》系列-Redis哨兵、持久化、主从、手撕LRU

    你知道的越多,你不知道的越多 点赞再看,养成习惯 前言 Redis在互联网技术存储方面使用如此广泛,几乎所有的后端技术面试官都要在Redis的使用和原理方面对小伙伴们进行360°的刁难.作为一个在互联 ...

  2. 《吊打面试官》系列-Redis常见面试题(带答案)

    你知道的越多,你不知道的越多 点赞再看,养成习惯 GitHub上已经开源,有面试点思维导图,欢迎[Star]和[完善] 前言 Redis在互联网技术存储方面使用如此广泛,几乎所有的后端技术面试官都要在 ...

  3. iOS图片加载速度极限优化—FastImageCache解析

    FastImageCache是Path团队开发的一个开源库,用于提升图片的加载和渲染速度,让基于图片的列表滑动 优化点 iOS从磁盘加载一张图片,使用UIImageVIew显示在屏幕上,需要经过以下步 ...

  4. iOS 图片加载速度极限优化—FastImageCache解析

    FastImageCache是Path团队开发的一个开源库,用于提升图片的加载和渲染速度,让基于图片的列表滑动起来更顺畅,来看看它是怎么做的.优化点iOS从磁盘加载一张图片,使用UIImageVIew ...

  5. 20191128 Spring Boot官方文档学习(9.9)

    9.9.数据存取 Spring Boot包含许多用于处理数据源的启动器. 9.9.1.配置自定义数据源 要配置自己的DataSource,请在配置中定义该类型的@Bean.Spring Boot可以在 ...

  6. prometheus远程写参数优化

    一.概述 prometheus可以通过远程存储来解决自身存储的瓶颈,所以其提供了远程存储接口,并可以通过过配置文件进行配置(prometheus.yml).一般情况下我们使用其默认的配置参数,但是为了 ...

  7. iOS 图片加载速度优化

    FastImageCache 是 Path 团队开发的一个开源库,用于提升图片的加载和渲染速度,让基于图片的列表滑动起来更顺畅,来看看它是怎么做的. 一.优化点 iOS 从磁盘加载一张图片,使用 UI ...

  8. Redis好文章推荐

    文章来源:掘金   作者:敖丙 Redis-避免缓存穿透的利器之BloomFilter <我们一起进大厂>系列- Redis基础 <我们一起进大厂>系列-缓存雪崩.击穿.穿透 ...

  9. 2020Java程序员架构师面试宝典,学习后面试必过,震惊,本人通过这篇教程,拿到了0个offer

    1. 引言 Java后端学习路线 <吐血整理>顶级程序员工具集 https://github.com/AobingJava/JavaFamily 跟上Java8 经历阿里.头条.腾讯等知名 ...

  10. CRL快速开发框架系列教程六(分布式缓存解决方案)

    本系列目录 CRL快速开发框架系列教程一(Code First数据表不需再关心) CRL快速开发框架系列教程二(基于Lambda表达式查询) CRL快速开发框架系列教程三(更新数据) CRL快速开发框 ...

随机推荐

  1. Python自动化运维 技术与最佳实践PDF高清完整版免费下载|百度云盘|Python基础教程免费电子书

    点击获取提取码:7bl4 一.内容简介 <python自动化运维:技术与最佳实践>一书在中国运维领域将有"划时代"的重要意义:一方面,这是国内第一本从纵.深和实践角度探 ...

  2. java数组的拷贝和扩容

    1.拷贝arraycopy方法 // 拷贝:arraycopy方法 // arraycopy // 第一个参数:原数组 // 第二个参数:原数组元素的起始位置 // 第三个参数:目标数组 // 第四个 ...

  3. Ubuntu环境下使用Jupyter Notebook查找桌面.csv文档的方法

    这个问题困扰了我很久,最后在一个老师发来的完成结果里找到了答案.(奇怪的是教材里没有.老师也不讲.尤其是百度也没有啊啊啊啊) 好了进入正题.教材里的原话是这样的 这行代码实现的环境应该是在window ...

  4. 010_go语言中的maps映射(字典)

    代码演示 package main import "fmt" func main() { m := make(map[string]int) m["k1"] = ...

  5. “随手记”开发记录day16

    今天先对前两天增加的“修改”功能进行测试.然后进行功能的明显划分,丰富账单的添加和显示方法.

  6. 使用免费证书安装 ipa 到真机

    使用免费证书安装 ipa 密码设置 进入 AppleId 官网 登录个人账号 登录进去之后, 找到 Security, 点击 Generate Password... 锁边输入几个字符, 再点击 Cr ...

  7. Probabilistic PCA、Kernel PCA以及t-SNE

    Probabilistic PCA 在之前的文章PCA与LDA介绍中介绍了PCA的基本原理,这一部分主要在此基础上进行扩展,在PCA中引入概率的元素,具体思路是对每个数据$\vec{x}_i$,假设$ ...

  8. Python中ansible的使用

    #!/usr/bin/env python # -*- coding: utf8 -*- # @Author: huangmanyao from ansible import constants fr ...

  9. [Kong 与 Konga与postgres数据库] 之 Kuberneres 部署

    1.Kong的概述 Kong是一个clould-native.快速的.可扩展的.分布式的微服务抽象层(也称为API网关.API中间件或在某些情况下称为服务网格)框架.Kong作为开源项目在2015年推 ...

  10. 炼技术(9): 简约而不简单,永不停歇的测试 -- always_run

    最强战力,永不停歇的测试:always_run 许多工程师写完程序后,都不愿意对自己的程序做仔细测试. 很多测试说会做自动化测试,可能工作好几年都没真做过多少自动化测试. 我们的解决方案是,在系统的测 ...