注明:文中Http缓存部分整理自https://zhuanlan.zhihu.com/p/29750583
磁盘I/O:
数据从磁盘复制到内核空间,然后从内核空间复制到用户空间,这会很缓慢。这时操作系统为了加速I/O访问,在内核空间使用缓存机制。
存储器的层次结构:
层次结构中每一层都缓存来自较低一层的数据对象。举例:本地磁盘作为远程磁盘中取出的文件的缓存,贮存作为本地磁盘上数据的缓存,依次类推,知道最小的缓存——CPU寄存器集合。
Http缓存:
大致分为强缓存和协商缓存。强缓存命中不需要和服务端交互,而协商缓存不管是否命中都需要和服务器交互,强制缓存的优先级高于协商缓存。
强缓存:
对强缓存来说,响应头中有两个字段 Expires/Cache-Control 来表明规则。
Expires 指缓存过期的时间,超过了这个时间点就代表资源过期。
Expires 是 HTTP/1.0 的标准,现在更倾向于用 HTTP/1.1 中定义的 Cache-Control。两个同时存在时也是 Cache-Control 的优先级更高。
Cache-Control 可以由多个字段组合而成,主要有以下几个取值:
max-age 指定一个时间长度,在这个时间段内缓存是有效的,单位是s。
public 表明响应可以被任何对象(发送请求的客户端、代理服务器等等)缓存。
private 表明响应只能被单个用户(可能是操作系统用户、浏览器用户)缓存,是非共享的,不能被代理服务器缓存。
no-cache 强制所有缓存了该响应的用户,在使用已缓存的数据前,发送带验证器的请求到服务器。
no-store 禁止缓存,每次请求都要向服务器重新获取数据。
协商缓存:
缓存的资源到期了,并不意味着资源内容发生了改变,如果和服务器上的资源没有差异,实际上没有必要再次请求。客户端和服务器端通过某种验证机制验证当前请求资源是否可以使用缓存。Last-modified/If-Modified-Since:
Last-modified: 服务器端资源的最后修改时间,响应头部会带上这个标识。Last-modified 要记得配合 Expires/Cache-Control 使用。
Etag/If-None-Match
服务器端生成的hash字符串
Etag和Last-modified的比较
- 某些服务器不能精确得到资源的最后修改时间,这样就无法通过最后修改时间判断资源是否更新。
- Last-modified 只能精确到秒。
- 一些资源的最后修改时间改变了,但是内容没改变,使用 Last-modified 看不出内容没有改变。
- Etag 的精度比 Last-modified 高,属于强验证,要求资源字节级别的一致,优先级高。如果服务器端有提供 ETag 的话,必须先对 ETag 进行 Conditional Request。
实际应用:
考虑缓存的内容:
- css样式文件
- js文件
- logo、图标
- html文件
- 可以下载的内容
一些不应该被缓存的内容:
- 业务敏感的 GET 请求