- 資訊首頁(yè) > 開(kāi)發(fā)技術(shù) > web開(kāi)發(fā) > ASP >
- ASP緩存技術(shù)詳解
一、何謂ASP緩存/為什么要緩存
當你的web站點(diǎn)采用asp技術(shù)建立的初期,可能感覺(jué)到的是 asp動(dòng)態(tài)網(wǎng)頁(yè)技術(shù)帶來(lái)的便利性,以及隨意修改性、自如的http控制。但是,隨著(zhù)訪(fǎng)問(wèn)量的增加,你一定會(huì )發(fā)現自己的站點(diǎn)訪(fǎng)問(wèn)速度越來(lái)越慢,IIS重新啟動(dòng)得越來(lái)越頻繁。接下來(lái),你一定想優(yōu)化asp,諸如更換性能更優(yōu)異的數據庫、建立索引、編寫(xiě)存儲過(guò)程等等。這些措施有些不需要增加成本壓力,有些則成本壓力很大(譬如叢access到SQL),而且效果還不一定。
面對web訪(fǎng)問(wèn)壓力,我認為最經(jīng)濟的辦法是利用緩存優(yōu)化技術(shù)來(lái)實(shí)現緩解 web的服務(wù)壓力。
Web訪(fǎng)問(wèn)量增加通常意味著(zhù)以下資源需求的快速增長(cháng):
1、 網(wǎng)卡流量增加,需要消耗更多的CPU處理網(wǎng)絡(luò )流量和網(wǎng)絡(luò )I/O線(xiàn)程。
2、 需要更頻繁的打開(kāi)/關(guān)閉數據庫連結(如果使用數據庫技術(shù)—通常asp都會(huì )采用數據庫作為數據存儲),嚴重消耗資源的事物數量、以及事務(wù)相互競爭資源引起的死鎖、會(huì )增加網(wǎng)絡(luò )I/O或者CPU消耗。
3、 如果采用session的話(huà),IIS為了維持狀態(tài),會(huì )消耗更多內存,而內存消耗可能會(huì )引發(fā)物理內存不夠,引起物理內存同輔存間的頻繁交換,從而引起代碼執行的停頓,web響應阻滯。
4、 由于訪(fǎng)問(wèn)的不到及時(shí)響應,會(huì )引起網(wǎng)頁(yè)訪(fǎng)問(wèn)故障,導致用戶(hù)刷新,從而加劇CPU、內存等資源需求。
實(shí)際上,考慮通常的web應用程序,很多時(shí)候的動(dòng)態(tài)代碼執行是不必要的。
二、asp緩存的分類(lèi)
擅自總結,asp的緩存可以分為兩類(lèi):
1、 文件緩存
所謂文件緩存,就是根據邏輯判斷,一段時(shí)間內某個(gè)asp的特定執行將不會(huì )有很大的變動(dòng),因而將內容以靜態(tài)html的形式存放,然后以web的重定向技術(shù)讓客戶(hù)端訪(fǎng)問(wèn)靜態(tài)文件,以達到減少CPU、數據庫資源等的需求。這樣的應用很多,譬如很多論壇就是在回復貼子的時(shí)候將整個(gè)貼子重新生成一個(gè)靜態(tài)文件,然后進(jìn)行重定向的,例如 donews.com的論壇。該成靜態(tài)還有一個(gè)副作用(好處)–可以很容易被google等搜索引擎收錄。一些所謂新聞發(fā)布系統的都采用了此技術(shù)。
2、 文件片斷緩存
所謂文件緩存,也是基于邏輯判斷,某部分數據(通常是需要消耗資源的大容量數據庫查詢(xún)取得)在一定時(shí)間內不會(huì )改變,所以我們可以將這些數據利用文件的形式進(jìn)行存儲,當需要時(shí)候,可以通過(guò)讀取文件來(lái)獲取數據,避免增加數據庫的負擔。例如,我們通常將一些數據以xml格式存儲,然后利用xslt技術(shù)實(shí)現顯示(xml處理通常需要大量CPU資源,所以通常是IE直接讀取xml到客戶(hù)端在客戶(hù)的CPU上進(jìn)行處理)。CSDN的論壇就是這樣處理的。
3、 主存緩存
除此之外,還可以考慮在內存中處理緩存,將需要及時(shí)響應的內容存儲在內存中,一旦訪(fǎng)問(wèn)需求,立即從快速的貯存中輸送出去。如果極大量的訪(fǎng)問(wèn)需求集中在幾個(gè)少量的頁(yè)面或者主存足夠多,我想采用主存緩存一定可以大幅度提高web訪(fǎng)問(wèn)性能。
三、如何實(shí)現/使用緩存
實(shí)現緩存需要考慮以下問(wèn)題:
1、 哪些頁(yè)面會(huì )在短時(shí)間內不會(huì )改變?
分析自己的站點(diǎn),這樣的頁(yè)面很多。譬如一個(gè)站點(diǎn)通常都有新聞資訊類(lèi)的欄目,這些欄目通常都是站點(diǎn)維護人員在一天的某個(gè)時(shí)間發(fā)布資料,之后很少改動(dòng)頁(yè)面。那么這些頁(yè)面就適合于采用靜態(tài)文件緩存。實(shí)際上,所謂新聞發(fā)布系統就是這么做的,那么那也可以參考這些系統的思想改造自己的原有動(dòng)態(tài)asp頁(yè)面。
2、 那些頁(yè)面針對全部訪(fǎng)問(wèn)者都采用同一個(gè)邏輯生成(也就是不區分訪(fǎng)問(wèn)者)。
除了新聞資訊之類(lèi)的欄目所有訪(fǎng)問(wèn)者都看一個(gè)界面外,論壇等消耗資源的應用一般也可以設計成統一邏輯生成(同一個(gè)貼子,張三李四看的都一樣),針對這類(lèi)應用頁(yè)面我們也可以采用靜態(tài)緩存來(lái)實(shí)現。也可以考慮將數據片斷化,利用腳本技術(shù)在服務(wù)器處理能力之外也就是客戶(hù)端瀏覽器進(jìn)行處理。
3、 采用緩存的代價(jià)和收獲。
主要就是“空間換(響應)時(shí)間”。利用緩存技術(shù)將之后頻繁需要的內容進(jìn)行預處理,使之提高web服務(wù)器響應能力,更重要贏(yíng)得訪(fǎng)問(wèn)者的歡心。
代價(jià)就是web空間需求增加,同時(shí)又可能影響到訪(fǎng)問(wèn)效果。
但我認為適當的緩存,是利大于弊的。
4、 那些地方不適宜采用緩存
動(dòng)態(tài)查詢(xún)頁(yè)面,每個(gè)人的查詢(xún)內容不一樣,所以顯示結果不大一樣,所以不大可能將查詢(xún)結果生成緩存,所以采用緩存較為復雜且緩存利用率底下,造成管理成本上什(假設你緩存了1000個(gè)查詢(xún)關(guān)鍵字,那么管理這些關(guān)鍵字同緩存的對應也是麻煩事)。
四、實(shí)例分析
假設一個(gè)建議論壇的原有布局如下:
根目錄下:
default.asp 首頁(yè),一般是精華、推薦之類(lèi)
listBorad.asp 該文件列出全部分欄目的名稱(chēng)和介紹,如果攜帶參數MainBID就表示要列出板塊下的欄目
listThread.asp 該文件如果不攜帶任何參數表示列出全部的貼子,攜帶MainBID表示列出某塊的全部貼子。如果攜帶subBID表示列出具體欄目的貼子。如果攜帶 page參數表示分頁(yè)列出主題。
ViewThread.asp 列出某個(gè)貼子內容。我們假設貼子顯示為一個(gè)發(fā)言,任意跟貼全部列在后面。ID參數為要顯示的貼子。
Reply.asp 回應某個(gè)貼子,攜帶參數Id回應某個(gè)貼子
其它的暫不討論。
以上,我們可以看到,如果全部是采用原始的 ASP/PHP來(lái)做,那幾乎每一個(gè)asp文件的執行都需要數據庫操作,頻繁的查詢(xún),多表查詢(xún)。要知道查詢(xún)數據庫最終會(huì )帶來(lái)性能的下降,響應速度下降,帶給訪(fǎng)問(wèn)者緩慢的瀏覽影響,不利于web的質(zhì)量。更重要的是對于甲乙兩個(gè)人來(lái)將,他們訪(fǎng)問(wèn)ViewThread.asp之類(lèi)的如果ID一致,那么很多時(shí)候他們會(huì )看到同樣的內容(他們的瀏覽器收到的HTML代碼幾乎一樣),但是為了這“同樣的內容”,服務(wù)器需要打開(kāi)數據庫連結、查詢(xún),讀取紀錄,顯示,關(guān)閉紀錄、數據庫連結。。。。以下列的消耗服務(wù)器資源的操作,如果是更多的人來(lái)訪(fǎng)問(wèn),最終的結果是這些人加劇消耗服務(wù)器資源。實(shí)際上,這些為了“同樣的內容”所做的重復勞動(dòng)是可以利用緩存技術(shù)進(jìn)行優(yōu)化避免的。譬如:
在reply.asp提交內容后,我們立即調用生成靜態(tài)的功能,將整個(gè)貼子內容存儲為viewThread_xxxx.htm之類(lèi)的靜態(tài)html文件,再通常情況下訪(fǎng)問(wèn)viewThread.asp?ID=xxxx的時(shí)候,系統自動(dòng) redirect到對應的靜態(tài)文件viewThreadxxxx.htm去。這樣,當一個(gè)貼子沒(méi)有最新發(fā)布時(shí)候,他始終是靜態(tài)內容提供給瀏覽者;一旦有了新的提交,將會(huì )更新到靜態(tài)文件中去,這樣,將會(huì )節省很多次數據庫操作,大大提高響應速度。
listBorad.asp也可以實(shí)施靜態(tài)化。我們可以分析其可能攜帶的參數,將緩存文件名設定為listBoard_xx.htm,在增加新的欄目時(shí)候進(jìn)行更新 listBoard_xxx.htm。listThread.asp也類(lèi)似,只不過(guò)由于其參數更多,所以緩存文件也會(huì )很多。擊若要緩存 listThread.asp? subBID=xxx&page=2,那么對應的靜態(tài)文件是listThread_xxx_p2.htm。default.asp也一樣。
那么如何判斷什么時(shí)候更新?在什么時(shí)機更新?
討論listThread.asp? subBID=xxx&page=2,我們在執行listThread.asp俄時(shí)候提取subID和page,然后探測 listThread_xxx_p2.htm是否存在,如果不存在就調用靜態(tài)生成功能進(jìn)行生成該文件,最終重定向到此靜態(tài)文件。注意,此處的不存在就意味著(zhù)出現了新的內容需要我們進(jìn)行更新。
那如何造成文件不存在呢?刪除。我們在發(fā)表一個(gè)新的貼子、刪除貼子、移動(dòng)貼子的時(shí)候我們可以將類(lèi)似listThread_xxx_p2.htm之類(lèi)的靜態(tài)文件全部刪除。這樣就通知了何時(shí)要進(jìn)行緩存。
現在還剩下一個(gè)問(wèn)題,如何生成靜態(tài)文件?
我們注意到,之前我們提到的“同樣的內容”。我們可以將改造前的default.asp、listThread.asp等拷貝一個(gè)副本,取名為default_d.asp、listThread_2.asp,且在同一個(gè)目錄中(理論上 listThtrad.asp?subID=123同LISTtHREAD_D.ASP?SUBID=123的訪(fǎng)問(wèn)結果會(huì )是同樣的內容),這樣我們在需要生成靜態(tài)文件的邏輯中,通過(guò)WEB訪(fǎng)問(wèn)請求的方式調用改造前的副本,得到html代碼,并存儲為靜態(tài)文件。這個(gè)web請求實(shí)際上相當于在任何真實(shí)瀏覽者訪(fǎng)問(wèn)靜態(tài)內容之前,由服務(wù)器自身現察看將會(huì )輸出的html,然后返回這些代碼,利用文件操作功能存儲為靜態(tài)文件。這樣,緩存文件就在真正瀏覽者之前被創(chuàng )建。
這樣的方案幾乎不觸動(dòng)原來(lái)的布局,幾乎不會(huì )造成因為改造出現404之類(lèi)的錯誤。其次,靜態(tài)文件也會(huì )幫助你的站點(diǎn)容易被被google之類(lèi)的搜索引擎收錄。何樂(lè )而不為?
最后,提醒,通過(guò)web訪(fǎng)問(wèn),asp編程環(huán)境下,很多人采用xmlHTTP組件訪(fǎng)問(wèn),這會(huì )造成很多問(wèn)題。 xmlhttp自身會(huì )cache請求的資源,導致我們通過(guò)此組件請求得到的內容不是最新的,造成邏輯上的混亂。所以,應當選擇xml Server http對象或者winhttp組件來(lái)實(shí)現web請求資源。
使用ASP中的緩存技術(shù)可以很大程度上提高你的網(wǎng)站性能,其實(shí)這些實(shí)現方法是非常的簡(jiǎn)單,它將說(shuō)明如何在服務(wù)器上的緩存是如何工作以及你如何使用一種被稱(chēng)為斷開(kāi)連接的ADO連接技術(shù)。
在介紹這些技術(shù)之前先說(shuō)明一下到底什么是ASP的緩存技術(shù)。
所謂緩存其實(shí)就是在內存中開(kāi)辟一個(gè)用來(lái)保存數據的空間,使用緩存你就不用頻繁的訪(fǎng)問(wèn)你保存在硬盤(pán)上的數據了,靈活的使用緩存你就免去了心疼的看著(zhù)可憐的硬盤(pán)飽受讀數據時(shí)的折磨了。當你一旦執行了一個(gè)查詢(xún)動(dòng)作,并且將查詢(xún)結果放入緩存中后,你就可以很迅速的重復訪(fǎng)問(wèn)這些數據了。而如果你不把數據放入緩存的話(huà),當你再次執行這個(gè)查詢(xún)時(shí),服務(wù)器會(huì )將進(jìn)程耗費在從數據庫中獲取并排序上了。
當數據保存在緩存中時(shí),再次查詢(xún)時(shí)耗費的時(shí)間主要是在顯示數據的時(shí)間上了。
也就是說(shuō),我們不應該把經(jīng)常需要改變的數據放到服務(wù)端的緩存中,我們應該把改變少,但是又需要經(jīng)常訪(fǎng)問(wèn)的數據放到緩存中。
現在我們先討論ASP在服務(wù)端使用緩存的技術(shù),過(guò)會(huì )再討論ASP如何在客戶(hù)端使用
緩存的技術(shù)。
當你有大量的數據(靜態(tài)的,就是說(shuō)變動(dòng)比較少的)需要顯示給客戶(hù)端時(shí),你就可以考慮使用服務(wù)端的緩存技術(shù)了。這種技術(shù)尤其適用于那些顯示風(fēng)格一致性比較強的網(wǎng)站(呵呵,對于非主流的網(wǎng)站可不好用的說(shuō)。)
其實(shí)實(shí)現方法特別的簡(jiǎn)單,大家只要看看下面這個(gè)簡(jiǎn)單的例子就明白了。
這是一個(gè)用來(lái)顯示書(shū)籍分類(lèi)的例子程序
DisplayBooks.ASP文件:
代碼如下:
< %@ LANGUAGE=JavaScript % >
< html >
< body >
< form method=post >
書(shū)籍分類(lèi); < %= getBooksListBox() % >
< p>
< input type=submit >
< %
function getBooksListBox()
{
BooksListBox = Application("BooksListBox")
if (BooksListBox != null) return BooksListBox;
crlf = String.fromCharCode(13, 10)
BooksListBox = "< select name=Books>" + crlf;
SQL = "Select * FROM Books orDER BY Name";
cnnBooks = Server.CreateObject("ADODB.Connection");
cnnBooks.Open("Books", "Admin","");
rstBooks = cnnBooks.Execute(SQL);
fldBookName = rstBooks("BookName");
while (!rstBooks.EOF){
BooksListBox = BooksListBox + " < option>" +
fldBookName + "" + crlf;
rstBooks.MoveNext();
}
BooksListBox = BooksListBox + ""
Application("BooksListBox") = BooksListBox
return BooksListBox;
}
% >
很簡(jiǎn)單把,其實(shí)就是用了很簡(jiǎn)單的Application技術(shù),而且就一句話(huà)的不同:
代碼如下:
Application("BooksListBox") = BooksListBox
你可以驗證一下你就會(huì )發(fā)現服務(wù)器上的請求數量會(huì )降低不少的。這種情況尤其適合與那些更新不是很頻繁的網(wǎng)站內容,例如你一天(或則很長(cháng)時(shí)間)只更新一次。
下面再討論一種客戶(hù)端的緩存技術(shù)這種技術(shù)也叫斷開(kāi)連接的ADO連接技術(shù)(翻譯水平太次,聽(tīng)上去怎么這么別扭)。這種技術(shù)主要使用在用來(lái)保存用戶(hù)個(gè)人信息,例如用戶(hù)的密碼,代號等等上面。它主要使用了ADO的一些屬性。同時(shí)也回答了一些網(wǎng)友曾經(jīng)提到過(guò)的能否在A(yíng)pplication中使用ADO對象的問(wèn)題。解釋不清楚,下面讓代碼來(lái)發(fā)言:
文件GLOBAL.ASA:
代碼如下:
<!--METADATA TYPE="TypeLib" FILE="C:\Program Files\Common
Files\system\ado\msado15.dll"-- >
< SCRIPT LANGUAGE=VBScript RUNAT="Server" >
Sub Application_OnStart
SQL = "Select UserName, Password FROM UserInfo"
cnnUsers = "DSN=User"
Set rsUsers = Server.CreateObject("ADODB.Recordset")
'注意下面這兩句話(huà),就是用來(lái)實(shí)現那個(gè)叫可用的斷開(kāi)連接的ADO技術(shù)
rsCustomers.CursorLocation = adUseClient
rsCustomers.Open SQL, cnnAdvWorks, adOpenStatic, AdLockReadOnly
' 斷開(kāi)RecordSet的和數據庫的連接
rsCustomers.ActiveConnection = Nothing
Set Application("rsCustomers") = rsCustomers
End Sub
文件Users.ASP
代碼如下:
< %
'Clone方法使得每個(gè)用戶(hù)擁有自己的一個(gè)RecordSet集合
Set yourUsers = Application("rsUsers").Clone
Set UserName = yourUsers("UserName")
Set Password = yourUsers("Password")
Do Until yourUsers.EOF
% >
用戶(hù)姓名:< %= UserName % > 用戶(hù)密碼:< %= Password % >
< %
yourUsers.MoveNext
Loop
% >
于緩存的作用,我想我也不用再多說(shuō)了,它的作用已經(jīng)很明顯,特別是對于信息量非常大或是全數據庫頁(yè)面的網(wǎng)站,他能很好地利用主機的內存資源,加速ASP的執行效率,減輕服務(wù)器的負擔,而動(dòng)網(wǎng)在這一方面做得是最突出的,像他現在的dvbbs7.1.0版,更是在緩存的利用上更上一層樓,前后臺大多的操作都和緩存有關(guān),而現在動(dòng)網(wǎng)里用的也就是迷城浪子的緩存類(lèi):
代碼如下:
< %
Class Cls_Cache
'==================使用說(shuō)明====================
'本類(lèi)模塊是動(dòng)網(wǎng)先鋒原創(chuàng ),作者:迷城浪子。如采用本類(lèi)模塊,請不要去掉這個(gè)說(shuō)明。
'公有變量:Reloadtime 過(guò)期時(shí)間(單位為分鐘)缺省值為14400
'MaxCount 緩存對象的最大值,超過(guò)則自動(dòng)刪除使用次數少的對象。缺省值為300
'CacheName 緩存組的總名稱(chēng),缺省值為"Dvbbs",如果一個(gè)站點(diǎn)中有超過(guò)一個(gè)緩存組,則需要外部改變這個(gè)值。
'屬性:Name 定義緩存對象名稱(chēng),只寫(xiě)屬性。
'屬性:value 讀取和寫(xiě)入緩存數據。
'函數:ObjIsEmpty()判斷當前緩存是否過(guò)期。
' 方法:DelCahe(MyCaheName)手工刪除一個(gè)緩存對象,參數是緩存對象的名稱(chēng)。
'========================
Public Reloadtime,MaxCount,CacheName
Private LocalCacheName,CacheData,DelCount
Private Sub Class_Initialize()
Reloadtime=14400 '過(guò)期時(shí)間(單位為分鐘)
CacheName="Dvbbs" '緩存組的總名稱(chēng)
End Sub
Private Sub SetCache(SetName,NewValue)
Application.Lock
Application(SetName) = NewValue
Application.unLock
End Sub
Public Property Let Name(ByVal vNewValue) '緩存對象名稱(chēng)
LocalCacheName=LCase(vNewValue)
End Property
Public Property Let Value(ByVal vNewValue) '讀取和寫(xiě)入緩存數據
If LocalCacheName<>"" Then
CacheData=Application(CacheName"_"&LocalCacheName)
If IsArray(CacheData) Then
CacheData(0)=vNewValue
CacheData(1)=Now()
Else
ReDim CacheData(2)
CacheData(0)=vNewValue
CacheData(1)=Now()
End If
SetCache CacheName"_"&LocalCacheName,CacheData
Else
Err.Raise vbObjectError + 1, "DvbbsCacheServer", " please change the CacheName."
End If
End Property
Public Property Get Value()
If LocalCacheName<>"" Then
CacheData=Application(CacheName"_"&LocalCacheName)
If IsArray(CacheData) Then
Value=CacheData(0)
Else
Err.Raise vbObjectError + 1, "DvbbsCacheServer", " The CacheData Is Empty."
End If
Else
Err.Raise vbObjectError + 1, "DvbbsCacheServer", " please change the CacheName."
End If
End Property
Public Function ObjIsEmpty() '判斷當前緩存是否過(guò)期
ObjIsEmpty=True
CacheData=Application(CacheName"_"&LocalCacheName)
If Not IsArray(CacheData) Then Exit Function
If Not IsDate(CacheData(1)) Then Exit Function
If DateDiff("s",CDate(CacheData(1)),Now()) < 60*Reloadtime Then ObjIsEmpty=False
End Function
Private Sub makeEmpty(SetName) '釋放內存
Application.Lock
Application(SetName) = Empty
Application.unLock
End Sub
Public Sub DelCahe(MyCaheName) '刪除緩存
makeEmpty(CacheName"_"&MyCaheName)
End Sub
End Class
'Set WydCache=New Cls_Cache
'WydCache.Reloadtime=0.5 '定義過(guò)期時(shí)間 (以分鐘為單位)
'WydCache.CacheName="pages" '定義緩存名
'IF WydCache.ObjIsEmpty() Then ''判斷是否可用(包括過(guò)期,與是否為空值)
'Response.write WydCache.Value
'Else
'..................
'BoardJumpList=xxx
'WydCache.Value=BoardJumpList '寫(xiě)入內容
'Response.write BoardJumpList
'End if
'
'mycache.DelCahe(" 緩存名") 刪除緩存
%>
免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng )、來(lái)自本網(wǎng)站內容采集于網(wǎng)絡(luò )互聯(lián)網(wǎng)轉載等其它媒體和分享為主,內容觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如侵犯了原作者的版權,請告知一經(jīng)查實(shí),將立刻刪除涉嫌侵權內容,聯(lián)系我們QQ:712375056,同時(shí)歡迎投稿傳遞力量。
Copyright ? 2009-2022 56dr.com. All Rights Reserved. 特網(wǎng)科技 特網(wǎng)云 版權所有 特網(wǎng)科技 粵ICP備16109289號
域名注冊服務(wù)機構:阿里云計算有限公司(萬(wàn)網(wǎng)) 域名服務(wù)機構:煙臺帝思普網(wǎng)絡(luò )科技有限公司(DNSPod) CDN服務(wù):阿里云計算有限公司 百度云 中國互聯(lián)網(wǎng)舉報中心 增值電信業(yè)務(wù)經(jīng)營(yíng)許可證B2
建議您使用Chrome、Firefox、Edge、IE10及以上版本和360等主流瀏覽器瀏覽本網(wǎng)站