Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

客户端缓存 #3

Open
moonlightop opened this issue May 31, 2021 · 0 comments
Open

客户端缓存 #3

moonlightop opened this issue May 31, 2021 · 0 comments

Comments

@moonlightop
Copy link
Owner

moonlightop commented May 31, 2021

由HTTP的缓存控制到缓存代理

浏览器缓存

  • memory cache是浏览器为了加快读取缓存的速度而作的优化

    读取速度:寄存器 > 高速cache > 内存 > 磁盘

image-20210530220917952


HTTP缓存控制

条件请求

  • 没有 If 开头的 条件请求 头字段时
1. 用HEAD请求获取该资源的Last-modified 或 ETag
2. 获取到的Last-modified 或 ETag与缓存的资源对比
3. 若资源发生了变化,那么就发送一次GET请求获取新的资源
   否则直接用缓存
  • HTTP定义了一系列的 If 开头的 条件请求 头字段,交由服务端来检验缓存是否过期
       客户端			      服务端
if-Modified-Since		Last-modified	        (弱检验器)	
if-None-Match			ETag			(强检验器)
  • ETag 全称 Entity Tag,资源的唯一标识符,用于解决Last-modified(单位秒)无法准确区分文件变化的问题

    • 强ETag要求资源在字节级别相同
    • 弱ETag要求资源在语义上相同即可(值前面有个 W/ 标记)
  • 图片来源

ETagAndIf-None-Match


两端缓存控制

  • 以前用Expires,缺点就是客户端这边可以修改本地时间,那就乱了呀,而现在Cache-Control: max-age=x,用相对响应报文创建的时间(Date头字段)

image-20210530231938397


  • 响应报文的头字段没有对缓存进行说明时,浏览器会采用一套 启发式算法来尽量缓存一段时间

    • 响应报文提供了Last-modified,但没有提供Cache-Control 或 Expires

      RFC建议:max-age =(Date - Last-modified)* 10%

    • 如果响应报文连Last-modified都没有呢,这个得看具体客户端是采用什么算法去缓存了

  • 响应报文的头字段 Cache-Control: max-age=0时,浏览器会不会缓存该资源呢 ?

    • 会,浏览器收到数据就会将其缓存起来,而内部有一套算法去清除,而max-age是浏览器清除缓存的参照物
  • 返回304和200的区别在于304不会携带实体数据,只是告诉浏览器Not Modified,让它去用缓存


应用

模式1: 不常变化的资源

  • 设置很长时间的强制缓存(时效性不强)
Cache-Control: max-age=31536000

模式2: 经常变化的资源

  • 设置使用前需要验证的强制缓存(时效性很强)
Cache-Control: no-cache
ETag: xxx
Last-modified: xxxx

模式1和2结合

  • 时效性不算太强,也不算太弱,来取个中
no-cache <=> max-age=0,must-revalidate
# 取中间
Cache-Control: max-age=600,must-revalidate
  • 很容易导致不同版本的资源组合在一起,导致报错
假设有三种资源:  index.html  index.js  index.css 存入浏览器缓存
	1. index.html的缓存有效时间先到期,被浏览器清除,而index.js index.css的缓存仍存在。
	2. 而此时浏览器请求到的新版本的index.html和旧版本的index.js和index.css组合很容易会报错

HTTP的代理服务

  • 代理一个是链路增长(成本),另一个交由它人处理(可信度)

client <=> proxy1 server <=> ... <=> proxyn server <=> origin server

  • X-Forwarded-ForVia 头字段经过代理节点就会添加上代理主机的信息

    • 前者添加 请求方的IP地址,后者添加 代理节点的Host
    • X-Real-IP === 仅有一个代理节点的 X-Forwarded-For 添加的IP地址

    via


  • 客户端发送请求报文后,服务端会传来一个TCP报文表示 我将要传输的报文大小,请稍等

    步骤2 和 4的TCP报文作用修改为上述描述

  • 而服务端发送响应报文,请求方收到后会发送TCP报文表示收到该报文

    步骤5 和 7的TCP报文作用修改为上述描述

  • 四次挥手并没有规定是从客户端还是服务端开始,而三次握手是客户端主动发起的

    • 只不过通常都是客户端主动断开,所以看到是客户端先发送tcp,但服务端也可以主动断开(超时,短链接,节约资源)

image-20210531113936424


  • 因为通过X-Forwarded-For || X-IP || Via 都需要修改原始报文,添加上相应的头字段

    • 一方面加大了代理节点的工作量
    • 其次在SSL/TLS加密的情况下,不允许修改原始报文
  • 所以出现了 "代理协议"(The PROXY protocol)

image-20210531123545230


  • 反向代理的负载均衡算法有哪些 ?
    • 加权随机
    • 加权轮询
    • 最小连接法 || 最快连接法
    • 源地址哈希法

缓存代理

HTTPCachtType

源服务器的缓存控制

  • no-transform

    • An intermediate cache or proxy cannot edit the response body,Content-Encoding,Content-Range,or Content-Type

      如:代理有时候会将缓存下来的数据做一些优化(图片生成png 、webp等几种格式),no-transform禁止这些变换

  • 仅在代理服务器生效的头字段,proxy-revalidate | s-maxage | no-transform

  • 图片来源

服务端代理缓存控制


客户端的缓存控制

  • 使用 only-if-cached 请求头字段,如果代理上没有缓存或缓存过期,返回504(GateWay Timeout)
请求报文中 max-age,max-stale,min-fresh 对`当前`缓存的有效时间的约束
    [min-fresh,)
    [start~max-age], start > 0
    [max-age,max-stale]
符合上述条件以及相应的 "Last-modified" and "ETag" 也符合的缓存返回

代理Cache-Control客户端缓存控制

Vary

  • vary主要用在缓存,用来告诉缓存代理此报文依据的是哪些请求头字段返回

    1. 返回带有Vary字段的响应报文给代理服务器,然后代理服务器将【w/ URL 
    and hash】作为key,该响应报文作为value存入缓存中
    * hash是根据vary字段的值,在该报文中提取出相应的值计算hash所得
    
    2. 当有新的请求访问代理服务器时,通过计算请求报文的相关头字段,得到相应的key,看缓存中是否存在
    	存在,则返回缓存
    	否则,向源服务器获取最新资源了
  • 图片来源

HTTPVary

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant