缓存版本号
Ⅰ 如何自动给CSS、JS添加版本号防止客户端缓存。
怎么说呢,个人有个笨点的办法,就是在代码中加上JS版本号的全局变量,应用JS时利用后台代码添加。
这样更改过JS时,将JS的文件名后边带上个自定义的版本号,再将JS版本号的变量修改一下就好了。其他程序由于是动态的读取JS文件名,所以不用再修改,也不用怕漏改。
Ⅱ 认识HTTP----缓存篇
本文内容大多参考 《图解HTTP》一书
所以讲缓存为什么要先扯代理服务器?别急,让我们看一下一个请求的简单示意图。
我们看到客户端(用户)发送了一个请求并不是直接发给源服务器的而是经过了代理服务器,然后经由代理服务器再发送给源服务器,响应也同样遵循这个顺序。
那么代理服务器在这中间担任了什么角色?
缓存是指代理服务器或客户端本地磁盘内保存的资源副本。利用缓存可减少对源服务器的访问,因此也就节省了通信流量和通信时间。
缓存服务器是代理服务器的一种,并归类在缓存代理类型中。换句话说,当代理转发从服务器返回的响应时,代理服务器将会保存一份资源的副本。
缓存服务器的优势在于利用缓存可避免多次从源服务器转发资源。因此客户端可就近从缓存服务器上获取资源,而源服务器也不必多次处理相同的请求了。
即便缓存服务器和客户端内有缓存,也不能每次都给我返回缓存吧,如果是这样,源服务器更新了我也不知道,因为我每次都是看缓存的资源。
为了解决这个问题,针对缓存设计了时效性的概念:
即使存在缓存,也会因为客户端的要求、缓存的有效期等因素,向源服务器确认资源的有效性。若判断缓存失效,缓存服务器将会再次从源服务器上获取“新”资源。
缓存不仅可以存在于缓存服务器内,还可以存在客户端浏览器中。以Internet Explorer 程序为例,把客户端缓存称为临时网络文件(Temporary Internet File)。
浏览器缓存如果有效,就不必再向服务器请求相同的资源了,可以直接从本地磁盘内读取。
另外,和缓存服务器相同的一点是,当判定缓存过期后,会向源服务器确认资源的有效性。若判断浏览器缓存失效,浏览器会再次请求新资源。
Pragma 是HTTP/1.1 之前版本的历史遗留字段,仅作为与HTTP/1.0的向后兼容而定义。
规范定义的形式唯一,如下所示。
Pragma: no-cache
该首部字段属于通用首部字段,但只用在客户端发送的请求中。客户端会要求所有的中间服务器不返回缓存的资源。
通过指定首部字段Cache-Control 的指令,就能操作缓存的工作机制。
可用的指令按请求和响应分类如下所示:
public指令
Cache-Control: public
当指定使用public 指令时,则明确表明其他用户也可利用缓存。
private指令
no-store指令
Cache-Control: no-store
当使用no-store 指令时,暗示请求(和对应的响应)或响应中包含机密信息。
因此,该指令规定缓存不能在本地存储请求或响应的任一部分。
ps:从字面意思上很容易把no-cache误解成为不缓存,但事实上no-cache代表不缓存过期的资源,缓存会向源服务器进行有效期确认后处理资源,也许称为do-not-serve-from-cache-without-revalidation更合适。no-store 才是真正地不进行缓存,请读者注意区别理解。
s-maxage指令
Cache-Control: s-maxage=604800 //(单位:秒)
s-maxage 指令的功能和max-age 指令的功能相同, 它们的不同点是s-maxage 指令只适用于供多位用户使用的公共缓存服务器(这里指代理服务器)。也就是说,对于向同一用户重复返回响应的服务器来说,这个指令没有任何作用。
另外,当使用s-maxage 指令后,则直接忽略对Expires 首部字段及max-age 指令的处理。
max-age指令
cache-extension token
Cache-Control: private, community="UCI"
通过 cache-extension 标记(token),可以扩展Cache-Control 首部字段内的指令。
如上例,Cache-Control 首部字段本身没有community 这个指令。借助extension tokens 实现了该指令的添加。如果缓存服务器不能理community 这个新指令,就会直接忽略。因此,extension tokens 仅对能理解它的缓存服务器来说是有意义的。
If-Unmodified-Since: Thu, 03 Jul 2012 00:00:00 GMT
首部字段If-Unmodified-Since 和首部字段If-Modified-Since 的作用相反。它的作用的是告知服务器,指定的请求资源只有在字段值内指定的日期时间之后,未发生更新的情况下,才能处理请求。如果在指定日期时间后发生了更新,则以状态码412 Precondition Failed 作为响应返回。
ps:Last-Modified 存在一定问题,如果在服务器上,一个资源被修改了,但其实际内容根本没发生改变,会因为Last-Modified时间匹配不上而返回了整个实体给客户端(即使客户端缓存里有个一模一样的资源)。
首部字段If-None-Match 属于附带条件之一。它和首部字段If-Match 作用相反。用于指定If-None-Match 字段值的实体标记(ETag)值与请求资源的ETag 不一致时,它就告知服务器处理该请求。
在GET 或HEAD 方法中使用首部字段If-None-Match 可获取最新的资源。因此,这与使用首部字段If-Modified-Since 时有些类似。
不与服务器确认,而是直接使用浏览器缓存的内容。其中响应内容和之前的响应内容一模一样,例如其中的Date时间是上一次响应的时间。
F5的作用和直接在URI输入栏中输入然后回车是不一样的,F5会让浏览器无论如何都发一个HTTP Request给Server,即使先前的响应中有Expires头部。
Ctrl+F5要的是彻底的从Server拿一份新的资源过来,所以不光要发送HTTP request给Server,而且这个请求里面连If-Modified-Since/If-None-Match都没有,这样就逼着Server不能返回304,而是把整个资源原原本本地返回一份,这样,Ctrl+F5引发的传输时间变长了,自然网页Refresh的也慢一些。
Cache-Control 是 HTTP1.1 才有的,不适用于 HTTP1.0,而 Expires 既适用于 HTTP1.0,也适用于 HTTP1.1,所以说在大多数情况下同时发送这两个头会是一个更好的选择,当客户端两种头都能解析的时候,会优先使用 Cache-Control。
二者都是通过某个标识值来请求资源, 如果服务器端的资源没有变化,则自动返回 HTTP 304 (Not Changed)状态码,内容为空,这样就节省了传输数据量。当资源变化后则返回新资源。从而保证不向客户端重复发出资源,也保证当服务器有变化时,客户端能够得到最新的资源。
其中Last-Modified使用文件最后修改作为文件标识值,它无法处理文件一秒内多次修改的情况,而且只要文件修改了哪怕文件实质内容没有修改,也会重新返回资源内容;ETag作为“被请求变量的实体值”,其完全可以解决Last-Modified头部的问题,但是其计算过程需要耗费服务器资源。
Expires和Cache-Control都有一个问题就是服务端的修改,如果还在缓存时效里,那么客户端是不会去请求服务端资源的(非刷新),这就存在一个资源版本不符的问题,而强制刷新一定会发起HTTP请求并返回资源内容,无论该内容在这段时间内是否修改过;而Last-Modified和Etag每次请求资源都会发起请求,哪怕是很久都不会有修改的资源,都至少有一次请求响应的消耗。
对于所有可缓存资源,指定一个Expires或Cache-Control max-age以及一个Last-Modified或ETag至关重要。同时使用前者和后者可以很好的相互适应。
前者不需要每次都发起一次请求来校验资源时效性,后者保证当资源未出现修改的时候不需要重新发送该资源。而在用户的不同刷新页面行为中,二者的结合也能很好的利用HTTP缓存控制特性,无论是在地址栏输入URI然后输入回车进行访问,还是点击刷新按钮,浏览器都能充分利用缓存内容,避免进行不必要的请求与数据传输。
做法很简单,就是把可能会更新的资源以版本形式发布,常用的方法是在文件名或参数带上一串md5或时间标记符:
可以看到上面的例子中有不同的做法,有的在URI后面加上了md5参数,有的将md5值作为文件名的一部分,有的将资源放在特性版本的目录中。
那么在文件没有变动的时候,浏览器不用发起请求直接可以使用缓存文件;而在文件有变化的时候,由于文件版本号的变更,导致文件名变化,请求的url变了,自然文件就更新了。这样能确保客户端能及时从服务器收取到新修改的文件。通过这样的处理,增长了静态资源,特别是图片资源的缓存时间,避免该资源很快过期,客户端频繁向服务端发起资源请求,服务器再返回304响应的情况(有Last-Modified/Etag)。
Ⅲ sass构建CSS时,如何给文件随机加版本号,以防止老文件缓存
1、线上的时候:在模板文件里对css跟js的引入路径后面追加一个类似于常量来做版本号
<link rel="stylesheet" href="style.css?version=20150828" />
2、线下测试的时候:对css跟js的引入路径后面追加随机数,时时刻刻更新,避免缓存影响了调试。
3、线下测试后:升级常量的版本号,把代码更新上去,这样用户的浏览器刷新就用到了新的样式,而又用到了缓存。
Ⅳ 【浏览器缓存问题】HTML静态文件中,css和js可以添加版本号来刷新缓存,但是只是修改的文字了呢
给网址后面添加一个随机数(或者是任意的字符串)即可,比如原来的网址是这样的:
http....../.../1.htm
改为
http....../.../1.htm?1234
即可(注意问号不能省)。
浏览器是根据网址来缓存的,所以只要给网址接个尾巴,浏览器就会认为是新网址,就会从网上重新下载数据了。当然,如果下次再次改变了网页内容,这个尾巴就要再次修改。
给css和js添加所谓版本号其实也是同一个原理。这个版本号其实就是给css和js的网址接个尾巴而已。
这个也同样适用网页里面的图片、音乐等资源,事实上只要是http协议的元素都可以利用这个办法来避开缓存实时刷新。
Ⅳ Tair 分布式缓存简介
Tair是由阿里巴巴自主研发的高性能高可用的分布式Key/Value结构数据存储系统,在阿里内部有着大规模的应用。
作为一个分布式系统,Tair由一个中心控制节点(config server)和一系列的服务节点(data server)组成,
Tair主要有下面三种存储引擎:
根据CAP理论,在分布式存储系统中,最多只能实现一致性、可靠性和分区容错性三点中的两点。而由于网络硬件肯定会出现延迟丢包等问题,所以分区容错性是我们必须需要实现的。所以我们只能在一致性和可用性之间进行权衡。
Tair 选择了一致性,同时采用复制技术来提高可靠性,并且为了提高效率做了一些优化。事实上在没有错误发生的时候,tair 提供的是一种强一致性,但是在有data server发生故障的时候,客户有可能在一定时间窗口内读不到最新的数据,甚至发生最新数据丢失的情况。
Tair中的每个数据都包含版本号,版本号在每次更新后都会递增。这个特性可以帮助防止数据的并发更新导致的问题。version 机制是乐观锁常用的实现方式。
tair 的存储引擎可以是 MDB、LDB 或 RDB。它们使用缓存、内存或 SSD 硬盘(LDB) 来提升性能。
configserver 不是传统的中心节点,挂了对集群的服务无影响
Tair 使用一致性哈希作为负载均衡策略。
当有某台data server故障不可用的时候, config server会发现这个情况, config server负责重新计算一张新的桶在data server上的分布表, 将原来由故障机器服务的桶的访问重新指派到其它的data server中。这个时候, 可能会发生数据的迁移。比如原来由data server A负责的桶,在新表中需要由 B负责。而B上并没有该桶的数据, 那么就将数据迁移到B上来。同时config server会发现哪些桶的备份数目减少了, 然后根据负载情况在负载较低的data server上增加这些桶的备份。当系统增加data server的时候, config server根据负载,协调data server将他们控制的部分桶迁移到新的data server上。迁移完成后调整路由。当然系统中可能出现减少了某些data server 同时增加另外的一些data server。处理原理同上。 每次路由的变更,config server都会将新的配置信息推给data server。在客户端访问data server的时候, 会发送客户端缓存的路由表的版本号。如果data server发现客户端的版本号过旧,则会通知客户端去config server取一次新的路由表。如果客户端访问某台data server 发生了不可达的情况(该 data server可能宕机了),客户端会主动去config server取新的路由表。
当迁移发生的时候, 我们举个例子, 假设data server A 要把桶 3,4,5 迁移给data server B。因为迁移完成前,客户端的路由表没有变化,客户端对 3, 4, 5 的访问请求都会路由到A。现在假设 3还没迁移, 4 正在迁移中, 5已经迁移完成。那么如果是对3的访问, 则没什么特别, 跟以前一样。如果是对5的访问, 则A会把该请求转发给B,并且将B的返回结果返回给客户,如果是对4的访问,在A处理,同时如果是对4的修改操作会记录修改log。当桶4迁移完成的时候,还要把log发送到B,在B上应用这些log。最终A B上对于桶4来说, 数据完全一致才是真正的迁移完成。当然如果是因为某data server宕机而引发的迁移, 客户端会收到一张中间临时状态的分配表。这张表中,把宕机的data server所负责的桶临时指派给有其备份data server来处理。 这个时候服务是可用的,但是负载可能不均衡。当迁移完成之后,才能重新达到一个新的负载均衡的状态。
https://yq.aliyun.com/articles/52059
https://www.cnblogs.com/jiangxiulian/p/8027739.html