我们应该从两个角度来看http的缓存:缓存控制 和 缓存校验。
缓存控制:控制缓存的开关,用于标识请求或访问中是否开启了缓存,使用了什么样的存方式。
缓存校验:如何校验缓存,缓存的有效期,如何确定缓存是最新的。

一、缓存控制

  http中控制缓存开关的字段有两个:Pragma 和 Cache-Control。

  Pragma已经基本淘汰,下文我们重点关注 Cache-Control 。

  在介绍之前,我们先说明一下比较容易忽略的俩个点:

  1、符合缓存策略时,服务器不会发送新的资源,但不是说客户端和服务器就没有会话了,客户端还是会发请求到服务器的。

  2、Cache-Control除了在响应中使用,在请求中也可以使用。如下图:(在开发者工具中,禁用缓存)

同时在Response Headers中也能到Cache-Control字段,这是服务端设置的,如下图:

Cache-Control字段:

请求中使用Cache-Control 时,它可选的值有:

响应中使用Cache-Control 时,它可选的值有:

在Cache-Control 中,这些值可以自由组合,多个值如果冲突时,也是有优先级的,而no-store优先级最高。

public和private的选择

  如果你用了CDN,你需要关注下这个值。CDN厂商一般会要求cache-control的值为public,提升缓存命中率。如果你的缓存命中率很低,而访问量很大的话,可以看下是不是设置了private,no-cache这类的值。如果定义了max-age,可以不用再定义public,它们的意义是一样的。

 哪里设置Cache-Control

  以LNMP的环境为例,一次响应经历的过程是:php-cgi解析代码并执行,将结果返回给nginx,如果nginx前面有反向代理,则会经过一次反向代理服务器,所以cache-control可能会在nginx,php-cgi,php代码,反向代理服务器这些地方地方设置。在php.ini中,有个参数是session.cache_limiter,需要注意下。

在nginx中有个很常见的配置:

location ~* ^.+\.(ico|gif|jpg|jpeg|png)$ {
expires 30d;
}

  这个指令等同于cache-control: max-age=2592000,同时你会在响应头部看到一个etag字段,这是由于nginx默认开启,如果要关闭可以增加个配置etag off。etag就是我们接下要看的缓存校验字段。

二、缓存校验

  在缓存中,我们需要一个机制来验证缓存是否有效。比如服务器的资源更新了,客户端需要及时刷新缓存;又或者客户端的资源过了有效期,但服务器上的资源还是旧的,此时并不需要重新发送。缓存校验就是用来解决这些问题的,在http 1.1 中,我们主要关注下Last-Modified 和 etag 这两个字段。

Last-Modified
  服务端在返回资源时,会将该资源的最后更改时间通过Last-Modified字段返回给客户端。客户端下次请求时通过If-Modified-Since或者If-Unmodified-Since带上Last-Modified,服务端检查该时间是否与服务器的最后修改时间一致:如果一致,则返回304状态码,不返回资源;如果不一致则返回200和修改后的资源,并带上新的时间。

If-Modified-Since和If-Unmodified-Since的区别是:
If-Modified-Since:告诉服务器如果时间一致,返回状态码304
If-Unmodified-Since:告诉服务器如果时间不一致,返回状态码412

etag
  单纯的以修改时间来判断还是有缺陷,比如文件的最后修改时间变了,但内容没变。对于这样的情况,我们可以使用etag来处理。
  etag的方式是这样:服务器通过某个算法对资源进行计算,取得一串值(类似于文件的md5值),之后将该值通过etag返回给客户端,客户端下次请求时通过If-None-Match或If-Match带上该值,服务器对该值进行对比校验:如果一致则不要返回资源。
  If-None-Match和If-Match的区别是:
  If-None-Match:告诉服务器如果一致,返回状态码304,不一致则返回资源
  If-Match:告诉服务器如果不一致,返回状态码412

总结
  缓存开关是: pragma, cache-control。
  缓存校验有:Expires,Last-Modified,etag。
  从状态码的角度来看,它们的关系如下图:

  

  cache-control的各个值关系如下图:

  

