.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控件使用了緩存設置,見上表。

 

 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章