专栏首页北京马哥教育Web Cache原理,你真的造吗?

Web Cache原理,你真的造吗?

一、Web Cache

在介绍Web cache时,我们需要简单介绍缓存的理解

1.1 缓存解释

缓存通常是基于键值对来缓存的,键通过hash计算后,存放于内存某个空间,所以键可以理解为索引。而值是存放在内存空间或是磁盘空间上。

当用户的用户请求送达至Web服务器,Web服务器会对URL进行hash计算,然后比对缓存(hash表)中的键。如若命中,则根据与之对应的值找到数据存放的位置(这里的值可以理解为指针,指着对应数据存放的位置),从而获取到缓存的结果。

1.2 工作原理

  • 1.2.1 缓存命中

① 客户端请求某个Web数据,会先送至缓存服务器中,缓存服务器本身会监听80号端口接收用户请求

② 当Web缓存服务器收到用户请求之后,会将这个请求送达至代理进程中

③ 进程拆除用户请求报文中的应用层首部,TCP首部,IP首部等,从而获取到请求报文中的URL

④ 对URL进行hash计算,然后和缓存服务器中hash表中的缓存键进行比对,若一致则缓存命中

⑤ 在对应的值所指向的内存或硬盘空间上找到对应的内容数据

⑥构建成响应报文,直接返回给客户端

  • 1.2.2 缓存未命中

① 客户端请求某个Web数据,会先送至缓存服务器中,缓存服务器本身会监听80号端口接收用户请求

② 当Web缓存服务器收到用户请求之后,会将这个请求送达至代理进程中

③ 进程拆除用户请求报文中的应用层首部,TCP首部,IP首部等,从而获取到请求报文中的URL

④ 对URL进行hash计算,然后和缓存服务器中hash表中的缓存键进行比对,不一致则缓存未命中

⑤ 代理服务器会自行封装成请求报文,把自己当做http的客户端,向上游服务器发起请求

⑥ 若内容存在,上游服务器会构建成响应报文,返回给代理服务器。

⑦ 当代理服务器收到响应之后,会检查该对象是否可以缓存,如若可以,会对URL进行hash之后生成一个键,存放到对应的hash表中

⑧ 在相应的内存或磁盘空间上存储对应的内容数据

⑨ 当操作完成之后,会将数据构建成相应报文,然后响应给客户端

1.3 扩展

在用户自己内部的浏览器会有自己的缓存(私有缓存),当用户请求一个首页的时候,会向代理服务器请求,之后缓存在本地的一些链接或者图片,如果在本地存在缓存,那么就直接响应给用户,而无需再向代理服务器请求。所以我们的缓存是有存在多级的

二、缓存失效

现在存在一个问题,那就是如果我们的缓存失效了应该如何处理,正常而已如果缓存过期了,我们应该不再使用此缓存。所以缓存是具有TTL(生命时间值)值的,当这个TTL值过期之前,我们可以正常使用此缓存对象,一旦过期,请求一方就只能到比他更高一级的下一层缓存中的后端服务器去请求资源。

假设某个缓存对象可以缓存7天,但是在第2天,后端服务器已经修改了此对象,那么此时应该如何处理。所以用户如果直接从缓存中获取到的数据就已经不是最新的了。这样可能会导致缓存有效期过期之前用户将无法获取有效的结果。那么如果处理呢?

2.1 缓存的方式

  • 基于绝对时间缓存 在http 1.0时使用的是绝对时间来缓存,可以理解精准的时间算法
  • 基于条件式缓存

到 1.1版本以后,对其缓存功能进行了扩展,引入了几种功能

1、引入相对时长过期时间 2、引入强大可缓存对象控制功能(哪些数据能缓存以及不能缓存) 3、引入条件式缓存

2.2 基于绝对时间

比方说,此次缓存时为中国时区的2016年7月3日9:00 缓存的,缓存的TTL值为7天,那么过期时间应该就是 7天之后(2016年7月10日)9:00 过期,但是如果是在美国,或者欧洲,因为时区的不同,使用绝对时间将会导致缓存缓存不