http 缓存机制简介的更多相关文章

  1. Mybatis的一级缓存机制简介

    1.接口 public interface MemberMapperCache { public Members selectMembersById(Integer id); } 2.配置文件xml ...

  2. 【Hibernate 7】浅谈Hibernate的缓存机制

    一.Hibernate缓存机制简介 对于Hibernate本身来说,它的缓存主要包括三部分:session缓存(一级缓存).二级缓存.查询缓存. 1.1,session缓存 随着session的关闭而 ...

  3. H5离线缓存机制-manifest

    简介:Manifest 其实就是web应用的一种缓存机制,主要用于现在webapp应用中,它是浏览器自己的一种机制,随着移动互联网时代的到来,网络可靠性降低,如果我们已经将需要的文件缓存下下来,一旦网 ...

  4. Solr4.8.0源码分析(18)之缓存机制(一)

    Solr4.8.0源码分析(18)之缓存机制(一) 前文在介绍commit的时候具体介绍了getSearcher()的实现,并提到了Solr的预热warn.那么本文开始将详细来学习下Solr的缓存机制 ...

  5. Hibernate 缓存机制全面讲解

    简介 为了降低应用程序访问我们的数据的时候的频率,提高数据读取的速率.比如计算机中为了缓解CPU和内存之间速度差异而引入的缓存是一样的道理.Hibernate同样对缓存进行了支持,使得程序的运行效率得 ...

  6. 聊聊MyBatis缓存机制【美团-推荐】

    聊聊MyBatis缓存机制 2018年01月19日 作者: 凯伦 文章链接 18778字 38分钟阅读 前言 MyBatis是常见的Java数据库访问层框架.在日常工作中,开发人员多数情况下是使用My ...

  7. Django的缓存机制和信号量相关

    缓存介绍 缓存的简介 在动态网站中,用户所有的请求,服务器都会去数据库中进行相应的增,删,查,改,渲染模板,执行业务逻辑,最后生成用户看到的页面. 当一个网站的用户访问量很大的时候,每一次的的后台操作 ...

  8. 【转】MyBatis缓存机制

    转载:https://blog.csdn.net/bjweimengshu/article/details/79988252. 本文转载自公众号 美团技术点评 前言 MyBatis是常见的Java数据 ...

  9. Django的缓存机制和信号

    Django的缓存机制 1.1 缓存介绍 1.缓存的简介 在动态网站中,用户所有的请求,服务器都会去数据库中进行相应的增,删,查,改,渲染模板,执行业务逻辑,最后生成用户看到的页面. 当一个网站的用户 ...

随机推荐

  1. Bootstrap4 glyphicon 移除图标 glyphicon fonts-faces 解决方案

    bootrap3是支持的图标 ,4不支持 4已经移除了 收费图标,取而代之建议使用其他的,比如 https://octicons.github.com/ 和http://fontawesome.io/ ...

  2. Java自学-接口与继承 隐藏

    Java中的方法隐藏 与重写类似,方法的重写是子类覆盖父类的对象方法 隐藏,就是子类覆盖父类的类方法 步骤 1 : 父类 父类有一个类方法 :battleWin package charactor; ...

  3. 基于elementUI创建的vue项目

    这周对公司的内容使用vue进行重构,所以记录一下开始项目的过程 下载elementUI: 项目文件夹中在命令行中输入:npm install elementui -s 下载完成后在 main.js 中 ...

  4. Vue学习之基础及部分指令小结(一)

    一.理解MVC和MVVM的关系: MVC:Model View Controller (模型 视图 控制器) 分别为:业务逻辑.界面.用来调度View和Model层 MVVM:Model View V ...

  5. 1 Dalvik和Java虚拟机

    Dalvik虚拟机特点: 1.  体积小 2.  DEX格式可执行文件,相比java运行速度快 3.  常量池采用32位索引值 4.  提供对象生命周期,堆栈,线程,权限,异常等管理 5.  Andr ...

  6. 升级.net core 3.x 后mvc项目调试状态编辑view代码不能实时预览

    https://stackoverflow.com/a/58126955 简单来说 需要在nuget上安装Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilati ...

  7. 3.kettle-定时执行任务

    kettle定时任务可以 用两种方法. 第一种如下,但这种缺点也很明显,就是该job窗口不能关闭.(重复时间含义问题截图来自https://www.cnblogs.com/biehongli/p/10 ...

  8. sudo的使用

    1. sudo:临时提权(提升权限)的工具通常,实际操作中,采用sudo的管理方式,临时的允许某个用户操作某些指令时,拥有root权限. 2. 使用方法: 配置sudo,决定,哪些用户,可以使用roo ...

  9. Linux 修改时区(PDT修改为CST)

    方法1: Linux 修改时区 本文链接:https://blog.csdn.net/Aritem/article/details/79213306 命令:tzselect 按照顺序依次输入5,9,1 ...

  10. 伪分布式下Hadoop3.0打不开localhost:50070

    伪分布式下Hadoop打不开localhost:50070,可以打开localhost:8088 1.对hdfs进行format hadoop namenode -format 在选择Y/N时输入大写 ...