学习笔记 HTTP权威指南 第7章 缓存

219 阅读7分钟

上一章介绍了整个HTTP结构中的代理这一环节,而在代理里面甚至是整个HTTP结构中,缓存是最重要的代理.所以这一章就专门介绍了为什么需要缓存,缓存的基本术语以及缓存的工作流程和如何操作缓存.

7.1 为什么需要缓存

7.1.1 冗余数据传输

  • 为什么会产生冗余传输
    • 多个客户端请求同一服务器,服务器会把相同的资源单独发送到每一个客户端
    • 如果把缓存放到客户端的路由器上,那么同一路由器所有电脑的请求都不需要服务器传输了

7.1.2 带宽瓶颈

  • 为什么会有瓶颈
    • 本地网络一般是100M/s,而服务器下行带宽一般只有几M/s
    • 从服务器请求资源肯定只有几M/s
    • 如果把资源缓存在本地网络,那么速度就是100M/s了

7.1.3 瞬时拥塞

  • 什么是瞬时拥塞
    • 就是在重大情况或事件发生时,网络访问量突然激增,导致网络卡.比如双11,明星离婚

7.1.4 距离时延

  • 为什么会有距离时延
    • 数据通过电波/光来传输,但是光本身的速度是限的.
    • 如果客户端和服务器在地球的2端,光来回跑,根据请求的多少,会导致几十ms甚至几百ms的延时
    • 如果算上中间路由和代理的损耗,时间更长

7.2 有关缓存的术语

7.2.1 缓存命中

  • 什么是缓存命中
    • 请求达到缓存代理,并由缓存资源提供响应

7.2.2 缓存未命中

  • 什么是缓存未命中
    • 请求达到缓存代理,但没有合适的缓存资源,请求被转发到原始服务器

7.2.3 缓存再验证

  • 什么是缓存再验证

    • 代理向原始服务器发送请求验证当前缓存是否需要更新
  • 为什么需要再验证/新鲜度检测

    • 原始服务器上的资源有可能已经更新或者被删除了
    • 要保证缓存和原始资源一致
  • 什么时候进行再验证

    • 在客户端发起请求后
    • 并且缓存资源变得很旧的时候向服务器进行验证
  • 再验证的几种结果

    • 再验证命中
      • 验证后发现资源未发生变化
      • 更新缓存头部信息
    • 再验证未命中
      • 验证后发现资源已经变化
      • 更新整个缓存,包括头部和主体
    • 对象被删除
      • 服务器的资源已经删除
      • 删除缓存

7.2.4 命中率

  • 什么是缓存命中率
    • 所有请求中,有多少响应是从缓存提供
  • 什么是字节命中率
    • 缓存提供的字节在所有请求的字节中所占的比例
  • 为什么需要字节命中率
    • 因为有些请求虽然少,但体积可能非常大
    • 所以用字节命中率统计流量非常有用
  • 怎么区分响应是否来自缓存
    • 响应中的Date首部如果小于当前时间
    • 通过响应中的Date和Age首部判断

7.3 缓存的结构

  • 缓存有哪几种分类

    • 私有缓存: 如浏览器自带的缓存
    • 公有缓存: 如CDN
  • 缓存有哪几种结构

    • 层次结构
    • 网状结构
  • 层次结构和网状结构的区别

    • 层次结构是串联的,1层没找到缓存就向父级缓存再找直到服务器
    • 网关结构是蜘蛛网形的,有可能被转发到任意的缓存上获取资源
  • 网状缓存有哪些功能

    • 在父缓存和原始服务器之间进行选择
    • 动态选择父缓存
    • 允许其他缓存对访问本地缓存
  • 什么是对等缓存

    • 将互联网上的其他缓存联合起来,组成一个巨大的缓存网
    • 资源互相共享的缓存网就是对等缓存
    • 其中的每一个缓存都是兄弟缓存
    • 如ICP,HTCP

7.4 缓存的处理步骤

缓存的处理步骤和代理的处理步骤是一样的7步,只是 细微的关于新鲜度检测这一块需要单独说明一下.

  • 接收请求
  • 解析请求
  • 查找资源
    • 查找资源的步骤
      • 先找本地缓存
      • 如果没有的话去服务器/父缓存中取
  • 新鲜度检测
    • 哪些情况下需要检测新鲜度
      • 过期时间超过了限值
      • 客户端要求检测
  • 构建响应
    • 响应包含哪些内容
      • 原始资源的头部
      • 原始资源的主体
      • 缓存相关信息,如Age,Cache-Control等
  • 发回响应
  • 记录日志