2.3 基于条件式缓存

  • 基于最后一次缓存时间后询问式验证请求

当用户访问同一个URL时,会发现在自己的缓存空间中存在一个相同的缓存对象,此时他不会了立即使用此缓存,而是去向上游服务器去验证这个缓存是否过期。主动向服务器发起验证请求,去请求一个URL,而且会发一个独特的请求首部(If-Modified-Sinces:time),询问在此时间之后(也就是缓存对象建立的时间之后),你是否发生了修改。如果后端服务器发现此资源未修改,会响应304(原始数据未修改)的响应码,由于资源未改变,所以此处发送的仅仅是响应码,数据无需发送。当客户端接收到响应后,就会直接使用本地的缓存。

如果后端服务器发现此资源已经修改,那么会找到对应的资源,然后发一个200(原始数据已修改)的响应码,并将资源发送给客户端。当客户端接收到后,会替换原先缓存下来的结果,并在浏览器上进行显示。 但是基于时间来记录判定其实并不理想,假设用户发验证时,而你的服务器时间并未到那个时间,那么就会无法验证缓存时间了。

  • 基于标签(tag)进行条件式请求

在服务器端,每一个文件、或者是资源,每次版本修改之后都会附带一个tag(这个tag可能是一个随机生成的数,所以可以理解具有唯一性)。当用户请求资源后,会发送一个独特的请求首部(If-None-Match:tag),会将本地缓存的tag发送给服务器端,询问资源的tag是否匹配,匹配则资源未改变,响应304响应码,否则资源已改变,响应200响应码。

所以这样就不会担心基于时间记录时所产生的各种问题。

三、HTTP的缓存工作模式

3.1 基于缓存过期时间

1、当用户第一次访问资源时,缓存服务器不存在对应的缓存对象,那么此时缓存服务器会向后端服务器请求数据,后端服务器会数据响应给缓存服务器,并附带Cache-Control首部信息,表示缓存的时间。然后缓存服务器会将数据缓存于本地,然后将数据响应给客户端。

2、当客户端再次请求同一个资源时,如果缓存时间未到期,那么此时缓存服务器会直接将用户请求的资源直接响应给客户端。

3、如果当客户端请求资源时发现缓存服务器里的缓存周期已过期,那么此时缓存服务器会向后端请求资源,并将信息资源缓存于本地,而此时也更新了缓存的TTL值,然后响应给客户端。

3.2 基于条件式缓存

1、当客户端第一次请求资源时,由于缓存服务器并没有响应的缓存资源,那么此时缓存服务器会向后端服务器发起资源请求。当后端服务器收到请求后,会响应缓存服务器的请求,并附带Last-Modified:time的首部信息,缓存服务器会将资源及Last-Modified信息缓存于本地,然后一同也将这些信息响应给客户端。

2、客户端发起资源请求,如果缓存服务器有对应的资源缓存条目,但是此时客户端不会直接使用,而是发送了If-Modified-Since:time请求首部给后端服务器,来询问是否数据未修改。如数据未修改,会返回304的响应码,那么此时客户端会直接使用缓存服务器里的资源。

3、类似上面的方法,但是如果后端服务器响应的是200(数据已修改)的响应码时,那么缓存服务器会接受下这段响应信息,并将数据缓存于本地,然后再讲资源 + Last-Modified响应信息发回给客户端。

3.3 组合应用HTTP首部

根据上面的介绍,我们知道,如果基于时间来判断,可能会导致数据不准确的情况。而使用基于条件式的缓存可以弥补基于时间的不足,但是它自身还有一个缺点,那就是需要不断的去询问后端服务器的数据。这样就消耗占用了后端服务器的资源以及带宽。所以我们可以使用基于两种方式的合并来完成缓存失效判断。

1、第一次用户访问,那么类似前面介绍的方法,不同的是,此时缓存服务器会记录 Etag信息和 Cache-Control信息。

2、如果客户端请求的相同的资源,如果缓存未过期,那么此时使用的仍然是缓存服务器上的资源。

