CDN缓存小结

安全咨询 0 276

假设你有一个带有开始页面的博客,这里面列出了所有近期的博客列表。完成这一过程,PHP 脚本要从数据库中获取到最近的文章实体,并且将它们转换成 HTML 结果页并返回给用户。


因此,对于一次请求或者访问包含了:一次php执行+一组数据库的查询,对于1000次请求挥着访问就包含了:1000次php执行+1000组数据库的查询,每一次php执行都要进行cpu,内存和 

I/O操作,对于数据库也是一样的。


当CPU 和内存访问到达极限的时候,访问就会出现问题,速度会开始变得非常的慢,甚至出现不能访问的情况,即便可以利用硬件来突破这一瓶颈,但是其工程会变得非常复杂,所以这时就会需要在中间加一层代理缓存,来减少资源对你的限制。


拿前面的例子来讲,使用代理缓存只有第一次请求需要执行 PHP 脚本、查询数据库和生成 HTML 结果页。所有后面过来的请求都会从这个缓存中取内容,读取缓存几乎和直接读取内存一样快。这意味着,上面的线性规模瓶颈的问题解决了!100 个用户或者1000 个用户都没关系,依然只有 1 次 PHP 执行、1 次数据库查询和 1 次的结果页生成。


CDN如何起作用?

实际上CDN的类型也有所不同,起分为‘pull cdn’和‘push cdn’两种,顾名思义,‘push cdn’表示你要给cdn提供相应的内容,但是‘pull cdn’则表示如何从cdn中取内容。


* pull cdn如何起作用的呢?*


我们来做个例子,假设你有一个可访问的网站,URL 是 https://www.fooer.com。在这样的场景下,域名fooer.com 会被放到 pull CDN 服务器中,而不是你的网站服务器中。CDN 作为你网站服务器的一个代理。


还有一个不被公开的域名指向实际的网站服务器。在这个例子中假设它是 direct.fooer.com,实际网站服务器叫做源。


这个 CDN 将会接受所有的请求。如果它的缓存中有结果的话将会直接返回给用户,否则会将这个请求托管给你实际的网站服务器,然后把返回的结果缓存起来为以后的请求做储备,同时将结果返回给用户。


最简单的pull cdn的运行过程如下:


获取一个页面的请求,例如这个页面就是fooer.com/some/page

把some/page当作缓存key检查缓存中是否存在

在缓存中则直接从缓存中直接返回结果给用户

不在缓存中则请求https://www.fooer.com/some/page,把返回的结果以/some/page作为key写入缓存,并返回给用户

3.缓存头

绝大多数的 pull CDN 采用以“每页”缓存形式解决动态内容的问题。为了达到这样的效果,一个简单的方法是 HTPP 响应缓存头。


关于http缓存头,新版最常见的就是 ETag 和 Cache-Control 这两个标签,但是旧版还支持Expires,Pragma 和 Age等多个便签,不过这些都是作为向后兼容来使用的。


ETag:


ETag:它是文档版本的标识符。通常是内容的 MD5 值,不过它也可以包含其他内容,代表的是文档的版本/日期,如: 1.0 或者 2017-10-30。这里注意一点是,它必须用双引号括起来,如:ETag: “d3b0756geyg42sd3edec49eaa6238ad5ff00”。


二次验证:


ETag 的实际应用:二次验证。我们暂时不考虑前面代理+源的架构模式,只考虑简单的客户端-服务器模式。


假设客户端请求了 http://www.fooer.com/hello.txt,接着服务端返回如下的内容: 



在响应里面,有两个有意思的头标识:一个是 ETag,内容的 MD5值,一个是 Last-Modified,这是 hello.txt 文件最后一次被修改的时间。


这里就是二次验证起作用的地方:当客户端在很短的时间内再次访问上面的 URL,客户端浏览器会使用 If-* 请求头。如 If-None-Match 检查 ETag 的内容是否有改变。也就是说,如果 ETag 发生变化,客户端接收到的一个完整的新响应;如果 ETag 没变化,客户端接收到的是一个表明内容没变化的标识。


 

如果 ETag 没有改变,那么服务端将会返回: 



正如上面所展示的,这次服务器的响应里面不是 200 ok,而是304 Not Modified,这就是说它略过包体部分,让客户端直接去自己的缓存里拿数据。在这个例子中,包体内容是 the body,比较小,效果不明显。可是想象一下如果是很大的内容呢,或者是很复杂的动态生成内容呢,价值就很大了。


我们都知道,你最想缓存起来的是内容,生成内容的代价是最大的,所以 ETag 头是更好的选择。


Cache-Control头


Cache-Control 既可以用于请求头,也可以用于响应头,其次它控制着两个缓存:本地缓存(私有缓存)和共享缓存。


本地缓存:是指在客户端本地机器中的缓存。它并不完全受你的控制,通常浏览器会自己决定是否把某些内容放到缓存中,这意味着:不要依赖于本地缓存。用户也可能在关闭浏览器的时候清理所有缓存,而你并不知道有这样的操作。

共享缓存(CDN):处于客户端和服务器之间的缓存,即CDN。

Cache-Control 有几种属性:


private:表示它只应该存在本地缓存

public:表示它既可以存在共享缓存,也可以被存在本地缓存

no-cache:表示不论是本地缓存还是共享缓存,在使用它以前必须用缓存里的值来重新验证

no-store:表示不允许被缓存。

max-age=:设置缓存时间,设置单位为秒。本地缓存和共享缓存都可以

s-maxage=:覆盖 max-age 属性。只在共享缓存中起作用。

immutable:表示文档是不能更改的。

must-revalidate:表示客户端(浏览器)必须检查代理服务器上是否存在,即使它已经本地缓存了也要检查。

proxy-revalidata:表示共享缓存(CDN)必须要检查源是否存在,即使已经有缓存。


也许您对下面的内容还感兴趣:

留言0

评论

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。