NET Petshop詳解(五)

NET Petshop詳解(五):petshop輸出緩存設置
 
ASP.NET的輸出緩存
衡量高性能、可縮放的web應用程序最重要的一個指標就是緩存了。ASP.NET提供了高性能的web應用程序的緩存功能,ASP.NET 有三種可由 Web 應用程序使用的緩存:
· 輸出緩存,它緩存請求所生成的動態響應。
· 片斷緩存,它緩存請求所生成的響應的各部分。
· 數據緩存,它以編程方式緩存任意對象。爲支持這種緩存,ASP.NET 提供了全功能的緩存引擎,使程序員能夠輕鬆地在請求間保留數據。
頁的輸出緩存是非常有用的。在海量的訪問站點中,有些頁面的訪問頻率佔了非常大的比重,即使對這些頁使用輸出緩存很少的時間,也會減輕系統不少的負擔,因爲後面對這些頁面的請求將不在執行創建該頁的代碼。
但是,這樣顯得不夠靈活,頁的請求可能的確是很多,然而在頁面上我們緩存了所有的東西,無論是構造成本高還是構造成本低的部分。能否有一種可以緩存頁的部分的數據呢?幸運的是ASP.NET提供了針對每個請求來創建或自定義該頁的各部分。比如說我們可以對頁面上構造成本很高的用戶控件做片斷緩存。
ASP.NET 緩存支持文件和緩存鍵依賴項,使開發人員可以使緩存項依賴於外部文件或其他緩存項。此項技術可用於在項的基礎數據源發生更改時使該項無效。 ASP.NET可以將這些項存儲在 Web 服務器上或請求流中的其他軟件上,例如代理服務器或瀏覽器。這可以使您避免重新創建滿足先前請求的信息,特別是當在服務器上創建時要求大量處理器時間或其他資源的信息。
Petshop的頁緩存設置
我們可以可通過使用低級別的 OutputCache API 或高級別的 @ OutputCache 指令來實現頁的輸出緩存。啓用輸出緩存後,當發出對頁的第一個 GET 請求時創建一個輸出緩存項。隨後的 GET HEAD 請求由該輸出緩存項服務,直到該緩存請求過期。輸出緩存還支持緩存的 GET POST 名稱/值對的變體。
輸出緩存遵循頁的過期和有效性策略。如果某頁位於輸出緩存中,並且有一個過期策略標記指示該頁自緩存起 60 分鐘後過期,則在 60 分鐘後將該頁從輸出緩存中移除。如果此後接收到另一個請求,則執行頁代碼,並且可以再次緩存該頁。
下面的指令在響應時激活輸出緩存:
<%@ OutputCache Duration="60" VaryByParam="none"%>
DurationVaryByParam是必選參數,前者標識過期時間,後者表示GET POST 名稱/值對的字符串。如果不使用該屬性,可是設置爲none。在這裏我們還要說明一個參數VaryByCustom,使用這個參數,我們可以自定義輸出緩存要求的任意文本。除了在OutputCache指令裏面申明該屬性之外,我們還得在應用程序的 global.asax 文件的代碼聲明塊中,重寫 GetVaryByCustomString 方法來爲自定義字符串指定輸出緩存的行爲。
舉一列來說:
<%@ OutputCache VaryByParam="none" VaryByCustom="CategoryPageKey" Location="server" Duration="43200" %>
這裏的VaryByCustom定義的爲CategoryPageKey,那麼在global.asax裏面我們必須定義CategoryPageKey這個字符創輸出緩存的行爲,見下面代碼。
public override string GetVaryByCustomString(HttpContext context, String arg) {
              string cacheKey = "";
              switch(arg) {
                   case "CategoryPageKey":
                       if (Request.IsAuthenticated == true) {
                            cacheKey = "QQQ" + context.Request.QueryString["category_id"] + context.Request.QueryString["requestedPage"];
                       }
                       else {
                            cacheKey = "AAA" + context.Request.QueryString["category_id"] + context.Request.QueryString["requestedPage"];
                       }
                       break;
                   case "SearchPageKey" :
                       if (Request.IsAuthenticated == true) {
                            cacheKey = "QQQ" + context.Request.QueryString["search_text"] + context.Request.QueryString["requestedPage"];
                       }
                       else {
                            cacheKey = "AAA" + context.Request.QueryString["search_text"] + context.Request.QueryString["requestedPage"];
                       }
                       break;
                   case "ProductPageKey" :
                       if (Request.IsAuthenticated == true) {
                            cacheKey = "QQQ" + context.Request.QueryString["name"] + context.Request.QueryString["product_id"] + context.Request.QueryString["requestedPage"];
                       }
                       else {
                                 cacheKey = "AAA" + context.Request.QueryString["name"] + context.Request.QueryString["product_id"] + context.Request.QueryString["requestedPage"];
                       }
                       break;
                   case "ProductDetailsPageKey" :
                       if (Request.IsAuthenticated == true) {
                            cacheKey = "QQQ" + context.Request.QueryString["item_id"] + context.Request.QueryString["requestedPage"];
                       }
                       else {
                            cacheKey = "AAA" + context.Request.QueryString["item_id"] + context.Request.QueryString["requestedPage"];
                       }
                       break;
                   case "UserID" :
                       if (Request.IsAuthenticated == true) {
                            cacheKey = "UserID_In";
                       }
                       else {
                            cacheKey = "UserID_Out";
                       }
                       break;
              }
              return cacheKey;
         }
從上面對CategoryPageKey字符創所作的行爲來看,當我們的請求頁面中含有對特定的category_id的某一分頁顯示的數據頁的請求時,將調用緩存(自然是已經緩存了該頁)。
下表列出了petshop的web應用程序的輸出緩存設置。
ASP.NET WebForms
Cache setting
Duration
ControlHeader
<%@ OutputCache
         Duration="43200"         
         VaryByParam="none"
         VaryByCustom="UserID" %>
12 hours
Default
<%@ OutputCache
         Duration="43200"
         VaryByParam="none"
         VaryByCustom="UserID" %>
12 hours
Help
<%@ OutputCache
         Duration="43200" 
         VaryByParam="none"
         VaryByCustom="UserID" %>
12 hours
Category
<%@ OutputCache
         Duration="43200" 
         VaryByParam="none"
         VaryByCustom="CategoryPageKey " %>
12 hours
Product
<%@ OutputCache
         Duration="43200" 
         VaryByParam="none"
         VaryByCustom="ProductPageKey " %>
12 hours
ProductDetails
<%@ OutputCache
         Duration="43200" 
         VaryByParam="none"
         VaryByCustom="ProductDetailsPageKey " %>
12 hours
Search
<%@ OutputCache
         Duration="43200" 
         VaryByParam="none"
         VaryByCustom="SearchPageKey " %>
12 hours
顯然petshopweb頁面上部的ControlHeader是隨着用戶登陸的狀態有關的,故其設置了VaryByCustom屬性以來標識用戶不同登陸狀態的緩存版本。而Category頁面由於可能被大量的訪問,並且數據量很大,是十分有必要緩存的,但是由於數據的隨機性很大,存在不同的版本,比如說是不同類別的Category,甚至不同的分頁顯示的數據頁,在這裏採用了VaryByCustom屬性以緩存不同版本的頁。
Petshop片斷緩存
在前面我們提到ASP.NET可以提供頁的局部數據的緩存,通常是一些構造代價較大的部分,諸如用戶控件。在petshop裏面,大量使用了用戶控件(尤其是.NET示例程序Duwamish7.0使用了更多的用戶控件,那些頁面簡直就是控件的拼裝),用戶控件的緩存設置方法和aspx頁的緩存設置方法基本相同,在這裏我們不再列出。只有ControlHeader控件使用了緩存設置,見上表。
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章