3、当缓存服务器的资源已失效,那么客户端会向后端服务器发起If-None-Match:Etag请求首部,向后端服务器确认资源是否已被修改,如果资源未修改,此时服务器会响应304(资源未修改)的响应码,那么缓存服务器会更新TTL值,并响应给客户端。

3.4 多级缓存

多级式缓存请求只是使用类似上面的方法,这里不再详细描述,下面列出相关的信息,有兴趣的小伙伴可以自己研究了解一下。

四、总结

4.1 HTTP Validation HTTP的有效性校验的方法

1、使用缓存过期时间 2、Last Modified / If-Modified-Since(基于最后一次缓存时间后询问式验证请求) 3、Etag/ If-Node-Match (基于标签式条件式请求) 这里需要注明:对于2和3点,左侧是响应首部,右侧为请求首部

4.2 常用的缓存相关的首部

ache-Control Last Modified/If-Modified-Since Etag/If-None-Match Expires (Cache-Control: max-age=, s-maxage)

本篇文章主要介绍关于缓存相关的工作原理、缓存失效的处理方式,以及关于HTTP缓存的工作模式。这篇文章在学习中总结汇总,由于本人能力有限,其中有些地方写的不足还有待完善,如果您有好的建议,欢迎您的指教。谢谢。

本文分享自微信公众号 - 马哥Linux运维(magedu-Linux),作者:温琦鹏

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2016-07-06

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Python缓存神奇库cacheout全解

    python的缓存库(cacheout) 链接: 项目: https://github.com/dgilland/cacheout 文档地址: https:/...

    小小科
  • varnish缓存实现动静分离

    一、简介 Web缓存是指一个Web资源(html,js,css,images...)存在与Web服务器和客户端(浏览器),缓存会根据进来的请求报文做出响应,后...

    小小科
  • MySQL 数据库上线后根据 status 状态优化

    马哥linux运维 | 最专业的linux培训机构 ---- 网上有很多的文章教怎么配置mysql服务器,但考虑到服务器硬件配置的不同,具体应用的差别,那些文...

    小小科
  • 构建高性能服务器 -- 缓存篇

    说到缓存,相信大家都不陌生。缓存的目的都在于避免重复的慢速计算,比如数据库访问。相对于慢速计算,缓存将会大大提高数据存取的速率,当然同时将会缩短用户每次请求处理...

    jiezhu
  • 我接手了一个“垃圾”系统,全栈优化后将性能提升了350倍

    我所在的前一家公司构建了一个大规模捐赠和支付软件系统,在一些盛大的节日里,我们一次活动中就会收到成千上万笔捐款。我在那家公司的其中一项职责就是扩展这个系统,确保...

    深度学习与Python
  • Spring Boot2(二):使用Spring Boot2集成Mybatis缓存机制

    学习SpringBoot集成Mybatis的第二章,了解到Mybatis自带的缓存机制,在部署的时候踩过了一些坑。在此记录和分享一下Mybatis的缓存作用。

    鸟不拉屎
  • 【HTTP】缓存

    随着用户访问量越来越大,缓存变得越来越重要。HTTP文件缓存可以减少冗余数据的传输;缓解网络瓶颈;降低对原始服务器的请求;以及降低距离延迟。

    奋飛
  • 后端技能清单(草稿)

    昨天也顺手整理了一下我所需要的后端技能清单。不过,由于我离非常有经验的后端开发者有点距离,希望大家可以给点意见哈。 入门 HTML / CSS 编程语言:Ja...

    Phodal
  • HTTP 缓存

    当某一个硬件要读取数据时候,会首先从缓存中查找数据,如果有,直接将数据返回,如果没有再从内存中获取数据。缓存获取数据的速度远比内存快。所以HTTP请求都采用缓存...

    Yif
  • Yii2页面缓存详解 转

    页面缓存指的是在服务器端缓存整个页面的内容。随后当同一个页面 被请求时,内容将从缓存中取出,而不是重新生成。 举例说明

    双面人

扫码关注云+社区

领取腾讯云代金券