HTTP缓存的应用,不仅仅是max-age

相信不管是做前端开发还是后端开发的同学,或多或少在开发过程中接触过缓存的概念。最简单的例子就是前端对于静态资源–即css、js、图片等文件资源进行缓存。但是大部分同学知道的可能就是设置Cache-Control: max-age=xxx来设置资源的过期时间,然而缓存的运用在互联网中可谓是无处不在,一个好的缓存方案可以大大提升服务的性能,而一个不好的缓存方案可能会导致网站的可用性降低。所以今天我们就来聊聊HTTP协议中的缓存。

首先HTTP协议中主要涉及缓存的Header就是Cache-ControlExpires,目前阶段来说Expires已经渐渐被淘汰了,所以我们主要讲讲Cache-Control

Cache-Control并不是只有指定max-age过期时间这么一种使用方式,事实上这只是Cache-Control最基础的用法,我们来看看Cache-Control有哪些可以设置的值

  1. private、public和no-cache用来指定客户端和代理缓存的可缓存性
  2. max-age和s-maxage用来指定客户端和代理缓存的缓存时间
  3. must-revalidate和proxy-revalidate用来指定缓存过期后是否必须验证才能使用
  4. no-store用来表明任何地方都不应该缓存内容
  5. 其他一些不常用的设置

首先大家必须要弄清楚的一点是,缓存不仅仅只有浏览器可以缓存,互联网中存在着各式各样的代理缓存。HTTP仅仅是一个应用层的协议,在数据传输的过程中逃不开各种中继的设备,而本身HTTP是明文传输的,所以每个中继设备都可以解析HTTP数据包中的内容,所以如果某个中继设备想,他就可以成为一个代理缓存(想想曾经的某些运行商做的事)。当然HTTP的代理缓存更多还是服务假设者自己做的,但是本质上是一个意思。

那么相对于大家都知道的客户端缓存,代理缓存有什么好处呢?最明显的优势就是:客户端缓存是一对一的,但是代理缓存是一对多的。

从这张图中我们可以看到,对于同一个源服务器可以存在不同的代理(有些CDN就近获取资源就有用到缓存的知识)。如果这些代理都开启来缓存功能,那么用户一在第一次访问数据的时候,代理通过源服务器获取资源返回给用户,并同时缓存来这个请求,这时候用户二再次来请求的时候,就不需要经过源服务器,直接从代理缓存读取就可以来。

所以对于耗时操作而且数据修改不频繁的数据,开启代理缓存对于性能的提升是非常明显的,哪怕你每次缓存的时间只有5秒,对于并发量很高请求带来的性能提升也是不可估量的。

当然这个操作源服务器通过自己设置缓存也可以实现,但是代理缓存的好处是,如果你的代理离用户足够近,那么减少的延时也是非常明显的。比如如果你的服务器在美国纽约,如果你不在国内设置一个代理缓存,那么所有数据都要跨国半个地球再绕回来,而有代理缓存的情况就不一样来。

那么说回来,怎么控制代理缓存的使用?还是靠HTTP协议,在HTTP协议的发展历史中,已经有非常多的实践让协议进行修改和发展,所以目前的缓存方案可以说已经比较完善了。一般来说,代理缓存服务器都会对最新的HTTP协议的标准进行实现,并且适当兼容老得标准,一般不会出现一些魔改实现。所以只要你对HTTP协议的缓存方案充分了解,那么你就可以很好得使用代理服务器的缓存了。

最主要的你需要知道:

  1. 如何控制代理服务是否缓存或者缓存多少时间
  2. 代理缓存时候可以提供过期缓存的内容
  3. 如何进行缓存验证

知道这些之后,配合一个好用的代理缓存,相信能对你的服务带来很大的性能提升。

最后,HTTP协议是所有WEB相关开发的同学都必须要牢牢掌握的基础,仅仅知道POST、GET、Content-Type并不算理解HTTP协议,HTTP协议中还有非常多好玩又好用的内容等着大家去发掘。