petshop缓存机制理解

来源:互联网 发布:拥有的域名可以干什么 编辑:程序博客网 时间:2024/04/30 08:45
 
为了提高网站首页的性能,首页凡是需要调用数据库显示数据的地方都会先试图从缓存中调用数据,如果缓存中没有可用数据再打开数据库取出记录集
页面级输出缓存
作为最简单的缓存形式,输出缓存只是在内存中保留为响应请求而发送的HTML的副本。其后再有请求时将提供缓存的输出,直到缓存到期,这样,性能有可能得到很大的提高(取决于需要多少开销来创建原始页面输出-发送缓存的输出总是很快,并且比较稳定)。
  
    实现
  
    要实现页面输出缓存,只要将一条OutputCache指令添加到页面即可。
  
  <%@ OutputCache Duration="60" VaryByParam="*" %>
 
片段缓存,用户控件输出缓存
  
    缓存整个页面通常并不可行,因为页面的某些部分是针对用户定制的。不过,页面的其他部分是整个应用程序共有的。这些部分最适合使用片段缓存和用户控件进行缓存。此外,菜单和其他布局元素,尤其是那些从数据源动态生成的元素,也可以用这种方法进行缓存。
  
    如果需要,可以按以下条件选择需要缓存的控件:
  
    (1)某控件的属性已改变
  
    (2)由页面级输出缓存所支持的任何一种页面或控件状态改变
  
    一旦对某些控件进行了缓存,使用它们的几百个页面就可以共享这些控件,而不再需要为每个页面保留单独的控件缓存版本。
  
    实现
  
    片段缓存使用的语法与页面级输出缓存一样,但其应用于用户控件(.ascx文件)而不是Web窗体(.aspx文件)。除了Location属性,对于OutputCache在Web窗体上支持的所有属性,用户控件也同样支持。用户控件还支持名为VaryByControl的OutputCache属性,该属性将根据用户控件(通常是页面上的控件,例如,DropDownList)的成员的值改变该控件的缓存。如果指定了VaryByControl,可以省略VaryByParam。最后,在默认情况下,对每个页面上的每个用户控件都单独进行缓存。不过,如果一个用户控件不随应用程序中的页面改变,并且在所有页面都使用相同的名称,则可以设置参数Shared的值为“true”,该参数将使用户控件的缓存版本供引用该控件的所有页面使用。
  
    示例
  
  <%@ OutputCache Duration="60" VaryByParam="*" %>
  
    该示例将缓存用户控件60秒,并且将针对查询字符串的每个变动、针对此控件所在的每个页面创建单独的缓存条目。 
<%@ OutputCache Duration="60" VaryByParam="none"
  VaryByControl="CategoryDropDownList" %>
  
    该示例将缓存用户控件60秒,并且将针对CategoryDrop
 
 
缓存API,使用Cache对象
  
    页面级和用户控件级输出缓存的确是一种可以迅速而简便地提高站点性能的方法,但是在ASP.NET中,缓存的真正灵活性和强大功能是通过Cache对象提供的。使用Cache对象,您可以存储任何可序列化的数据对象,基于一个或多个依赖项的组合来控制缓存条目到期的方式。这些依赖项可以包括自从某对象被缓存后经过的时间、自从某对象上次被访问后经过的时间、对文件或文件夹的更改以及对其他缓存对象的更改,在略作处理后还可以包括对数据库中特定表的更改。
  
    在Cache中存储数据
  
    在Cache中存储数据的最简单的方法就是使用一个键为其赋值,就像HashTable或Dictionary对象一样:
  
  Cache["key"] = "value";
  
    这种做法将在缓存中存储项,同时不带任何依赖项,因此它不会到期,除非缓存引擎为了给其他缓存数据提供空间而将其删除。要包括特定的缓存依赖项,可使用Add()或Insert()方法。其中每个方法都有几个重载。Add()和Insert()之间的唯一区别是,Add()返回对已缓存对象的引用,而Insert()没有返回值(在C#中为空,在VB中为Sub)。
  
    示例
  
  Cache.Insert("key", myXMLFileData, new
  System.Web.Caching.CacheDependency(Server.MapPath("users.xml")));
        
          SqlCacheDependency特性实际上是通过System.Web.Caching.SqlCacheDependency类来体现的。 通过该类,可以在所有支持的SQL Server版本(7.0,2000,2005)上监视特定的SQL Server数据库表,并创建依赖于该表以及表中数据行的缓存项。当数据表或表中特定行的数据发生更改时,具有依赖项的数据项就会失效,并自动从 Cache中删除该项,从而保证了缓存中不再保留过期的数据。
在数据库中新建相应的缓存数据库,相应的数据库表,触发器,存储过程等,作用是处理过期数据
ICacheDependency提供缓存依赖接口
CacheDependencyFactory处理缓存依赖的实现
其中 DependencyAccess.cs工厂模式处理依赖实现
 DependencyFacade.cs采用Facade模式统一工厂模式实现后的调用
TableCacheDependency 实现ICacheDependency的缓存依赖,对应具体的item,product等表
web项目中的App_Code文件夹中webUtility实际上是Proxy模式中的代理对象,实现函数以处理是使用BLL直接调用数据库还是使用Cache,诸如此类的还有ItemDataProxy.cs,ProductDataProxy.cs
从职责分离与分层设计的角度分析,我更希望这些Proxy对象是被定义在业务逻辑层中,而不像在PetShop的设计那样,被划分到表示层UI中。 此外,如果需要考虑程序的可扩展性与可替换性,我们还可以为真实对象与代理对象建立统一的接口或抽象类。然而,单以PetShop的表示层调用来看,采用 静态类与静态方法的方式,或许更为合理。
最后在web页面中调用webUtility方法,不允许使用Cache则直接从数据库调出数据,否则第一次时从数据库调出数据,将数据添加到缓存,并制定对数据库表的依赖,相应数据库表更改时缓存内容删除。

具体的Facade模式,和Proxy模式没有弄清楚机理。