ASP.NET MVC緩存


根據緩存的位置不同,可以區分為:

  ①客戶端緩存(緩存在用戶的客戶端,例如瀏覽器中)

  ②服務器緩存(緩存在服務器中,可以緩存在內存中,也可以緩存在文件里,並且還可以進一步地區分為本地緩存和分布式緩存兩種)

  應該說,緩存的設計是一門較為復雜的學問,主要考慮的問題包括:要不要緩存?要緩存哪些數據?要緩存多少數據?要緩存多久?如何更新緩存(手動還是自動)?將緩存放在哪里?本文將以較為通俗易懂的方式,來看一看在MVC4的項目中,如何使用緩存功能。對於上述提到的一些具體業務問題,我這里不會進行太過深入地探討。

MVC3中的緩存功能鎼滅儲

  ASP.NET MVC3 繼承了ASP.NET的優良傳統,內置提供了緩存功能支持。主要表現為如下幾個方面:

  ①可以直接在Controller,Action或者ChildAction上面定義輸出緩存(這個做法相當於原先的頁面緩存和控件緩存功能)

  ②支持通過CacheProfile的方式,靈活定義緩存的設置(新功能)

  ③支持緩存依賴,以便當外部資源發生變化時得到通知,並且更新緩存

  ④支持使用緩存API,還支持一些第三方的緩存方案(例如分布式緩存)

  那么,下面我們就逐一來了解一下

一、使用輸出緩存

MVC中內置了一個OutputCache的ActionFilter,我們可以將它應用在某個Action或者ChildAction上面

【備注】ChildAction是MVC3的一個新概念,本質上就是一個Action,但通常都是返回一個PartialView。通常這類Action,可以加上一個ChildActionOnly的ActionFilter以標識它只能作為Child被請求,而不能直接通過地址請求。鎼滅儲

【備注】我們確實可以在Controller級別定義輸出緩存,但我不建議這么做。緩存是要經過考慮的,而不是不管三七二十一就全部緩存起來。緩存不當所造成的問題可能比沒有緩存還要大。

1 [OutputCache(Duration=10)] 2 public ActionResult Index() 3  { 4 //這里目前作為演示,是直接硬編碼,實際上可能是讀取數據庫的數據 5 var employees = new[]{ 6 new Employee(){ID=1,Name="ares",Gender="Male"} 7  }; 8 return View(employees); 9 }

   那么,也就是說,第一次請求這個Index的時候,里面的代碼會執行,並且結果會被緩存起來,然后在10秒鍾內,第二個或者后續的請求,就不需要再次執行,而是直接將結果返回給用戶即可。

  這個OutputCache的Attribute,實際上是一個ActionFilter,它有很多參數。參考http://msdn.microsoft.com/zh-cn/library/system.web.mvc.outputcacheattribute(v=vs.118).aspx

使用緩存配置文件鎼滅儲

  第一節中,我們詳細地了解了MVC中,如何通過OutputCache這個ActionFilter來設置緩存。但是,因為這些設置都是通過C#代碼直接定義在Action上面的,所以未免不是很靈活,例如我們可能需要經常調整這些設置,該如何辦呢?

  ASP.NET 4.0中提供了一個新的機制,就是CacheProfile的功能,我們可以在配置文件中,定義所謂的Profile,然后在OutputCache這個Attribute里面可以直接使用。

  通過下面的例子,可以很容易看到這種機制的好處。下面的節點定義在system.web中

1 <caching>
2       <outputCacheSettings>
3         <outputCacheProfiles>
4           <add name="employee" duration="10" enabled="true" location="ServerAndClient" varyByParam="none"/>
5         </outputCacheProfiles>
6       </outputCacheSettings>
7     </caching>
 1 [OutputCache(CacheProfile="employee")]
 2         public ActionResult Index()
 3         {
 4             //Response.Cache.SetOmitVaryStar(true);
 5             ViewBag.CurrentTime = DateTime.Now.ToString();
 6 
 7             //這里目前作為演示,是直接硬編碼,實際上可能是讀取數據庫的數據
 8             var employees = new[]{
 9                 new Employee(){ID=1,Name="ares",Gender="Male"}
10             };
11             return View(employees);
12         }

 

 二、使用緩存API

  通過上面的兩步,我們了解到了使用OutputCache,並且結合CacheProfile,可以很好地實現靈活的緩存配置。但是有的時候,我們可能還希望對緩存控制得更加精細一些。因為OutputCache是對Action的緩存,不同的Action之間是不能共享數據的,假如某些數據,我們是在不同的Action之間共享的,那么,簡單地采用OutputCache來做,就會導致對同一份數據,緩存多次的問題。

  所以,ASP.NET除了提供OutputCache這種基於聲明的輸出緩存設置之外,還允許我們在代碼中,自己控制要對哪些數據進行緩存,並且提供了更多的選項。

  關於如何通過API的方式添加或者使用緩存,請參考http://msdn.microsoft.com/zh-cn/library/18c1wd61%28v=VS.80%29.aspx鎼滅儲

  基本上就是使用HttpContext.Cache類型,可以完成所有的操作,而且足夠靈活。

  值得一提的是,我知道不少公司在項目中都會采用一些ORM框架,某些ORM框架中也允許實現緩存。例如NHibernate就提供了較為豐富的緩存功能,大致可以參考一下 http://www.cnblogs.com/RicCC/archive/2009/12/28/nhibernate-cache-internals.html

  需要注意的是,微軟自己提供的Entity Framework本身並沒有包含緩存的功能。

  這里仍然要特別提醒一下,使用這種基於API的緩存方案,需要仔細推敲每一層緩存的設置是否合理,以及更新等問題。

三、使用緩存依賴

  很早之前,在ASP.NET中設計緩存的時候,我們就可以使用緩存依賴的技術。關於緩存依賴,詳細的信息請參考 http://msdn.microsoft.com/zh-cn/library/ms178604.aspx

  實際上,這個技術確實很有用,ASP.NET默認提供了一個SqlCacheDependency,可以通過配置,連接SQL Server數據庫,當數據庫的表發生變化的時候,會通知到ASP.NET,該緩存就會失效。

  值得一提的是,不管是采用OutputCache這樣的聲明式的緩存方式,還是采用緩存API的方式,都可以使用到緩存依賴。而且使用緩存API的話,除了使用SqlCacheDependency之外,還可以使用標准的CacheDependency對象,實現對文件的依賴。

四、分布式緩存

  上面提到的手段都很不錯,如果應用系統不是很龐大的話,也夠用了。需要注意的是,上面所提到的緩存手段,都是在Web服務器本地內存中進行緩存,這種做法的問題在於,如果我們需要做負載均衡(一般就會有多台服務器)的時候,就不可能在多台服務器之間共享到這些緩存。正因為如此,分布式緩存的概念就應運而生了。

  談到分布式緩存,目前比較受到大家認可的一個開源框架是 memcached。顧名思義,它仍然使用的是內存的緩存,只不過,它天生就是基於分布式的,它的訪問都是直接通過tcp的方式,所以可以訪問遠程服務器,也可以多台Web服務器訪問同一台緩存服務器。

  需要注意的是,分布式緩存不是為了來提高性能的(這可能是一個誤區),並且可以肯定的是,它的速度一定會被本地慢一些。如果你的應用只有一台服務器就能滿足要求,你就沒有必要使用memcached。它的最大好處就是跨服務器,跨應用共享緩存。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM