转载:關於 ASP.NET 的 Cache
2007-08-20 10:43 Koy 阅读(269) 评论(0) 编辑 收藏 举报
转载自:http://blog.roodo.com/thinkingmore/archives/867191.html
一般人大概會想,這有甚麼好說的,不就是在頁面加上 @ OutputCache 指示詞(Directive), 這樣就表示會快取頁面.
列在 .Net framework SDK documentation 裡的詳細語法:
或許吧,這沒啥大不了的,但我好奇的是,背地裡,.Net 是怎麼幫我完成這件事情的呢??
從 .Net Framework SDK documentation 裡面,幾乎無法找到相關資訊,解釋得很籠統.
於是我只能作這些猜想:
1. .Net 利用 HTTP/1.1 的 Caching 來實現.
2. 內部再使用 Cache hashtable 來避免對後端過於頻繁的存取.例如,取得資料以後,先放到 Cache,如果 Cache 裡面找的到(表示沒過期),就直接拿來顯示,否則的話就再去取資料.
我對第二點沒什麼意見,實際上應該是要這麼作.
但是第一點,我就有問題了. HTTP/1.1 的 Caching 機制對 server 端來說,server 只是送出特定的 HTTP header, 如 Cache-Control, Expires 等等. (參見 HTTP/1.1: Caching in HTTP ).
對 client 來說,他收到這些 header, 怎麼實做,反而是看他自己.如果是坊間抓網頁程式,他可以忽略這些 header, 卯起來抓,那麼這樣就沒有 cache 的效果啦~
另外一點,我感到懷疑的,在他語法裡,可以指定 Any/Client/Downstream/Server, 所謂的 Server, 又是指甚麼意義呢?
就我自己的認知,應該是 Server 在處理的時候,會把整個頁面放到 Cache 裡面.
當遇到有人索取這頁面的時候,就會檢查 Cache, 如果有就直接取出.
所以我查找 Mono 與 .Net 解釋 HttpApplication 的部份,他們都特別指出了 HttpApplication 收到 web request 以後處理的順序:
特別注意步驟 4 與步驟 9, 他們都提到了 Cache.
p.s. 我覺得 Mono Framework class reference 寫的比較清楚, 參閱 HttpApplication
接著,我又利用 Google 查找相關資訊.
發現有用mono應用程式的 web.config 多半都會加掛 OutputCacheModule 這個 Module.
參考 mono 的源碼以後,發現這就是我要找的.
這個 Module 的確做了我推想的事情.
他在 OnResolveRequestCache 事件先依據 FilePath 去檢查 Cache, 如果存在,就直接以 Cache 內保存的內容輸出.
接著在 OnUpdateRequestCache 事件,檢查頁面是否需要被 Cache, 需要的話,就把輸出結果保存到 Cache 中.
Bingo!!
但這是mono的作法, .Net 是否也有同樣的類別呢??
我利用Reflector 這個工具去看 System.Web.dll, 的確, 有 OutputCacheModule 這個 Module.
至此,我們已經解決了我想要解決的問題,並做出一個小結論:
如果想對頁面作 Cache 的話,需要作兩件事情:
1. 在頁面的開始加上 @ OutputCache 指示詞.
2. 在 web.config 裡面加掛 OutputCacheModule
可是我接下來想知道的是,如果我用 .Net 去寫作的時候,也需要特別加掛這個 Module 嗎??
再次求助於 mono 的源碼, 從 HttpApplication.cs 開始查找.
我直接搜索 HttpModule, 因為我想知道 HttpApplication 是在何時載入 Module.
HttpApplication 正巧有一個 HttpModuleCollection, 這看來就是 HttpModule 的 Collection.
宣告的名稱為 modcoll, 接著以 modcoll 進行搜索.很快就找到 InitOnce, 這裡以 ModulesConfiguration 對 modcoll 進行了初始化.
接著再查看 ModulesConfiguration 與 HttpModulesConfigurationHandler 的源碼, 至此已經真相大白.
原來如果沒有在 web.config 指定要掛載的 module 的話,只會掛載內定的 DefaultAuthenticationModule.
那麼微軟的 .Net 呢??
以 Reflector 查找同樣的 Class, 並進行 disassembly.
果然也做了一樣的事情,沒指定要掛載的 module 的話,只會掛載內定的 DefaultAuthenticationModule.
補充結論:
除了小結論所提到的事項之外,一定要在 web.config 裡面指定要掛載 OutputCacheModule, 才會更能發揮 Cache 的功效.
參考資料:
*HTTP/1.1: Caching in HTTP
*Caching in ASP.NET
*Page Output Caching, Part 1
*ASP.NET Caching
*mono的源碼
*.Net framework SDK documentation
一般人大概會想,這有甚麼好說的,不就是在頁面加上 @ OutputCache 指示詞(Directive), 這樣就表示會快取頁面.
列在 .Net framework SDK documentation 裡的詳細語法:
<%@ OutputCache Duration="#ofseconds" Location="Any | Client | Downstream | Server | None" Shared="True | False" VaryByControl="controlname" VaryByCustom="browser | customstring" VaryByHeader="headers" VaryByParam="parametername" %>
或許吧,這沒啥大不了的,但我好奇的是,背地裡,.Net 是怎麼幫我完成這件事情的呢??
從 .Net Framework SDK documentation 裡面,幾乎無法找到相關資訊,解釋得很籠統.
於是我只能作這些猜想:
1. .Net 利用 HTTP/1.1 的 Caching 來實現.
2. 內部再使用 Cache hashtable 來避免對後端過於頻繁的存取.例如,取得資料以後,先放到 Cache,如果 Cache 裡面找的到(表示沒過期),就直接拿來顯示,否則的話就再去取資料.
我對第二點沒什麼意見,實際上應該是要這麼作.
但是第一點,我就有問題了. HTTP/1.1 的 Caching 機制對 server 端來說,server 只是送出特定的 HTTP header, 如 Cache-Control, Expires 等等. (參見 HTTP/1.1: Caching in HTTP ).
對 client 來說,他收到這些 header, 怎麼實做,反而是看他自己.如果是坊間抓網頁程式,他可以忽略這些 header, 卯起來抓,那麼這樣就沒有 cache 的效果啦~
另外一點,我感到懷疑的,在他語法裡,可以指定 Any/Client/Downstream/Server, 所謂的 Server, 又是指甚麼意義呢?
就我自己的認知,應該是 Server 在處理的時候,會把整個頁面放到 Cache 裡面.
當遇到有人索取這頁面的時候,就會檢查 Cache, 如果有就直接取出.
所以我查找 Mono 與 .Net 解釋 HttpApplication 的部份,他們都特別指出了 HttpApplication 收到 web request 以後處理的順序:
1. BeginRequest
2. AuthenticateRequest
3. AuthorizeRequest
4. ResolveRequestCache
5. AcquireRequestState
6.PreRequestHandlerExecute
7.PostRequestHandlerExecute
8.ReleaseRequestState
9.UpdateRequestCache
10.EndRequest
特別注意步驟 4 與步驟 9, 他們都提到了 Cache.
p.s. 我覺得 Mono Framework class reference 寫的比較清楚, 參閱 HttpApplication
接著,我又利用 Google 查找相關資訊.
發現有用mono應用程式的 web.config 多半都會加掛 OutputCacheModule 這個 Module.
<httpModules>
<add name="OutputCache" type="System.Web.Caching.OutputCacheModule"/>
</httpModules>
參考 mono 的源碼以後,發現這就是我要找的.
這個 Module 的確做了我推想的事情.
他在 OnResolveRequestCache 事件先依據 FilePath 去檢查 Cache, 如果存在,就直接以 Cache 內保存的內容輸出.
接著在 OnUpdateRequestCache 事件,檢查頁面是否需要被 Cache, 需要的話,就把輸出結果保存到 Cache 中.
Bingo!!
但這是mono的作法, .Net 是否也有同樣的類別呢??
我利用Reflector 這個工具去看 System.Web.dll, 的確, 有 OutputCacheModule 這個 Module.
至此,我們已經解決了我想要解決的問題,並做出一個小結論:
如果想對頁面作 Cache 的話,需要作兩件事情:
1. 在頁面的開始加上 @ OutputCache 指示詞.
2. 在 web.config 裡面加掛 OutputCacheModule
可是我接下來想知道的是,如果我用 .Net 去寫作的時候,也需要特別加掛這個 Module 嗎??
再次求助於 mono 的源碼, 從 HttpApplication.cs 開始查找.
我直接搜索 HttpModule, 因為我想知道 HttpApplication 是在何時載入 Module.
HttpApplication 正巧有一個 HttpModuleCollection, 這看來就是 HttpModule 的 Collection.
宣告的名稱為 modcoll, 接著以 modcoll 進行搜索.很快就找到 InitOnce, 這裡以 ModulesConfiguration 對 modcoll 進行了初始化.
接著再查看 ModulesConfiguration 與 HttpModulesConfigurationHandler 的源碼, 至此已經真相大白.
原來如果沒有在 web.config 指定要掛載的 module 的話,只會掛載內定的 DefaultAuthenticationModule.
那麼微軟的 .Net 呢??
以 Reflector 查找同樣的 Class, 並進行 disassembly.
果然也做了一樣的事情,沒指定要掛載的 module 的話,只會掛載內定的 DefaultAuthenticationModule.
補充結論:
除了小結論所提到的事項之外,一定要在 web.config 裡面指定要掛載 OutputCacheModule, 才會更能發揮 Cache 的功效.
參考資料:
*HTTP/1.1: Caching in HTTP
*Caching in ASP.NET
*Page Output Caching, Part 1
*ASP.NET Caching
*mono的源碼
*.Net framework SDK documentation