概述
緩衝學術一些的解釋是”將常用資料放入易於讀取的地方以提高效能”。而對於Asp.net來說,需要被緩衝的對象多種多樣,包括從資料庫中提取出來的資料,以及aspx頁面產生的靜態頁,甚至是編譯好的程式集。合理利用緩衝能讓Asp.net的效能大幅提升,下面將對Asp.net中的緩衝機制進行簡單概述。
緩衝的分類
在Asp.net中,大部分緩衝機制是儲存在cache對象中,也就是伺服器記憶體的一部分。當使用者請求資料時,如果資料已經被緩衝,則使用者所提取的資料直接從服務端返回,而不是從資料庫等底層資料庫提取。這對效能的提升不得不說很有協助。下面來看asp.net中幾種緩衝機制。
組件快取
簡單的說,這種緩衝是asp.net內建的,無需開發人員進行參與的緩衝方式。即當第一次請求伺服器時,Page類以及相關程式集被編譯,當下次請求時,訪問緩衝後的編譯而不是重新編譯。CLR會自動檢測代碼的改變,如果代碼改變後,當下次訪問時,相關代碼會被重新編譯。
資料來源緩衝
資料來源緩衝,顧名思義,也就是利用資料來源控制項對擷取的資料進行緩衝的方式。這些控制項包括SqlDataSource,ObjectDataSource等:
作為抽象類別的DataSourceControl暴漏了如下屬性用於緩衝:
名稱 |
說明 |
CacheDuration |
擷取或設定以秒為單位的一段時間,資料來源控制項就在這段時間內緩衝 SelectMethod 屬性檢索到的資料。 |
CacheExpirationPolicy |
擷取或設定緩衝的到期行為,該行為與期間組合在一起可以描述資料來源控制項所用緩衝的行為。 |
CacheKeyDependency |
擷取或設定一個使用者定義的鍵依賴項,該鍵依賴項連結到資料來源控制項建立的所有資料緩衝對象。 |
EnableCaching |
擷取或設定一個值,該值指示 ObjectDataSource 控制項是否啟用資料緩衝。 |
而使用起來就非常簡單了,只需要將緩衝的相關屬性進行設定即可。比如我想要當前資料來源緩衝10秒,只需要設定EnableCaching屬性和CacheDuration屬性如下:
<asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:AdventureWorksConnectionString %>" SelectCommand="SELECT top 10 * FROM [Person].[Contact]" EnableCaching="true" CacheDuration="10"></asp:SqlDataSource>
這種方式的工作原理可以用表示:
關於ObjectDataSource我推薦閱讀Caching Data with the ObjectDataSource
SQL Cache Dependency
大家應該注意到了上面的資料來源控制項還暴漏了CacheKeyDependency屬性,這是用於實現SQL Cache Dependency的方式,關於Dependency,其實就是在資料庫表內容改變時,將相應的緩衝進行更新,正如Dependency這個詞的意思一樣,是緩衝依賴底層資料庫。下面就要說到兩種實現SQL Cache Dependency的方法了。
方法一:使用輪流查詢機制(polling-based):
這種方式實現機制是在sql server中插入以AspNet_SqlCacheNotification_Trigger開頭的一個特殊的表和5個預存程序,當被監測的表資料發生改變時,則一個名為AspNet_SqlCacheTablesForChangeNotification的表被更新,而Asp.net程式會根據使用者佈建的間隔時間每隔一定時間檢查一下資料庫內容是否更新,如果更新,則將緩衝中的資料進行跟新。
這種機制配置相對比較麻煩。具體做法網上有很多教程,這裡我推薦閱讀:Using SQL Cache Dependencies.
使用起來就很簡單了,可以在頁面頭部的OutputCache指令中設定,會社DataSource空間中進行設定,設定格式為:“資料庫名:表名”.裡面的表名即是需要監測是否改變的表名,樣本如下:
<%@ OutputCache Duration="30" VaryByParam="none" SqlDependency="DatabaseName:tableName" %>
如果需要添加多個表,則用”;”進行分割
SqlDependency="database:table;database:table"
方法二:使用通知機制(notification-based)
使用通知機制配置起來要簡便很多,但是sql server的版本需要9.0以上,也就是sql server 2005,使用這種方式需要將sql server的通知服務開啟。
使用通知機制可以對頁面進行緩衝,也可以對datasouce控制項進行緩衝,對頁面進行緩衝代碼如下:
<%@ OutputCache Duration="30" VaryByParam="none" SqlDependency="CommandNotification" %>
注意SqlDependency必須設定成CommandNotification。
對於datasource控制項,也是同樣:
<asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:AdventureWorksConnectionString %>" SelectCommand="SELECT top 10 * FROM [Person].[Contact]" EnableCaching="true" CacheDuration="10" SqlCacheDependency="CommandNotification"></asp:SqlDataSource>
輸出緩衝(output Caching)
輸出緩衝是頁面層級的緩衝,是將aspx頁面內容在第一次請求後產生的靜態頁放入緩衝,在不到期時間內每一次請求時從緩衝中返回靜態頁,而不是重新走完Asp.net的生命週期。可以將可以通過在頁面頭部加入OutputCache指令實現,也可以通過HttpCachePolicy類實現。
輸出緩衝可以緩衝整個頁面,也可以緩衝部分頁面,快取頁面面的一部分是通過使用者控制項來實現。
下面來看通過OutputCache指令實現頁面緩衝:
前面已經看到,這種方式十分簡單,下面說一下OutputCache的重點屬性
Duration
頁面到期的時間,單位為秒。超過到期時間後,則在下一次請求時頁面會重建並緩衝。
VaryByHeader
VaryByCustom
VaryByParam
VaryByControl
VaryByContentEncodings
這些屬性都是為了儲存頁面的多個版本,比如說一個頁面用於顯示產品,則根據產品id的不同,緩衝同一個頁面的不同版本,具體的意思請看MSDN
CacheProfile
這個選項有些像連接字串,作用只是將具體的緩衝選項變成對於選項的引用,比如我們在Web.Config放入如下代碼:
<caching> <outputCacheSettings> <outputCacheProfiles> <add name="CacheProfile" enabled="true" duration="60" varyByParam="product:id"/> </outputCacheProfiles> </outputCacheSettings> </caching>
則在引用時只需要在頁面頭部設定如下:
<%@ OutputCache CacheProfile="CacheProfile" %>
而不是全部寫入頁面
DiskCacheable
因為伺服器記憶體是有限的,所以通過將DiskCacheable屬性設定為true,則可以將快取頁面面放入硬碟中,這樣即使伺服器崩潰重啟,緩衝依然存在.
緩衝部分頁面
快取頁面面的一部分實現原理和緩衝整個頁面毫無二致,都是在頁面頭部加入OutputCache指令,唯一的不同是緩衝部分頁面是在使用者控制項中進行的。這部分就不在多說了。
使用HttpCachePolicy快取頁面面
前面已經說了通過OutputCache指令在頁面頭部設定緩衝選項,另一種替代方法是使用HttpCachePolicy類,這個類的執行個體是Response.Cache.如果使用HttpCachePolicy設定緩衝,則需要在頁面移除OutputCache指令。
比如:
<%@ OutputCache Duration="30" VaryByParam="state;city" %>
和下面代碼是等價的:
Response.Cache.SetExpires(DateTime.Now.AddSeconds(30)); Response.Cache.VaryByParams["state"] = true; Response.Cache.VaryByParams["city"] = true;
更多關於HttpCachePolicy,請查看MSDN
對象緩衝
對象緩衝是將繼承與System.Object的對象緩衝在伺服器的記憶體中,通過Page類的Cache屬性可以訪問到Cache集合。Cache內可以放任何類型的對象,但是要小心使用Cache,因為Cache是佔用伺服器記憶體,如果使用不當,也許會拖累效能。
使用Cache的例子:
//save object into Cache Cache["table"] = GridView1; //get object from Cache GridView gv = (GridView)Cache["table"];
要注意的是,再提取緩衝中的對象時,一定別忘了強制轉換。
總結
文中對Asp.net的緩衝機制進行了簡述,asp.net中的緩衝極大的簡化了開發人員的使用。如果使用得當,程式效能會有客觀的提升。