標籤:style blog http color io os 使用 ar strong
根據緩衝的位置不同,可以區分為:
①用戶端緩衝(緩衝在使用者的用戶端,例如瀏覽器中)
②伺服器緩衝(緩衝在伺服器中,可以緩衝在記憶體中,也可以緩衝在檔案裡,並且還可以進一步地區分為本機快取和分布式緩衝兩種)
應該說,緩衝的設計是一門較為複雜的學問,主要考慮的問題包括:要不要緩衝?要緩衝哪些資料?要緩衝多少資料?要緩衝多久?如何更新緩衝(手動還是自動)?將緩衝放在哪裡?本文將以較為通俗易懂的方式,來看一看在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。它的最大好處就是跨伺服器,跨應用共用快取。
ASP.NET MVC緩衝