7.5 如何保持缓存的新鲜度

  • 怎么判断文档是否过期

    • Cache-Control: max-age
    • Expires
  • 为什么推荐使用max-age

    • max-age是指Date之后的多长时间
    • Expires是指具体的一个时间值
    • 不同的服务器解析时间值的方法可能不一样,所以用Expires可能会导致差异
  • 设置过期时间的目的

    • 服务器资源随时可能变化
    • 给个到期时间提醒缓存需要验证是否发生了变化
  • 再验证的工作流程

    • 如果资源发生了变化 -> 获取新的缓存 -> 转发给客户端
    • 如果资源未变化 -> 获取新的首部 -> 转发给客户端
  • 为什么要用GET条件方法进行再验证

    • 发送一个带条件的GET方法
    • 只有满足条件时才返回实体资源
    • 可以减少网络流量
  • 用于条件GET的2个首部

    • If-Modified-Since:
    • If-None-Match:
  • IMS的不足之处

    • 有些文件会周期性的重写,变化的只是日期,内容不会变化,会导致重新更新缓存
    • 有些文件虽然更新了内容,但只是变了些无关紧要的部分,如注释,也会导致缓存更新
    • 有些文件是实时更新的,过期时间是秒就无法满足要求了
  • 什么是缓存验证器

    • 除了过期时间以外,还可以通过实体标签验证缓存资源
    • 这两个都属于缓存验证器
  • 为什么需要区分强弱验证器

    • 有些资源发生了不重要的变化,不需要重新更新缓存
    • 这种情况只更新强标签,而不用更新弱标签
    • 以弱标签为判断依据的缓存就没必要更新了
  • 弱标签的表现形式

    • 会在实体标签前面加上一个W/用于区分
  • 什么情况下使用IMS和实体标签验证

    • 响应只返回了Last-Modified的时候使用IMS
    • 响应只返回了ETag时使用实体标签验证
    • 如果都返回了,两种方式都要使用

7.6 服务器怎么控制代理缓存

  • Cache-control: no-store

    • 禁止缓存
  • Cache-Control: no-cache

    • 可以缓存,但是每次请求都必须进行新鲜度检测
  • Pragma: no-cache

    • 和no-cache一致
    • 只是为了兼容HTTP/1.0
  • Cache-Control: max-age=100

    • 最大存活时间
  • Cache-Control: s-maxage=100

    • 作用同max-age
    • 只适用于共享缓存
  • Expires:

    • 具体的某个时间点过期
  • Cache-Control: must-revalidate

    • 没搞懂他和no-cache的区别
  • 什么是试探性过期

    • 当服务器没有提供Expires也没有提供Cache-Control: max-age时
    • 代理自动推算过期时间
  • 设置试探性过期的几种方式

    • 通过算法估算
    • 设置成一个固定值

7.7 客户端如何控制缓存

  • Cache-Control: max-stale
  • Cache-Control: max-stale=s
  • Cache-Control: max-fresh=s
  • Cache-Control: max-age=s
  • Cache-Control: no-cache
  • Cache-Control: no-store
  • Cache-Control: only-if-cached
  • Pragma: no-cache

7.8 如何设置缓存

7.8.1 Apache

这个就不用做笔记了吧.如果以后要搞全栈,那就要专门看Apache的书了

7.8.2 HTML元信息标签HTTP-EQUIV

  • HTTP-EQUIV是什么
    • 就是一个HTML元素
    • 专门用于指定该HTML文档的缓存信息
<meta http-equiv="Cache-Control" content="no-store">
  • 为什么不推荐使用HTTP-EQUIV
    • 很少有服务器实现这个功能
    • 浏览器虽然实现了这个功能,但和代理实现的逻辑可能不一样

7.9 新鲜度的详细算法

暂时涉及到算法的部分,先全部跳过吧

7.10 缓存和广告

  • 为什么广告商讨厌缓存

    • 广告商一般是根据广告展现次数收费
    • 有了缓存之后,流量都从缓存走了,不经过广告商
    • 就收不到广告费啦
  • 如何解决缓存拦截流量

    • 设置no-cache
    • 通过CGI网关提供广告
    • 重写广告URL
    • 在缓存上配置,每次都进行再验证
    • 将命中日志报告发给服务器
    • 使用HTTP/1.1中的Meter首部