web缓存
- 格式:docx
- 大小:20.50 KB
- 文档页数:1
组件System.Web.Optimization原理及缓存问题详解1】开篇介绍这篇⽂章将简单的分析⼀下有关静态⽂件捆绑的组件System.Web.Optimization的运⾏原理及基本的缓存问题:在我们的项⽬⾥⾯充斥着很多静态⽂件,为了追求模块化、插件化很多静态⽂件都被设计成模块的⽅式或者被分解,在需要的时候在通过组合的⽅式在UI层上使⽤;这就带来⼀个问题,⽂件多了会影响浏览器加载页⾯的速度,⽽且由于浏览器的并发限制,对于并⾏的请求不是⽆限制的,所以捆绑静态⽂件的功能就产⽣;其实在以前,IIS还没有集成管道模型的时候我们只能通过动态资源的⽅式进⾏输出,也就是我们经常在*aspx页⾯⾥看见很多*.axd结尾的请求,当然多数情况下是配合AJAX⽤来输出动态JS、HTMDOM、CSS⽤的;最新的IIS已经很好的集成了管道模型,也就是说我们完全可以通过本⾝的扩展来控制所有经过IIS的请求,包括静态⽂件,所以让捆绑静态⽂件成为了可能;下⾯我们将分析⼀下System.Web.Optimization组件的基本运⾏原理,它是如何动态加载的,如何控制缓存的;2】System.Web.Optimization 组件每当我们新建⼀个MVC4站点的时候都会在~/App_Start⽬录下有⼀个BundleConfig.cs的启动⽂件,当然创建其他的4.0及4.0以上的项⽬也会有;我第⼀次看见这个⽂件实在让我困惑,所以我打算简单的分析⼀下,知道其基本原理;代码是⼀个静态⽅法,然后传⼊⼀个BundleCollection集合对象,其实就是Bundle对象的集合,然后通过向集合内部注册多个Bundle;每个Bundle对应着多个静态⽂件,可以想象成就是键值对集合;通过后⾯的Include⽅法包含N多个静态⽂件,这⾥的静态⽂件路径可以是符合特定规则的字符串,由它内部去计算;这是注册阶段,然后就是使⽤阶段,使⽤阶段很简单只要我们通过我们注册的Key字符串就能直接引⽤这些静态⽂件列表;我们只要关注Styles.Render、Scripts.Render两个⽅法,这两个⽅法是想页⾯注⼊之前在后台配置的静态⽂件列表;这样我们在客户端看见的就是被捆绑过后的⽂件集合了;⽂件的连接地址已经是被捆绑过后的地址了,这个地址就是我们在之前注册的时候⽤的key,后⾯它需要这个key去获取value 静态⽂件列表;要想你的捆绑起效果需要在注册的时候加上⼀段:BundleTable.EnableOptimizations = true;代码,意思是说开启捆绑,如果不开启捆绑则默认在调试环境⾥将不起效果,因为System.Web.Optimization使⽤了默认捆绑策略,如果是在Debug模式下,将不启⽤捆绑,如果你⼈为的设置了将覆盖默认设置;使⽤就是这些,下⾯我们需要搞懂它是如何运⾏的,要了解⼀下它的基本原理;3】System.Web.Optimization 组件基本原理既然IIS集成了管道模型,那么我们肯定是能找到对应的HttpModule的,为了节省时间我就不去下载源码了,我们直接⽤反编译⼯具看⼀下;这就是Bundle的HttpModule,它只⽤来处理Bundle的连接地址,虽然它在HTTP的管道中;找到它就好顺藤摸⽠了,但是奇怪的是我在Web.config⾥没有发现它的配置信息,奇怪了,难道它还跑去系统⽂件改,当然是不可能的;所以我⼀时还想不起能有什么办法动态注册,提起动态注册突然有了思路,好像有⼀个Assembly级别的特性⽤来注册Application_Start启动时候的前置代码,会在Application启动之前执⾏,来看⼀下;果然藏着这⾥呢,它注册了⼀个PreApplicationStartCode静态类,使⽤Start⽅法启动;这段代码很简单,先判断有没有执⾏过注册,如果没有就执⾏动态注册,这个动态注册组件是.NETFramework⾃带的,在Microsoft.Web.Infrastructure⾥⾯只不过属于平台相关的,跟没有直接关系,我们可以⽤Microsoft.Web.Infrastructure 来开发⾃⼰的WEB组件;这⾥有⼀个疑问,为什么静态⽅法也要加判断呢,不是只会执⾏⼀次吗,因为静态⽅法的执⾏是不受控制的,所以如果不加判断很有可能会注册多次,出于严谨考虑还是加上;现在基本上我们已经找到源头了,服务端这⾥我们先放⼀下,对于客户端的疑问很多,它既然帮我们捆绑了,那么缓存是如何处理的,也就是说它的输出缓存有没有设置,如果设置了不是有问题;【客户端缓存相关】为了很好的了解请求之间的信息,我们⽤Fiddler监听⼀下;我们看见它的Cache部分是⽤了If-Modified-Since来表⽰本地的⽂件的最后⼀次修改,这样是为了能够让服务器去验证⽂件是否改动,如果没有改动服务器的响应状态码为304,说明Bundle在输出的时候并没有设置对这个⽂件进⾏客户端强制缓存,我们通过Pragma: no-cache头也能看出来了;那么我们得出结论,所有Bundle出来的⽂件都不可能直接缓存在浏览器中,每次都会带上Cache段If-Modified-Since去验证服务器的⽂件版本;刚好这⾥我们可以跟动态输出的静态⽂件地址的后⾯的参数对上了;⽐如:/Content/css?v=ZPnWVRT3c0yyrVDPmI-xkJuhBdJfQsL3A0K5C9WTOk01这个链接后⾯的v参数是表⽰当前Bundle后虚拟⽂件的版本,如果我们在服务器上把⽂件修改了之后那么这个⽂件的If-Modified-Since验证就失败了,会⽣成新的版本号作为连接的参数;我们来看⼀下,⼼⾥踏实;我加了⼀个width:auto的style,那么这个时候我刷新客户端应该是不会再有304出现了;显然/Content/css?v=doYFOk3BdOYWDIRbQ7juV6eQdlJAu6RtC0G13El7X041 ⽂件的版本变了,那么Response也不应该是304了;如果静态⽂件的版本号发⽣改变,根本就不会带上 If-Modified-Since,这个是⽤在每次进⾏进⾏Post是⽤来验证的;其实意思就是说如果没有IIS集成模式那么捆绑⽂件的⽅式只能改变静态⽂件的⽂件名;4】扩展⾃定义类型静态⽂件Bundle对象是所有需要捆绑⽂件的基类,如果我们需要扩展⼀些静态⽂件,如⼀些特定领域的静态⽂件,我们可以直接继承这个类;【XML⽂件的缓存】扩展XML⽂件很简单,我们只需要继承⼀下Bundle对象,所有关于动态⽣成URL都有专门的对象处理,我们来看下代码;public class XmlBundle : Bundle{public XmlBundle(string path) : base(path) { }}public static class XmlBundleRender{public static IHtmlString Render(string path){BundleResolver bundle = new BundleResolver(BundleTable.Bundles);return new HtmlString(string.Format(@"<link href=""{0}"" rel=""stylesheet""/>", bundle.GetBundleUrl(path)));}}⾸先我们需要⼀个继承⾃Bundle对象的XmlBundle,⽤来表⽰我们所有将要传输的XML⽂件捆绑容器,然后我们需要⼀个静态⽅法⽤来注册捆绑后的URL;这个URL的⽣成有专门的BundleResolver对象来完成,我们只需要传⼊所有的BundleCollection对象,我这⾥为了能在浏览器中测试所以写了⼀段stylesheet类型的link;这样我们就能直接在我们需要的地⽅直接使⽤了,我在index视图中引⽤:@MvcApplication4.Seed.XmlBundleRender.Render("~/custom/xml");是不是很简单,这样我们就能对所有想控制捆绑的⽂件进⾏捆绑,只需要继承加简单的静态⽅法辅助;我们来看⼀下我们的XML⽂件是否具有所有缓存特性;第⼀次请求没有加If-Modified-Since段,返回的内容是⼀个简单的<model>222</model> 测试简单,现在我们看它是否在下⼀次不改变内容的情况下使⽤缓存;在我们预料之中,使⽤了缓存数据,下⾯我们需要把服务器上的XML⽂件进⾏修改,将222改成243454637看是否⾃动刷新本地缓存也就是说不会是304返回状态;也刷新缓存,符合理论根据,正确的返回了我们修改后的值;结:其实HTTP不仅仅⽤在浏览器中,会有很多使⽤HTTP的场合,所以我们能很好的将这种功能⽤来捆绑⼀些图⽚、⽂字等多种场合中,确实是个不错的组件;⽂章结束,谢谢;作者:本⽂版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在⽂章页⾯明显位置给出原⽂连接,否则保留追究法律责任的权利。
/
web缓存的实现原理
1 什么是Web缓存
WEB缓存(cache)位于Web服务器和客户端之间。
缓存会根据请求保存输出内容的副本,例如html页面,图片,文件,当下一个请求来到的时候:如果是相同的URL,缓存直接使用副本响应访问请求,而不是向源服务器再次发送请求。
HTTP协议定义了相关的消息头来使WEB缓存尽可能好的工作。
2 缓存的优点
减少相应延迟:因为请求从缓存服务器(离客户端更近)而不是源服务器被相应,这个过程耗时更少,让web服务器看上去相应更快。
减少网络带宽消耗:当副本被重用时会减低客户端的带宽消耗;客户可以节省带宽费用,控制带宽的需求的增长并更易于管理。
3 与缓存相关的HTTP扩展消息头
Expires:指示响应内容过期的时间,格林威治时间GMT
Cache-Control:更细致的控制缓存的内容
Last-Modified:响应中资源最后一次修改的时间
ETag:响应中资源的校验值,在服务器上某个时段是唯一标识的。
Date:服务器的时间
If-Modified-Since:客户端存取的该资源最后一次修改的时间,同Last-Modified。
If-None-Match:客户端存取的该资源的检验值,同ETag。