楊永國(guó) 何樹(shù)有
91550部隊(duì) 遼寧 116023
緩沖(caching)技術(shù)在現(xiàn)在的網(wǎng)站建設(shè)中的作用顯得相當(dāng)重要,由于目前的技術(shù)大多是在客戶端瀏覽器發(fā)出請(qǐng)求時(shí),動(dòng)態(tài)的生成可瀏覽網(wǎng)頁(yè),如靜態(tài)HTML網(wǎng)頁(yè),然后將根據(jù)請(qǐng)求生成的網(wǎng)頁(yè)傳回瀏覽器,關(guān)于動(dòng)態(tài)生成網(wǎng)頁(yè)的優(yōu)勢(shì)長(zhǎng)處,想必都有所了解,但是,我們現(xiàn)在要考慮的是如何降低這種技術(shù)帶來(lái)的對(duì)性能的更高要求,這種動(dòng)態(tài)生成技術(shù)的流行使得對(duì)網(wǎng)站的服務(wù)器性能要求較高,是因?yàn)樾枰獙?shí)時(shí)的根據(jù)瀏覽器的請(qǐng)求生成網(wǎng)頁(yè),在生成復(fù)雜網(wǎng)頁(yè)或是頻繁生成相同的頁(yè)面時(shí),問(wèn)題顯得尤為嚴(yán)重。ASP.NET提供了一種在內(nèi)存中開(kāi)辟緩沖區(qū)的機(jī)制,很好地解決了上述問(wèn)題。
ASP.NET為網(wǎng)絡(luò)應(yīng)用程序提供了三種緩沖方式,利用在內(nèi)存中開(kāi)辟的緩沖區(qū)將難以動(dòng)態(tài)生成的頁(yè)面和訪問(wèn)頻率較高的頁(yè)面或是重要的內(nèi)容放入緩沖區(qū),當(dāng)網(wǎng)絡(luò)應(yīng)用程序發(fā)出請(qǐng)求時(shí),將保存的內(nèi)容傳給瀏覽器或是應(yīng)用程序,從而降低了服務(wù)器的工作負(fù)荷。
頁(yè)面輸出緩沖是通過(guò)保存已生成的動(dòng)態(tài)頁(yè)面來(lái)提高請(qǐng)求和響應(yīng)的吞吐量,頁(yè)面緩沖是默認(rèn)允許的,但是,對(duì)于已給定的響應(yīng),輸出是不加以緩沖的,除非是有直接的代碼說(shuō)明為響應(yīng)提供頁(yè)面輸出緩沖。
要為響應(yīng)提供輸出緩沖,需指定緩沖區(qū)中內(nèi)容的有效期和建立有訪問(wèn)權(quán)限的公有緩沖,這可以通過(guò)OutputCache API實(shí)現(xiàn)或是使用@OutputCache指令來(lái)完成,當(dāng)緩沖區(qū)建立以后,第一次的 GET請(qǐng)求會(huì)為緩沖區(qū)開(kāi)辟一個(gè)入口,以后的GET請(qǐng)求或是 HEAD請(qǐng)求都利用這個(gè)入口來(lái)并行地利用輸出緩沖的,只要緩沖區(qū)中留有請(qǐng)求的內(nèi)容,輸出緩沖是利用有效期來(lái)管理緩沖區(qū)中的頁(yè)面的,假設(shè)在緩沖區(qū)中有一個(gè)頁(yè)面被標(biāo)記上有效期并且有效期是 60分鐘,那么當(dāng)這個(gè)頁(yè)面在緩沖區(qū)中停留的時(shí)間超過(guò)60分鐘時(shí)就會(huì)被清理出緩沖區(qū)。如果此時(shí)請(qǐng)求這個(gè)頁(yè)面 那么這個(gè)被清理出緩沖區(qū)的頁(yè)面就會(huì)根據(jù)請(qǐng)求重新創(chuàng)建,然后又一次放入緩沖區(qū)標(biāo)記上新的有效期,這種類型的有效期就是絕對(duì)有效期,也就是頁(yè)面在緩沖區(qū)中被保留的時(shí)間使用指令@OutputCache聲明有效期是:
<%@ OutputCache Duration="60" VaryByParam="none"%>
其中,參數(shù)Duration是以秒為單位的,Duration =“60”指定了有效期是60秒,參數(shù) VaryByParam指明頁(yè)面不會(huì)被GET或是POST指令改變。
聲明有效期的方法還可以通過(guò) HttpCachePolicy類來(lái)實(shí)現(xiàn),由HttpResponse.Cache 屬性可以得到關(guān)于緩沖內(nèi)容的說(shuō)明,比如有效期可否被修改等。
在將網(wǎng)頁(yè)整頁(yè)地放入緩沖區(qū)變得不現(xiàn)實(shí)時(shí),ASP.NET 提供了將網(wǎng)頁(yè)的一部分放入緩沖區(qū)的方法,頁(yè)面部分緩沖。事實(shí)上,頁(yè)面部分緩沖也可以看成頁(yè)面輸出緩沖的一種。使用頁(yè)面部分緩沖,首先要將網(wǎng)頁(yè)中放入緩沖區(qū)的部分分離出來(lái)。在網(wǎng)頁(yè)中使用user control來(lái)說(shuō)明需要緩沖的部分,然后使用@OutputCache 指令標(biāo)記出這些部分,為這些部分確定有效期等屬性。
@OutputCache指令一共有6個(gè)屬性:
Duration:以秒為單位,指定有效期的時(shí)間長(zhǎng)度。這是必須的屬性。因?yàn)槿魏屋敵鼍彌_中的內(nèi)容都要指定有效期,部分緩沖也是一樣。
Location:取值限于枚舉集OutputCacheLocation的ANY、Client、Downstream、Server和None五種枚舉值,默認(rèn)值是ANY。當(dāng)輸出緩沖區(qū)中的 ASP.NET頁(yè)面和用戶控件(user control)時(shí),這個(gè)屬性是必須的。
取Client值時(shí),輸出緩沖定位于發(fā)送請(qǐng)求的客戶瀏覽器。取Server值時(shí),定位于處理請(qǐng)求的服務(wù)器。取 Downstream時(shí),輸出緩沖定位于處理請(qǐng)求的服務(wù)器的下傳流。
如果取ANY,那么上面三種情況都是允許的。取None則請(qǐng)求頁(yè)面的輸出緩沖沒(méi)有被激活,也就是說(shuō)沒(méi)有輸出緩沖可用。
VaryByCustom:當(dāng)VaryByCustom取browser值時(shí),根據(jù)瀏覽器的名字和主要的版本信息改變緩沖區(qū)內(nèi)容。如果屬性值為自定義的字符串,就必須在應(yīng)用程序的Global.asax文檔中重定義HttpApplication.GetVaryByCustomString方法。
VaryByHeader:根據(jù)http頭信息來(lái)改變緩沖區(qū)內(nèi)容。當(dāng)有多重頭信息時(shí),輸出緩沖中會(huì)為每個(gè)指定的HTTP 頭信息保存不同的頁(yè)面文檔。VaryByHeader屬性可以應(yīng)用于緩沖所有http/1.1的緩沖內(nèi)容,不僅僅是ASP.NET的緩沖。
但是 VaryByHeader屬性不支持@OutputCache指令對(duì)user control的標(biāo)記,我們?cè)谶@里只是提一下這個(gè)屬性,已使你能獲得對(duì)@OutputCache指令的全面認(rèn)識(shí)。
當(dāng)瀏覽器請(qǐng)求該頁(yè)面時(shí),創(chuàng)建表單后,將需要緩沖的部分放入緩沖區(qū)。再次請(qǐng)求時(shí),會(huì)判斷請(qǐng)求頁(yè)面中是否有緩沖區(qū)中的頁(yè)面部分,如果判斷結(jié)果是肯定的,那么將創(chuàng)建請(qǐng)求頁(yè)面的其他部分,再加上緩沖區(qū)中的內(nèi)容合成請(qǐng)求頁(yè)面,作為請(qǐng)求的響應(yīng)將頁(yè)面?zhèn)骰貫g覽器。如果請(qǐng)求的頁(yè)面在緩沖區(qū)中沒(méi)有部分緩沖頁(yè)面,那么將再次創(chuàng)建請(qǐng)求頁(yè)面?zhèn)骰貫g覽器,并且再次根據(jù)@OutputCache 指令將user control部分放入緩沖區(qū)中。
除了上述的兩種緩沖方法以外,ASP.NET還提供一種強(qiáng)大的,易于操作的緩沖機(jī)制—數(shù)據(jù)緩沖。數(shù)據(jù)緩沖可以在緩沖區(qū)中為每個(gè)應(yīng)用程序保存各種對(duì)象,這些對(duì)象可以根據(jù)http的請(qǐng)求被調(diào)用。緩沖區(qū)對(duì)于各個(gè)不同的應(yīng)用程序來(lái)說(shuō)是私有的。
在ASP.NET中,數(shù)據(jù)緩沖是通過(guò)Cache類來(lái)實(shí)現(xiàn)的。每個(gè)應(yīng)用程序的緩沖區(qū)實(shí)際上就是Cache類的一個(gè)實(shí)例。每個(gè)應(yīng)用程序的生存周期就是這個(gè)緩沖實(shí)例的生存周期。當(dāng)應(yīng)用程序重新運(yùn)行時(shí)Cache類實(shí)例會(huì)重建。通過(guò)Cache類的方法,可以將數(shù)據(jù)對(duì)象放入緩沖區(qū)中,然后再根據(jù)關(guān)鍵字匹配尋找到并加以利用這些對(duì)象。
Cache類提供了一個(gè)接口,通過(guò)這個(gè)接口可以完全控制要緩沖的內(nèi)容,并且可以規(guī)定緩沖的時(shí)間和方式,一個(gè)簡(jiǎn)單的添加緩沖對(duì)象的例子是:
Cache["keyname"] = keyValue;
然后重新找到這個(gè)對(duì)象,對(duì)這個(gè)對(duì)象的訪問(wèn)是:
keyValue = Cache["keyname"];
if(keyValue != null ) { DisplayData(keyValue); }
在ASP.NET中,主要有三種數(shù)據(jù)緩沖方式:
(1)清除廢物(Scavenging)
當(dāng)系統(tǒng)的內(nèi)存資源緊張時(shí),將最不常用的和不重要的內(nèi)容清除出緩沖區(qū),把內(nèi)存用來(lái)處理頻繁訪問(wèn)的方法稱為清除廢物的緩沖方式。這種方法在緩沖技術(shù)中很常見(jiàn),比如內(nèi)存的緩沖 Cache。這種方法保證了在緩沖區(qū)中的都是重要的和常用的內(nèi)容。
使用這種方法需要在將對(duì)象放入緩沖區(qū)時(shí),為這些對(duì)象標(biāo)記優(yōu)先級(jí)和必需的訪問(wèn)頻率。
當(dāng)需要清除廢物時(shí),根據(jù)對(duì)象的優(yōu)先級(jí)來(lái)判斷哪些是不重要的內(nèi)容,根據(jù)指定的訪問(wèn)頻率判斷哪些內(nèi)容的訪問(wèn)頻率達(dá)不到指定的頻率,然后將這些內(nèi)容清除出內(nèi)存緩沖區(qū)。
實(shí)現(xiàn)上,在使用Cache.Add和Cache.Insert方法向緩沖區(qū)中加入對(duì)象時(shí),可以指定其優(yōu)先級(jí),優(yōu)先級(jí)一共有6種,由小到大依次為:Low、BelowNormal、Normal、AboveNormal、High和NotRemoveable。默認(rèn)值是Normal。
(2)有效期
在使用Add 和Instert方法時(shí),還可以為添加的內(nèi)容標(biāo)上有效期,通過(guò)有效期來(lái)判斷哪些內(nèi)容應(yīng)該被清出緩沖區(qū),這和輸出緩沖的方法類似,超過(guò)有效期的內(nèi)容將會(huì)被清除出去。Add和Insert方法有兩個(gè)參數(shù)來(lái)說(shuō)明這個(gè)方法:
DateTime指定了有效期的時(shí)間,可以是絕對(duì)時(shí)間,比如每天1:00也可以是相對(duì)時(shí)間,比如從創(chuàng)建開(kāi)始的30秒。
TimeSpan 決定了創(chuàng)建對(duì)象的時(shí)間間隔。當(dāng)對(duì)象被清出緩沖區(qū)時(shí),所有對(duì)該對(duì)象的請(qǐng)求都會(huì)得到 null,直到對(duì)象再次創(chuàng)建并加入到緩沖區(qū)中。
(3)關(guān)鍵字匹配
ASP.NET允許根據(jù)外部文件,目錄或其他的緩沖內(nèi)容來(lái)確定要緩沖的內(nèi)容,這樣就造成了一種依賴關(guān)系,可以是依賴外部文件或是依賴關(guān)鍵字。當(dāng)這種依賴關(guān)系改變時(shí),緩沖區(qū)中的內(nèi)容就是無(wú)效的,需要被清出內(nèi)存。這種方法可以有效地更新緩沖區(qū)中的內(nèi)容,尤其是當(dāng)緩沖內(nèi)容的數(shù)據(jù)源被修改時(shí),使用這種方法可以根據(jù)這種依賴關(guān)系來(lái)更新緩沖內(nèi)容,將修改前的數(shù)據(jù)作為無(wú)效內(nèi)容清除出內(nèi)存。
三種方法各有所長(zhǎng),可以根據(jù)不同的需要來(lái)選擇數(shù)據(jù)緩沖的方法,下面對(duì)數(shù)據(jù)緩沖的類Cache類中的Add和Insert方法進(jìn)行實(shí)例分析。
Add 方法的使用示例:
Cache.Add(key, value, null, DateTime.Now.AddSeconds (15),t,
CacheItemPriority.High, CacheItemPriorityDecay.Slow, onRemove);
我們來(lái)逐個(gè)的分析參數(shù)的含義:
key 緩沖內(nèi)容的關(guān)鍵字,用來(lái)引用緩沖內(nèi)容的關(guān)鍵字。value 要放入緩沖的內(nèi)容。dependencies 依賴關(guān)系,當(dāng)依賴關(guān)系發(fā)生改變,內(nèi)容就會(huì)被標(biāo)為無(wú)效的數(shù)據(jù)。絕對(duì)有效期 這里有效期時(shí)間為15秒。時(shí)間間隔 這里用變量來(lái)表示間隔的時(shí)間。優(yōu)先級(jí) 這里取 CacheItemPritorty.BelowNormal即優(yōu)先級(jí)為BelowNormal。訪問(wèn)頻率 這里的頻率是Slow。onRemove 如果采用onRemove ,那么當(dāng)這個(gè)應(yīng)用程序在緩沖區(qū)中的對(duì)象被清出緩沖區(qū)時(shí),會(huì)通報(bào)應(yīng)用程序。
Insert方法也有和Add方法一樣的調(diào)用形式,參數(shù)的含義也相同,除此之外Insert方法還有簡(jiǎn)單的調(diào)用形式:
Insert(key, value);
Insert(key, value , CacheDependency);
Insert(key, value, CacheDependency, DateTime, TimeSpan);
其中CacheDependency是指依賴關(guān)系,DateTime是有效期的時(shí)間,TimeSpan是創(chuàng)建對(duì)象的時(shí)間間隔。
對(duì)數(shù)據(jù)庫(kù)有所了解的程序員來(lái)說(shuō),緩沖這個(gè)概念一定不陌生,為了保證數(shù)據(jù)庫(kù)的安全,數(shù)據(jù)庫(kù)對(duì)數(shù)據(jù)的操作都有緩沖機(jī)制。同理,ASP.NET中為了保證數(shù)據(jù)的安全,也引入了緩沖機(jī)制,極大的提高了網(wǎng)站的安全性。
[1]王超,張鵬.ASP.NET/XML深入編程技術(shù).北京:希望電子出版社.2009.
[2]趙克立.ASP.NET編程培訓(xùn)教程.北京:清華大學(xué)出版社. 2005.
[3]楊云,ASP.NET 典型系統(tǒng)開(kāi)發(fā)詳解.北京:人民郵電出版社. 2005.
[4]徐謖,ASP.NET應(yīng)用與開(kāi)發(fā)教程.北京:清華大學(xué)出版社. 2007.