Web 相关的缓存技术,我其实不是太懂;这里谈谈我的浅见;本文参考《HTTP权威指南》第7章。
网络相关的缓存技术,大致上包括:
- 浏览器缓存(HTTP缓存)
- 代理缓存
- 数据库缓存
- 页面缓存
no-cache
和 no-store
的区别是啥?
数据库缓存
实际上,就是平常所说的缓存数据库,redis & memcached 等 nosql 数据库。
我们可以将一些读取非常频繁的数据,比如访问次数,表单中显示的数据等,存储在 redis,memcached 等基于内存的nosql数据库中,作为缓存,提高响应速度。
- 读取缓存失败时,将会从mysql中取数据,并设置redis相应的数据库缓存。
- 当更新 mysql 数据库时,也更新 redis 相应的数据库缓存。
静态页面缓存
我们可以将一些访问量大,但更新不很频繁的页面,生成 html 文件。每当我们更新数据时,就重新生成一次html页面,这适用于”首页”和”关于我”等页面,因为是 html 页面,不需要动态执行,也不需要从数据库取数据,所以访问速度很快。
代理缓存
反向代理隐藏了真实的服务端,当我们请求www.google.com 的时候,就像拨打10086一样,背后可能有成千上万台服务器为我们服务,但具体是哪一台,你不知道, 也不需要知道,你只需要知道反向代理服务器是谁就好了,www.google.com 就是我们的反向代理服务器,反向代理服务器会帮我们把请求转发到真实的服务器那里去。
其实反向代理也可以理解为服务器,反向代理服务器是代理服务器改用于特定目的时的代名称
。可以在防火墙外部用它来向外部客户机表示一个安全内容服务器,以防从公司外部直接、不受监视地访问服务器数据。不直接访问的原因和我们不使用裸指针而使用智能指针或者句柄差不多,安全。
反向代理服务器,在数据转发过程中,可以缓存一些数据,以提高响应速度。
HTTP缓存
HTTP缓存(浏览器缓存)一般是在服务器中设置的,也可以通过页面的 HTTTP-EQUIV 属性设置。
1 | <meta HTTP-EQUIV="Cache-control" CONTENT="no-cache"> |
就算我们不在服务器配置 HTTP 缓存,现代的浏览器也会通过使用自己的算法进行缓存,不过缓存的时间一般比较短。
也可以附加 Cache-Control
设定缓存的生命周期&优先级:
从上到下,优先级一次降低。(下面展开谈优先级问题)
max-age & Expires
max-age
的优先级高于 Expires
1 | location ~ .*\.(gif|jpg|jpeg|bmp|png|ico|txt|js|css)$ |
- 在7d之内,该缓存文件都是“新鲜”的
- 超过7d,该缓存文件就是“过期”的
浏览器每次请求一个文件时,会先检查是否存在本地缓存:
- 如果没有缓存,则向服务器发送请求,下载该文件到本地
- 如果本地有缓存,则进一步检查缓存是否”新鲜”
- 如果缓存“新鲜”,就直接从缓存中取数据,并不会向服务器发送请求
- 如果缓存“过期 ”,则需要向服务器发送请求,检查该缓存是否需要替换,如果服务器文件没有修改,则不需要替换,服务器返回304 not modified,并将缓存续期7d;如果服务器文件已修改,则下载新的文件,覆盖原来的缓存文件,服务器返回200 ok,新缓存也是7d后“过期”。
no-cache & store
配置如下:
1 | location ~ .*\.(gif|jpg|jpeg|bmp|png|ico|txt|js|css)$ |
也就是如果真的不让浏览器使用缓存,应该设置 Cache-Control:no-store
。(no-cache
看下面)
还有一种情况就是,我们修改了服务器上的css文件,由于该css文件的max-age还没有到期,所以浏览器默认会从本地缓存中获取该css文件,并知道服务器上的文件已经修改。这时,用户看到的样式就是旧的css文件显示的样式,通常需要刷新一下页面(强制将max-age置为0),才能看到新的样式。
1 | location ~ .*\.(gif|jpg|jpeg|bmp|png|ico|txt|js|css)$ |
我们可以在服务器上设置 Cache-control:no-cache
,它表示浏览器不能直接使用本地的缓存文件,必须向服务器发送请求验证该文件是否被修改过,如果被修改过则需要下载新的文件进行替换。(没被修改过且没有过期,则可以使用缓存)
这种方法能够保证用户看到的页面都是最新的,但是服务器要处理更多的验证请求,如果文件没有修改,则服务器返回一个 header 为304 Not Modified,body为空的响应。
刷新
没有过期的缓存如果和服务器端已经不一致了,这个时候就应该刷新,强制让缓存过期,去服务端请求(检查本地缓存是否需要替换)
刷新 操作会将 max-age 置0,立即向服务器发送缓存检查的请求。
服务器通过请求头中的If-Modified-Since和If-None-Match和服务器文件中的Last-Modified和ETag进行比对,如果一致则说明文件没有过期,返回状态码304 not modified;如果不一致,说明服务器文件修改过,返回状态码200 ok,下载新的文件覆盖缓存。
强制刷新
强制刷新是强制浏览器从服务器获取新的数据覆盖本地缓存的操作(强制替换)。
头文件不包含本地缓存信息(然后 no cache),重新下载服务器上的最新文件,替换原来的缓存。
刷新和正常点击链接进行的页面跳转,使用缓存的顺序是不同的
参考
- 前端人员谈缓存
- 《HTTP 权威指南》 这本书不仅仅谈 HTTP, 它是从 TCP 谈到 HTTP
Merlin 2018.2 了解前端缓存技术