1、如果每次进入页面的时候都查询数据库生成页面内容的话,如果访问量非常大,则网站性能会非常差。而如果只有第一次访问的时候才查询数据库生成页面内容,以后都直接输出内容,则能提高系统性能。这样无论有多少人访问都只访问一次数据库,数据库压力不变。
2、为了保证从缓存中读取数据和数据库中数据一致,则需要在数据库中对应的数据发生变化的时候,清除缓存中相应的数据(缓存依赖)。
3、缓存是改进网站性能的第一个手段,Asp.Net缓存主要分为:页面缓存(中庸)、数据源缓存(最不灵活的)、数据缓存(灵活)这三种主要类型。
页面缓存
给aspx页面添加<%@ OutputCache Duration=“15” VaryByParam=“none”%>标签就可以启用页面缓存,这样整个页面的内容都会被缓存,页面中的ASP.Net代码、数据源在缓存期间都不会被运行,而是直接输出缓存的页面内容。 Duration表示缓存时间,以秒为单位,超过这个时间则缓存失效,再次生成以后会再缓存15秒,以此类推。注:这个缓存是在服务器缓存的,不是在客户端,因为用HttpWatch还是能看到向服务器提交的请求,只不过服务器看到有缓存就没有再执行页面类。
页面缓存是针对所有这个页面的访问者。这样1个访问者和1万个访问者、一次访问和100万次访问对数据库的压力是一样的。
测试代码很简单
Cache.aspx.cs
View Code前台Cache.aspx
View Code<% @ Page Language="C#" AutoEventWireup="true" CodeFile="Cache.aspx.cs" Inherits ="Cache" %> <! DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <% @ OutputCache Duration="15" VaryByParam="none" %> <!-- 添加代码之后 客户端依然向服务端发送了请求 但是服务端返回了304的状态码 304---相当于告诉浏览器 页面没有修改 从自己的缓存里拿取页面 --> < html xmlns ="http://www.w3.org/1999/xhtml"> < head runat ="server"> <title ></ title> </ head> < body> <form id="form1" runat="server"> <div > </div > </form > </ body> </ html>
两次请求图解页面缓存
页面缓存原理图解
补充:
1、如果需要针对http://www.cnblogs.com/piziyimao/?page=1 http://www.cnblogs.com/piziyimao/?page=2两个相同页面的不同的page进行单独缓存需要设置VaryByParam=“page”如果有多个确定缓存的参数 则将参数名用分号隔开即可,比如VaryByParam=“page;number” page与number是或的关系 page或者number中有一个值不相同即产生不同缓存两者值都相同的情况下才使用同一缓存
2、缓存可能会有过期数据的问题,因此根据需求选用。
3、如果想让任何不同的查询字符串都创建不同的缓存,则设置VaryByParam="*",一般情况下设置“*”就足够。
4、在WebUserControl中也可以像页面缓存一样设置控件的缓存。
数据源缓存
设定ObjectDataSource的CacheDuration(缓存时间:秒),EnableCaching=true。这样每隔CacheDuration指定的时间段才调用ObjectDataSource绑定的数据库查询方法,其他时候都是直接返回缓存的数据。
DataSourceCache.aspx页面代码如下
View Code<% @ Page Language="C#" AutoEventWireup="true" CodeBehind="DataSourceCache.aspx.cs" Inherits ="WebForm.DataSourceCache" %> <! DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> < html xmlns ="http://www.w3.org/1999/xhtml"> < head runat ="server"> <title > 数据源缓存</ title > <style type="text/css"> #tblist{ border-top :1px solid #000 ; border-left : 1px solid #000 ; margin: 0px auto ;width : 600px;} #tblist td {border-bottom : 1px solid #000 ; border-right: 1px solid #000; padding :5px } </style > </ head> < body> <form id="form1" runat="server"> <div > < asp: ObjectDataSource ID ="ObjectDataSource1" runat ="server" EnableCaching ="true" CacheDuration ="" SelectMethod ="getAllClasses" TypeName ="BLL.Classes"> < SelectParameters> < asp: Parameter DefaultValue ="false" Name ="isDel" Type ="Boolean" /> </ SelectParameters> </ asp: ObjectDataSource > </div > <ul id="tbList"> <asp : Repeater ID ="Repeater1" runat ="server" DataSourceID ="ObjectDataSource1"> <ItemTemplate > <li > <% # Eval("CName" ) %> </li > </ItemTemplate > </asp : Repeater> </ul > </form > </ body> </ html>
原理图解:
页面缓存和数据源缓存的区别
1.页面缓存的是保存被请求页面对象执行后生成的HTML代码
而数据源缓存是保存的数据源控件上次查询到的数据集合(List<Classes>list)
2.页面缓存失效前服务器都不会去创建被请求的页面类对象来执行生成html代码从缓存中直接获取html代码
数据源缓存不管缓存有没有失效 服务器都会为每个浏览器请求创建页面类对象并执行生成html代码只是不会再去数据库查询数据而是用数据源缓存中的数据
自定义缓存以及文件缓存依赖
View Codeusing System; using System.Web.Caching; namespace WebForm { public partial class CustomCache : System.Web.UI. Page { protected void Page_Load( object sender, EventArgs e) { //Response.Write(DateTime.Now.ToString()); if (Cache["dt" ] != null) { Response.Write( "缓存中的数据:" + Cache[ "dt"].ToString()); } else { //使用绝对过期时间 //参数(键key,值value,缓存依赖项,20秒绝对过期时间,不使用相对过期时间) //Cache.Insert("dt", DateTime.Now, null, DateTime.Now.AddSeconds(20), System.Web.Caching.Cache.NoSlidingExpiration); //使用相对过期时间 //参数(键key,值value,缓存依赖项,绝对过期时间无限大,时间戳)15秒之内请求 服务器都会重置过期时间 //Cache.Insert("dt", DateTime.Now, null, DateTime.MaxValue, new TimeSpan(0, 0, 15)); //使用 文件缓存依赖 //缓存 依赖于指定路径文件内容 CacheDependency file = new CacheDependency (Server.MapPath("CacheDependencyFile.txt" )); //参数(键key,值value,缓存依赖项,绝对过期时间无限大,时间戳,缓存优先级,依赖的文件内容发生改变时调用的回调函数) Cache.Insert( "dt" , DateTime .Now, null, DateTime .MaxValue, new TimeSpan (0, 0, 15), CacheItemPriority .Normal, CacheItemRemovedCallback); Response.Write( "缓存中没有数据,已将当前时间存入自定义缓存中" ); } } /// 缓存依赖文件CacheDependencyFile内容发生改变时触发 /// <param name="key"> 被删除缓存键 </param> /// <param name="value"> 被删除缓存值 </param> /// <param name="reason"> 被删除原因 </param> public void CacheItemRemovedCallback( string key, object value, CacheItemRemovedReason reason) { string content = "key" + key + ",value" + value + ",Reason" + reason.ToString(); string filePath = Server.MapPath("CacheDependencyFile_Log.txt" ); System.IO. File .WriteAllText(filePath, content); } } }
CacheDependencyFile_Log.txt
内容如下:
Key dt,value2013/2/26 13:37:25,ReasonExpired
自定义缓存中的绝对过期时间与相对过期时间:
绝对过期时间:是指一个确切的时间点 过了,缓存就自动清空
相对过期时间:是指一个确切的时间戳(如:15秒),那么页面在15秒内被任何一个浏览器访问,缓存失效时间都会更新回15秒并重新倒数计时,一旦15秒内没有任何访问那么服务器会清空该缓存
来源:https://www.cnblogs.com/xiaogui9527/archive/2013/03/26/2982338.html