Web缓存解决方案
缓存是构建于HTTP统一接口之上的最有用功能之一。可以利用缓存减少终端用户感知到的延时,增加可靠性,减少带宽使用和成本,降低服务器负载。缓存无处不在,可以在服务器网络里,内容分发网络(Content delivery network,简称CDN)或是客户端网络里(通常被称为转发代理Forward Proxy)。
- 如何设置过期缓存头
当缓存可以在不访问源服务器时做出尽可能多的响应时,它是最高效的。设计过期缓存(Expiration Caching)就是为了降低源服务器收到的请求数量,同时减少应用程序使用的带宽。过期缓存基于Cache-Control和Expires这两个头,它们指导客户端和缓存在一段指定时间内保存从服务器返回的表述副本。在这个时间窗口以内,甚至超出该时间窗口,缓存可以对后续请求做出响应,无需访问源服务器。下面是Cache-Control指令列表及其适用性:
public 默认指令。当请求是经过身份验证的,但您仍希望共享缓存提供缓存响应时,也可以使用该指令。
private当响应专属于某个客户端或用户时,使用该指令。任意客户端缓存(如浏览器缓存或转发代理)都可以缓存表述,但诸如服务器缓存或网络之类的共享缓存则不能进行缓存。在基于客户端或用户身份验证来提供表述的时候添加该指令。
no-cache和no-store 通过这些指令可以避免缓存存储或提供已经缓存的响应。如非必要,一般不使用这些指令。
max-age该指令的值即为新鲜寿命,单位为秒。
s-maxage这个指令与max-age类似,但只对共享缓存有意义。在源服务器同时设置了max-age和s-maxage时,缓存会使用s-maxage头。实际上,单独设置max-age指令就足够了。
must-revalidate要求缓存在提供陈旧的表述前先检查源服务器。
proxy-revalidate只应用于共享缓存。最佳过期缓存的关键是为资源表述计算一个合理的新鲜寿命值。如果有历史信息,例如表述的更新日志,可以参考它们来建立基线寿命。如果没有此类数据,可以先从一个合理的推测值出发,在获取更多信息后对其做出调整。通常这些信息源自于您发现某个客户端看不到最近更新的表述。
类似Squid这样的缓存还支持两个Cache-Control头的扩展指令——state-if-error和state-while-revalidate。服务器可以用stale-if-error来告诉缓存,它们可以在指定时间间隔内继续提供陈旧的响应。 - 何时设置过期缓存头
HTTP规定了什么是能缓存的,什么是不能缓存的,缓存也可能只实现了部分HTTP缓存协议。
为所有带成功响应码的GET和HEAD请求的响应设置过期缓存头。虽然POST是可缓存的,但缓存会把该方法视为不可缓存的。其他方法无需设置过期缓存头。
除了带200(OK)响应码的成功响应,还可以考虑缓存待3**和4**响应码的HTTP头,这能减少由客户端错误带来的流量。这种做法被称为消极缓存(negative caching)。
300(multiple choices)带这个状态码的表述不太可能经常发送变化,缓存此类应答可以降低服务器负载。
301(Moved Permanently)当资源永久移动时,那些将URI存储在数据库中的客户端可能不会修改这些URI。在这种情况下,缓存可以不用访问源服务器,直接提供重定向响应。
400(Bad Request)当服务器返回该状态码时,客户端按理说不该重复请求,但出于软件错误或恶意攻击等原因,有些客户端会重复发起请求。
403(Forbidden)如果服务器永久拒绝服务该资源,请为其添加缓存。
404(Not Found)该资源不存在,而且没必要让服务器仅为失败生成表述。
405(Method Not Allowed)客户端可能会因为软件错误而重复发送此类请求。
410(Gone)资源不再存在了,所以缓存应该尽可能久地提供错误响应。 - 何时以及如何在客户端使用过期缓存头
除非你是在构建一个封装在压缩包内的、需要用户安装并运行的客户端应用程序,否则应该避免在客户端应用程序中实现对过去缓存的支持。可以在客户端网络中部署一个转发代理缓存,避免在客户端代码中实现自己的缓存层。
通常情况下,客户端应独立于过期缓存之外。理论上是有可能构建支持HTTP缓存协议的客户端应用程序的。举例来说,常见的浏览器实现了过期缓存,并将表述存储在内存或文件系统之中。实际上,在客户端应用程序中构建并维护一个缓存是项很麻烦的工作。它涉及正确地实现no-store,no-cache和must-revalidate这样的过期指令,还要遵循Vary头的内容。在同一个运行时内放入缓存还会造成客户端应用程序代码与缓存代码争夺内存与CPU资源,这会让客户端的调优变得更加困难。
相较之下,在客户端和服务器之间放置一个转发代理缓存更容易一些。不涉及任何开发活动,你就可以坐享经过精心测试的、健壮的缓存基础设施所带来的好处,无须自己构建。这么做还为日后扩展留下了空间,你可以架设一个所有客户端共享的转发代理服务器集群。
如果客户端和服务器在同一个网络里,不一定需要转发代理。服务器上可以部署一个被所有客户端共享的缓存。但如果客户端是在和一个其他网络中的第三方Web服务交互,那么使用转发代理可以帮助减少客户端与服务器之间往返请求次数。 - 如何支持复合资源的缓存
基于那些对新旧程度有强烈要求的数据来制定缓存决策,根据它们的变更频率来设置过期头。
相比其它类型资源,复合资源实现缓存更为复杂,此类资源包含与其他资源重叠的数据,它们可能会有不同的过期时间。
复合资源是便利性与缓存效率之间权衡的一个好例子。对客户端而言,复合资源用起来很方便,但服务器要提供最新的资源却代价很大。
一个解决办法是:将复合资源打散成三个资源,但这就强迫客户端发起多次请求来获取数据。换言之,服务器需要考虑利害关系并做出权衡。当资源的表述粒度较粗时,就会发生这种情况,有可能会以独立资源的方式来提供表述中所含的数据。 - 如何保持新鲜且温暖的缓存
缓存支持的众多挑战之一就是保持缓存的“新鲜”(最新状态)和“温暖”(非空),就算客户端没有发起请求时也是如此。以一个照片分享服务为例,在用户上传照片后,所有针对这些照片的缓存都是空的,因此服务器不得不生成照片的表述。类似的,当引入一个新的缓存时,它是空的,随着客户端开始发起请求后,它才会慢慢有内容。当缓存处于新鲜状态时,其中包含最新的表述。一个“温暖”的缓存能避免冷启动问题。但是,预先保持缓存的新鲜与温暖不在HTTP范畴之内。
尽可能地让过期时间与更新频率保持同步。当这点很难做到时,实现一些后台进程来监控数据库变更,定时执行无条件GET请求来刷新缓存。在定时调度这些请求时,一定要考虑到数据库复制的延迟。
如果正在使用Squid,可以使用HTTP缓存频道扩展(HTTP cache channel extension)向缓存传播资源更新。
在HTTP中,当客户端提交PUT,POST或DELETE请求时,要求缓存作废表述。此后,客户端再对同一资源发起GET或HEAD请求时,缓存就能从源服务器获得一个新的表述。尽管这种做法不太高效(因为缓存无法保持非空状态),但它却保证了客户端能获得最新的表述。
现实中,你的网络里可能有多个应用程序会读写相同的数据存储,只要其中任意应用程序的写操作绕过HTTP缓存和服务器,那么就会导致缓存的表述变旧。
考虑以下场景:
服务器上可能会有每晚执行的定时任务,更新摘要数据表以反映日间的工作。这个更新可能直接发生在数据库层面上,不会有任何HTTP请求。但你可能缓存了这个资源,一旦定时任务执行了,存储在缓存中的应答就旧了。
广泛分布的数据存储在一天里可能会周期性地进行复制。数据的改变不会反映在全部的缓存里。
大型应用程序可能会有一个或多个客户端或服务是使用自定义协议来更新数据的。只要使用这些服务就可以在不通过HTTP的情况下改变数据库,此时缓存并不知道资源发生了变化。
Web缓存解决方案的更多相关文章
- (转)unity web 缓存解决方案
unity web 缓存解决方案 官方发布 web版限制五十M缓存,根据自己的经验绕了过去,解决了缓存的问题.带工程,带源代码.由于本人的水平也有限,是用JS来解决的,如果你还是没有头绪,可以购买来试 ...
- Web 技术人员需知的 Web 缓存知识(转)
最近的译文距今已有4年之久,原文有一定的更新.今天踩着前辈们的肩膀,再次把这篇文章翻译整理下.一来让自己对web缓存的理解更深刻些,二来让大家注意力稍稍转移下,不要整天HTML5, 面试题啊叨啊叨的~ ...
- Web缓存的作用与类型
前言 Web缓存是指一个Web资源(如html页面,图片,js,数据等)存在于Web服务器和客户端(浏览器)之间的副本.缓存会根据进来的请求保存输出内容的副本:当下一个请求来到的时候,如果是相同的UR ...
- Web 技术人员需知的Web 缓存知识
最近的译文距今已有4年之久,原文有一定的更新.今天踩着前辈们的肩膀,再次把这篇文章翻译整理下.一来让自己对web缓存的理解更深刻些,二来让大家注意力稍稍转移下,不要整天HTML5, 面试题啊叨啊叨的~ ...
- Web开发人员需知的Web缓存知识
最近的译文距今已有4年之久,原文有一定的更新.今天踩着前辈们的肩膀,再次把这篇文章翻译整理下.一来让自己对web缓存的理解更深刻些,二来让大家注意力稍稍转移下,不要整天HTML5, 面试题啊叨啊叨的~ ...
- Web缓存(Varnish方案)
Web缓存(Varnish方案) 转载 http://www.s135.com/post/313/ arnish是一款高性能的开源HTTP加速器,挪威最大的在线报纸 Verdens Gang (htt ...
- Web缓存相关知识整理
一.前言 工作上遇到一个这样的需求,一个H5页面在APP端,如果勾选已读状态,则下次打开该链接,会跳过此页面.用到了HTML5 的本地存储 API 中的 localStorage作为解决方案,回顾了 ...
- 面试的妹纸问我:web缓存设置不是后台的事情吗?
背景介绍 团队最近在招前端开发,早上收到一封简历,是个妹纸,从技能点来看还算符合要求,于是约了下午3点过来面试. 整个面试过程持续了大约40分钟,问的题目也比较常规,其中一道题就是"常见的性 ...
- web缓存策略之HTTP缓存大全
一. web缓存总分类 数据库数据缓存 Web应用,特别是SNS类型的应用,往往关系比较复杂,数据库表繁多,如果频繁进行数据库查询,很容易导致数据库不堪重荷.为了提供查询的性能,会将查询后的数据放到内 ...
随机推荐
- Errors occurred during the build. Errors running builder 'JavaScript Validator' on
eclipse又一次编译时候就会报错Errors occurred during the build. Errors running builder 'JavaScript Validator' on ...
- style中position的属性值具体解释
Position的英文原意是指位置.职位.状态.也有安置的意思.在CSS布局中,Position发挥着非常关键的数据,非常多容器的定位是用Position来完毕. Position属性有四个可选值,它 ...
- Mysql C语言API编程入门讲解
原文:Mysql C语言API编程入门讲解 软件开发中我们经常要访问数据库,存取数据,之前已经有网友提出让鸡啄米讲讲数据库编程的知识,本文就详细讲解如何使用Mysql的C语言API进行数据库编程. ...
- Android设备连接Unity Profiler性能分析器
Unity提供两种方式让Developer的Android设备连接Profiler进行性能分析: 1.通过wifi,Android设备和计算机处于同一个Wlan中. 2.通过USB ADB 普通情况我 ...
- 利用HttpClient抓取话费详单等信息
由于项目需要,需要获取授权用户的在运营商(中国移动.中国联通.中国电信)那里的个人信息.话费详单.月汇总账单信息(需要指出的是电信用户的个人信息无法从网上营业厅获取).抓取用户信息肯定是要模仿用户登录 ...
- Spring IOC之基于注解的容器配置
Spring配置中注解比XML更好吗?基于注解的配置的介绍提出的问题是否这种途径比XML更好.简单来说就是视情况而定. 长一点的答案是每一种方法都有自己的长处也不足,而且这个通常取决于开发者决定哪一种 ...
- 确保Zend Studio最佳性能的10点建议
作为一个PHP开发人员,你需要知道使用Zend Studio时,什么应该做,什么要避免.就像Roy Ganor说的那样“你必须掌握的你IDE”.从IDE角度来看,建立PHP项目时,了解Zend Stu ...
- MSSQL2008数据库备份还原和数据恢复
原文:MSSQL2008数据库备份还原和数据恢复 序言 一直想写一篇关于数据库备份与恢复的文章,但基于能力的有限对数据库认知的有限怕不足以准确的表达,最后思考很久还是决定把自己的一些理解写出来供大 ...
- javascript立即调用的函数表达式N种写法(第二篇)
原文:javascript立即调用的函数表达式N种写法(第二篇) 上一篇博客我谈到将函数声明转换为函数表达式最常见的一种写法是:通过括号()将匿名函数声明转换为函数表达式即(function(){}) ...
- Mysql高级之事务
原文:Mysql高级之事务 通俗的说事务: 指一组操作,要么都成功执行,要么都不执行.---->原子性 在所有的操作没有执行完毕之前,其他会话不能够看到中间改变的过程-->隔离性 事务发生 ...