zoukankan      html  css  js  c++  java
  • HTTP 笔记 缓存

    web缓存是可以自动保存常见文档副本的HTTP设备。使用缓存有下列优点:

    1 缓存减少了冗余的数据传输

    2 缓存缓解了网络瓶颈的问题

    3 缓存降低了对原始服务器的要求

    4 缓存降低了距离时延。每台网络路由器都会增加因特网流量的时延。光速自身也会造成显著的时延。

    可以用已有的副本为某些到达缓存的请求提供服务。这被称为缓存命中 cache hit,其他一些到达缓存的请求可能会由于没有副本可用,而被转发给原始服务器。这被称为缓存未命中 cache miss

    再验证:原始服务器的内容可能会发生变化,缓存要不时对其进行检测,看看它们保存的副本是否仍是服务吕上最新的副本。这些新鲜度检测 被称为 http 再验证。为了有效地进行再验证,HTTP定义了一些特殊的请求,不用从服务器上获取整个对象,就可以快速检测出内容是否是最新的。

    缓存对缓存的副本进行再验证时,会向原始服务器发送一个小的再验证请求。如果内容没有变化,服务器会以一个小的304 not modified进行响应。只要缓存知道副本仍然有效,就会再次将副本标识为暂时新鲜 ,并将副本提供给客户端,这被称作再验证命中 或 缓慢命中。这种方式确实要与原始服务器进行核对,所以会比单纯的缓存合中要慢,但它没有从服务器中获取对象数据,所以要比缓存未命中快一些。

    Http 提供了几个用来对已缓存对象进行再验证的工具,但最常用的是If-Modified-Since首部。将这个首部添加到GET请求中去,就可以告诉服务器,只有缓存了对象的副本之后,又对其时行了修改的情况下,才发送此对象。

      如果服务器对象未被修改,服务器会向客户发送一个小的http 304 not modified响应。

      如果服务器对象与已缓存副本不同,服务器向客户端发送一条普通的、带有完整内容的HTTP200 OK响应。

      如果服务器对象已经被删除了,服务器就回送一个404 not found响应,缓存也会将其副本删除。

    命中率:由缓存提供服务的请求所占的比例被称为缓存命中率 cache hit rate 或称为缓存命中比例,有时也被称为 文档命中率。命中率在0到1之间,但通常是用百分数来描述的,0%表示每次请求都未命中,要通过网络来获取文档,100%表示每次请求都命中了 在缓存中有一份副本。

    对现在中等规模的web缓存来说,40%的命中率是合理的。

    字节命中率:表示的是缓存提供的字节在传输的所有字节中所占的比例。通过这种度量方式,可以得知节省流量的程序。100%的字节命中率说明每个字节都来自缓存,没有流量流到因特网上去。

    文档命中率和字节命中对缓存性能的评估都是很有用的。文档命中率说明组止了多少通往外部网络的web事务。事务有一个通常都很大的固定时间成分,比如 建立一条到服务器的TCP连接,提高文档命中率对降低整体时延很有好处。

    字节命中率说明阻止了多少字节传向因特网。提高 字节命中率对节省带宽很有利。

    客户可以使用Date首部,将响应中Date首部的值与当前时间进行比较,如果响应中的日期值比较早,客户端通常就可以认为这是一条缓存的响应。也可以通过Age首部来检测缓存的响应。

    缓存的拓扑结构

    专用缓存被称为私有缓存。私有缓存是个人的缓存,包含了单个用户最常用的页面。

    共享的缓存被称为公有缓存。包含了某个用户团体的常用页面。

    web浏览器中有内建的私有缓存,大多数浏览器都会将常用文档缓存在个个电脑的磁盘和内存中,并且允许用户去配置缓存的大小和各种设置。

    公有缓存是特殊的共享代理服务器,被称为缓存代理服务器,或者 更常见地被称为代理缓存。代理缓存会从本地缓存中提供文档,或者代表用户与服务器进行联系。公有缓存会接受来自多个用户的访问,所以通过它可以更好地减少冗余流量。

    可以通过指定手工代理、或者 通过代理自动配置文件,将浏览器配置为使用代理缓存。还可以通过使用拦截代理 在不配置浏览器的情况下,强制http请求经过缓存传输。

     如果没有在一次缓存中命中,较大 父缓存可能能够处理它们的请求,在缓存层次结构很深的情况下,请求可能要穿过很长一溜缓存,但每个拦截代理都会添加一些性能损耗,当代理链路变得很长的时候,这种性能损耗会变得非常明显。

    网状缓存中为内容路由设计的缓存要完成下列所有功能:

    1 根据URL在父缓存或原始服务器之间进行动态选择。

    2 根据URL动态地选择一个特定的父缓存。

    3 前往父缓存之前,在本地缓存中搜索已缓存的副本。

    4 允许其他缓存对其缓存的部分内容进行访问,但不允许因特网流量通过它们的缓存。

    缓存的处理步骤:

    1 接收--缓存从网络中读取抵达的请求报文:缓存检测到一条网络连接上的活动,读取输入数据,高性能的缓存会同时从多条输入连接上读取数据,在整条报文抵达之前开始对事务进行处理。

    2 解析--缓存对报文进行解析,提取出URL和各种首部。缓存将请求报文解析为片断,将首部的各个部分放入易于操作的数据结构中。

    3 查询--缓存查看是否有本地副本可用,如果没有,就获取一份副本并将其保存在本地。

      本地副本可能存储在内存、本地磁盘,甚至附近的另一台计算机中。专业级 缓存会使用快速算法来确定本地缓存中是否有某个对象。如果本地没有这 个文档,它可以根据情形和配置,到原始服务器或父代理中去取,或者返回一条错误信息。

      已缓存对象中包含了服务器响应主体和原始服务器响应首部,这样就会在缓存命中时返回正确的服务器首部。已缓存对象中还包含了一些元数以,用来记录对象在缓存中停留了多长时间,以及它被用过多少次 等。

    4 新鲜度检测--缓存查看已缓存副本是否足够新鲜,如果不是,就询问服务器是否有任何更新。

      HTTP通过缓存将服务器文档的副本保留一段时间。在这段时间里,都认为文档是新鲜的,缓存可以在不联系服务器的情况下,直接提供该文档。但一旦已缓存副本停留的时间太长,超过了文档的新鲜度限值,就认为对象过时了,在提供该文档之前,缓存要再次与服务器进行确认,以查看文档是否发生了变化。客户端发送给缓存的所有请求首部自身都可以强制缓存进行再验证,或者完全避免验证。

    5 创建响应--缓存会用新的首部和已缓存的主体来构建一条响应报文。缓存将已缓存的服务器响应首部作为响应首部的起点。然后缓存对这些基础首部进行了修改和扩充。

    缓存会向其中插入新鲜度信息,cache-Control、age/expires首部,而且通常会包含一个via首部来说明请求是由一个代理缓存提供的。

    缓存不应该调整Date首部。date首部表示的是原始服务器最初产生这个对象的日期

    6 发送--缓存通过网络将响应发回给客户端。

    7 日志--缓存可选地创建一个日志文件条目来描述这个事务。

    文档过期:

    通过特殊 http Cache-Control首部和Expires首部,HTTP 让原始服务器向每个文档附加了一个 过期日期。这些首部说明了在多长时间内可以将这些内容视为新鲜的。

    在缓存文档过期之前,缓存可以以任意频率使用这些副本,而无需与服务器联系,除非客户端请求中包含有阻止提供已缓存或未验证资源的首部。但一旦已缓存文档过期,缓存就必须与服务器进行核对,询问文档是否被修改过,如果被修改过,就要获取一份新鲜的副本。

    过期日期和使用期:

    服务器用HTTP/1.0 的Expires首部或http/1.1的Cache-Control:max-age响应首部来指这过期日期,同时还会带有响应主体。cache-control首部使用的是相对时间而不是绝对日期,绝对日期依赖于计算机时钟的正确设置。

    服务器再验证:

    已缓存文档过期并不意味着它和原始服务上目前处于活跃状态的文档有实际的区别,只是意味着到了要进行核对的时间了。这种情况被称为 服务器再验证,说明缓存需要询问原始服务器文档是否发生了变化。

    如果再验证显示内容发生了变化,缓存会获取一份新文档副本,并将其存储在旧文档的位置上,然后将文档发送给客户端。

    如果再验证显示 内容没有发生变化,缓存只需要获取新的首部,包括一个新的过期日期,并对缓存中折首部进行更新就行了。

    Http协议要求行为正确的缓存返回下列内容之一:

    1 足够新鲜的已缓存副本

    2 与服务器进行过再验证,确认其仍然新鲜的已缓存副本

    3 如果需要与之进行再验证的原始服务器出故障了,就返回一条错误报文。

    4 附有警告信息说明内容可能不正确的已缓存副本。

    用条件方法进行再验证:

    http的条件方法可以高效地实现再验证。Http允许缓存原妈服务器发送一个 条件GET,请求服务器只有在文档与缓存中现有的副本不同时,才回送对象主体。

    IF-Modified-Since:<date> 如果从指定日期之后文档被修改过了,就执行请求的方法。可以与Last-Modified服务器响应首部配合使用,只有在内容被修改后与已缓存版本有所不同 时候才去获取内容。

    If-None-Match:<tags>服务器可以为文档提供特殊的标签,而不是将其与最近修改日期相匹配,这些标签就像序列号一样。如果已缓存标签与服务器文档中的标签有所不同,If-None-Match首部就会执行所请求的方法。

    If-Modified-Since:Date再验证请求通常被称为IMS请求:

    如果自指定日期后,文档被修改了,If-Modified-Since条件就为真,通常GET就会成功执行。携带新首部的新文档会被返回给缓存,还包含了一个新的过期日期.

    如果自指定日期后,文档没被修改过,条件就为假,会向客户端返回一个小的304 Not Modified响应报文,为了提高有效性,不会返回文档的文体。这些首部是放在响应中返回的,但只会返回那些需要在源端更新的首部。

    原始服务器会将最后的修改日期附加到所提供的文档上去。当缓存要对已缓存文档进行再验证时,就会包含一个If-Modified-Since首部,其中携带有最后修改已缓存副本的日期 If-Modified-Since:<cached last-modified date>

    如果在此期间内容被修改了,最后的修改日期就会有所不同,原始服务器就会回送新的文档。

    有些web服务器并没有将if-modified-since作为真正的日期来进行比对。相反,它们在IMS日期和最后修改日期之间进行了字符串匹配。这样得到的语义就是:如果最后的修改不是在这个确定的日期时行的

    If-None-Match:实体标签再验证

    1 有些文档可能会被周期性地重写,但实际包含的数据常常是一样 。尽管内容没有变化,但修改日期会发生变化。

    2 有些文档可能被修改了,但所做的修改并不重要,不需要让世界范围内的缓存都重装数据。

    3 有些服务器无法准确地判定期页面的最后修改日期

    4 有些服务器提供的文档会在来亚秒间隙发生变化

     实体标签是附加到文档上的任意标签 引用字符串。它们可能包含了文档的序列号或版本号,或者是文档内容的校验和及其他指纹信息。

    当发布者对文档进行修改时,可以修改文档的实体标签来说明这个新的版本。

    如果服务器上的实体标签已经发生了变化,服务器会在一个200 Ok响应中返回新的内容以及相应的新Etag

    如果服务器回送了一个实体标签,http/1.1客户端就必须使用实体标签验证器。如果服务器只回送了一个Last-Modified值,客户端就可以使用if-modified-since验证。如果实体标签和最后修改日期都提供了,客户端就应该使用这两种验证方案。

    控制缓存的能力:

    服务器可以通过http定义的几种方式来指定在文档过期之前可以将期缓存多长时间。按照优先级递减的顺序,服务器可以:

    1 附加一个Cache-Control:no-store首部到响应中去

    2 附加一个Cache-Control:no-cache首部到响应中去

    3 附加一个Cache-Control:must-revalidate首部到响应中去

    4 附加一个Cache-Control:max-age首部到响应中去

    5 附加一个Expires日期首部到响应中去

    6 不附加过期信息,让缓存确定自己的过期日期。

    标识为not-store的响应会禁止缓存对响应进行复制。缓存通常会像非缓存代理服务器一样,向客户端转发一条no-store响应,然后删除对象。

    标识为no-cache的响应实际上是可以存储在本地缓存区中的。只是在与原始服务器进行新鲜度再验证之前,缓存不能将其提供给客户端使用。这个首部使用do-not-serve-from-cache-without-revalidation这个名字会更恰当一些。

    http/1.1中提供Pragma:no-cahce首部与http/1.0+ 兼容。

    max-age响应首部:

    Cache-Control:max-age首部表示的是从服务器文档传来之时起,可以认为此文档处于新鲜状态的秒数。还有一个s-maxage 与max-age 行为类似 仅适用于共享缓存。

    Cache-Control:max-ae=3600 Cache-Control:s-maxage=3600

    将最大使用期设置为零,从而在每次访问的时候都进行刷新:Cache-Control:max-age=0

    Expires响应首部:

    不推荐使用Expires首部,它指定的是实际过期日期而不是秒数。

    Cache-Control:must-revalidate 响应首部告诉缓存,在事先没有跟原始服务器进行再验证的情况下,不能提供这个对象的陈旧副本。如果在缓存进行新鲜度检查时,原始服务器不可用,缓存就必须返回一条504 gateway timeout错误

    LM-Factor算法是一种很用的试探性过期算法,将最后修改日期作为依据,来估计文档有多么易变。逻辑:

    如果已缓存文档最后一次修改发生在很久以前,它可能会是一份稳定的文档,不太会突然发生变化,因此将其继续保存在缓存中会比较安全。

    如果已缓存文档最近被修改过,就说明它很可能会频繁地发生变化,因此在与服务器进行再验证之前,只应该将其缓存很短一段时间。

    实际的LM-Factor算法会计算缓存与服务器对话的时间跟服务器声明文档最后被修改的时间之间的差值,取这个间隔时间的一部分。将其作为缓存中的新鲜度持续时间。

    通常人们会为试探性新鲜周期设置上限,这样它们就不会变得太大了。尽管比较保守的站点会将这个值设置为一天,但通常站点会将其设置为一周

    缓存通常会为没有任何新鲜周期线索的文档分配一个默认的新鲜周期。比较保守的缓存会将这种试探性新鲜生成期设置为0,强制缓存在每次将其提供给客户端之前,都去验证一下这些数据仍然是新鲜的。

    客户端的新鲜度限制:

    web浏览器都有Refresh刷新、Reload 重载按钮,可以强制对浏览器或代理缓存中可能过期的内容进行刷新。

  • 相关阅读:
    如何成为合格的技术面试官?
    互联网上有多少个网站?
    前端领域不需要架构师?
    WebAssembly 简介
    git常用命令
    剑指offer-基本思想学习(未包括代码)
    OS知识点总结
    对软件工程的一点认识
    项目实现过程的每个阶段
    编译原理课程设计总结
  • 原文地址:https://www.cnblogs.com/caojuansh/p/13051098.html
Copyright © 2011-2022 走看看