改善ASP性能與外觀的技巧集錦(中)
發(fā)表時間:2024-02-18 來源:明輝站整理相關(guān)軟件相關(guān)文章人氣:
[摘要]技巧 9:進程外執(zhí)行過程以性能換取可靠性 ASP 和 MTS/COM+ 兩者都有配置選項,可使您兼顧可靠性和性能。當建立和部署應(yīng)用程序時,應(yīng)知道如何兼顧兩者的性能。ASP 選項可以配置 ASP 應(yīng)用程序,以便以三種方法之一運行。在 IIS 5.0 中,引入了“隔離級”這一術(shù)語以說明這些選項。這三個...
技巧 9:進程外執(zhí)行過程以性能換取可靠性
ASP 和 MTS/COM+ 兩者都有配置選項,可使您兼顧可靠性和性能。當建立和部署應(yīng)用程序時,應(yīng)知道如何兼顧兩者的性能。ASP 選項可以配置 ASP 應(yīng)用程序,以便以三種方法之一運行。在 IIS 5.0 中,引入了“隔離級”這一術(shù)語以說明這些選項。這三個隔離級分別是低級、中級和高級:
低級隔離:這在 IIS 的所有版本中都得到支持,且是最快的。它在 Inetinfo.exe 中運行 ASP,Inetinfo.exe 是主要 IIS 進程。如果 ASP 應(yīng)用程序崩潰,IIS 也會崩潰。(要在 IIS 4.0 下重新啟動 IIS,Web 站點管理員應(yīng)使用諸如 InetMon 之類的工具監(jiān)視站點,如果服務(wù)器發(fā)生故障,應(yīng)啟用批處理文件以重新啟動服務(wù)器。IIS 5.0 引入了可靠的重新啟動,該方法可使發(fā)生故障的服務(wù)器自動重新啟動。)
中級隔離:IIS 5.0 引入了這個新的級別,它被稱為進程外級別,因為 ASP 在 IIS 進程之外運行。在中級隔離中,被配置作為中級隔離運行的所有 ASP 應(yīng)用程序都共享一個進程空間。這就減少了在一臺服務(wù)器運行多個進程外 ASP 應(yīng)用程序所需要的進程數(shù)量。中級隔離是 IIS 5.0 中的默認隔離級別。
高級隔離:在 IIS 4.0 和 IIS 5.0 中支持這一級別,高級隔離也是進程外的。如果 ASP 崩潰,Web 服務(wù)器并不會崩潰。下次 ASP 請求時,ASP 應(yīng)用程序就會自動重新啟動。在高級隔離中,配置作為高級隔離運行的每個 ASP 應(yīng)用程序都在其自有進程空間中運行。這樣做可保護 ASP 應(yīng)用程序彼此之間不相互干擾。其缺點是它要求每個 ASP 應(yīng)用程序都要有一個單獨的進程。當在一臺服務(wù)器上必須運行許多應(yīng)用程序時,系統(tǒng)開銷就會大大增加。
哪個選項最好的呢?在 IIS 4.0 中,進程外運行將顯著降低性能。在 IIS 5.0 中,做了許多改進,將進程外運行 ASP 應(yīng)用程序所產(chǎn)生的開銷降到最低限度。事實上,在絕大多數(shù)測試中,IIS 5.0 中的 ASP 進程外應(yīng)用程序比 IIS 4.0 中的進程內(nèi)應(yīng)用程序運行得更快。不管怎樣,在兩個平臺上,進程內(nèi)(低隔離級)性能最佳。但是,如果訪問率相對較低或最大吞吐量較低,低隔離級的優(yōu)勢不太明顯。因此,在您每一 Web 服務(wù)器每秒鐘需要數(shù)百或成千上萬頁面時,才會覺得有必要設(shè)置低隔離級。與往常一樣,應(yīng)對多種配置進行測試,確定您要采取哪一種折衷方案。
注意 當您運行 ASP 進程外應(yīng)用程序時(中級或高級隔離),它們在 NT4 中的 MTS 和在 Windows 2000 中的 COM+ 中運行。即,在 NT4 中它們在 Mtx.exe 中運行;而在 Windows 2000 中,它們在 DllHost.exe 中運行。您可以在任務(wù)管理器中看到這些進程在運行。您還可以看到 IIS 如何為進程外 ASP 應(yīng)用程序配置 MTS 程序包或 COM+ 應(yīng)用程運行。您還可以看到 IIS 如何為進程外 ASP 應(yīng)用程序配置 MTS 程序包或 COM+ 應(yīng)用程序。
COM 選項
COM 組件也有三種配置選項,雖然與 ASP 選項不完全類似。COM 組件可以是“未配置的”、配置為庫應(yīng)用程序或配置為服務(wù)器應(yīng)用程序。“未配置的”意思是指組件沒有注冊COM+。組件將在調(diào)用程序的進程空間運行,那就是說,它們是“進程內(nèi)的”。庫應(yīng)用程序也是進程內(nèi)的,但使用 COM+ 的服務(wù),包括安全、事務(wù)和上下文支持。服務(wù)器應(yīng)用程序被配置為在它們自有的進程空間內(nèi)運行。
您可以看到未配置的組件比庫應(yīng)用程序略有一些優(yōu)勢。庫應(yīng)用程序比服務(wù)器應(yīng)用程序的性能優(yōu)點更大。這是因為庫應(yīng)用程序與 ASP 在同一進程內(nèi)運行,而服務(wù)器應(yīng)用程序在它們的自有進程內(nèi)運行。進程間的調(diào)用比進程內(nèi)調(diào)用開銷更大。而且,當在進程之間傳遞諸如記錄集之類的數(shù)據(jù)時,必須在兩個進程之間復制所有的數(shù)據(jù)。
陷阱!當使用 COM 服務(wù)器應(yīng)用程序時,如果您在 ASP 和 COM 之間傳遞對象,要確保對象執(zhí)行“按值匯集”或 MBV。執(zhí)行 MBV 的對象將它們自己從一個進程復制到另一個進程。這比下面一種方法好,采用這種方法時,對象仍在創(chuàng)建者的進程中,另外一個進程反復地調(diào)用創(chuàng)建進程以使用該對象。切斷連接的 ADO 記錄集將“按值匯集”,連接的記錄集則不然。Scripting.Dictionary 不執(zhí)行 MBV,且不在進程之間傳遞。
最后,VB 程序員請注意:MBV 不通過傳遞參數(shù) ByVal 獲得。MBV 由原始的組件作者執(zhí)行。怎么辦?
如果讓我們建議一個兼顧性能與可靠性的合理配置,它們應(yīng)是如下的配置:
在 IIS 4.0 中,使用 ASP 低隔離級別,使用 MTS 服務(wù)器程序包。
在 IIS 5.0 上,使用 ASP 的中隔離級,并使用 COM+ 庫應(yīng)用程序。
這些是非常一般的原則,主機服務(wù)公司一般情況下以中或高隔離級運行 ASP,而單用途的 Web 服務(wù)器可以以低隔離級運行。衡量各種利弊,并自己決定哪個配置更能符合您的需要。
技巧 10:使用顯式選項
在 .asp 文件中應(yīng)使用 Option Explicit。此指令放在 .asp 文件的最上面,它強制開發(fā)人員聲明要使用到的所有變量。許多程序員認為這種方法對于調(diào)試應(yīng)用程序很有幫助,因為這種方法避免了鍵錯變量名和誤建新變量的可能性(例如,將 MyXMLString=) 錯寫成 MyXLMString=...。
更重要的一點也許是,聲明的變量比未聲明的變量速度更快。由此,腳本在運行時每次用到未聲明的變量時,按名稱引用它。另一方面,聲明的變量是有順序的,要么以編譯時間,要么以運行時間。以后,聲明的變量都按此順序引用。因為 Option Explicit 強制變量聲明,它能確保聲明所有變量,因此訪問的速度也很快。
技巧 11:在子例程和函數(shù)中使用局部變量
局部變量是那些在子例程和函數(shù)內(nèi)聲明的變量。在函數(shù)或子例程內(nèi),局部變量訪問比全局變量訪問更快。局部變量的使用也會使代碼更清晰,因此應(yīng)盡量使用局部變量。
技巧 12:將經(jīng)常使用的數(shù)據(jù)復制到腳本變量中
當訪問 ASP 中的 COM 對象時,應(yīng)將經(jīng)常使用的對象數(shù)據(jù)復制到腳本變量中。這樣做可減少 COM 方法調(diào)用,因為 COM 方法調(diào)用與訪問腳本變量相比,開銷相對較大。當訪問Collection 和 Dictionary 對象時,這種技術(shù)也會減少開銷很大的查找。
一般來說,如果您打算不止一次訪問對象數(shù)據(jù),那么就應(yīng)將數(shù)據(jù)放到腳本變量中。這種優(yōu)化的主要目標是 Request 變量(Form 和 QueryString 變量)。例如,您的站點可傳遞一個名為 UserID 的 QueryString 變量。假設(shè)此 UserID 在特定頁面上被引用 12 次。可以無須調(diào)用 Request(?UserID?) 12 次,而是在 ASP 頁面最上面將 UserID 指派到?梢詿o須調(diào)用 Request(?UserID?) 12 次,而是在 ASP 頁面最上面將 UserID 指派到一個變量。然后在該頁面自始至終使用該變量。這樣就省去了 11 次 COM 方法調(diào)用。實際上,訪問 COM 屬性或方法的開銷并沒有那么大。
技巧 13:避免重新確定數(shù)組的維數(shù)
應(yīng)盡量避免 Redim 數(shù)組。就性能而言,如果計算機的物理內(nèi)存大小有限,最好將數(shù)組的初始維數(shù)設(shè)置為其最不利的情況 - 或?qū)⒕S數(shù)設(shè)置為其最佳的情況,然后再按需要重新確定維數(shù)。這并非意味著,如果知道您不需要內(nèi)存時,就隨便分配幾兆字節(jié)的內(nèi)存。
下面的代碼給您顯示使用 Dim 和 Redim 不當?shù)那樾巍?
<%
Dim MyArray()
Redim MyArray(2)
MyArray(0) = ?hello?
MyArray(1) = ?good-bye?
MyArray(2) = ?farewell?
...
' some other code where you end up needing more space happens, then ...
Redim Preserve MyArray(5)
MyArray(3) = ?more stuff?
MyArray(4) = ?even more stuff?
MyArray(5) = ?yet more stuff?
MyArray(5) = ?yet more stuff?
%>
最好一開始就將數(shù)組的初始大小 Dim 正確(在本例中,是 5)比 Redim 數(shù)組使其更大好得多。您可能浪費一些內(nèi)存(如果您沒有使用所有的元素),但獲得的好處是速度變得更快。
技巧 14:使用響應(yīng)緩沖
您可以通過啟用“響應(yīng)緩沖”,將要輸出的一整頁緩沖起來。這樣就將寫到瀏覽器的量減到最少,從而改善總體性能。每個寫操作都會產(chǎn)生很大的系統(tǒng)開銷(在 IIS 中以及在通過網(wǎng)絡(luò)發(fā)送的數(shù)據(jù)量方面),因此寫操作越少越好。由于其啟動慢且使用 Nagling 算法(用來減輕網(wǎng)絡(luò)塞車情況),TCP/IP 在發(fā)送一些大的數(shù)據(jù)塊時比必須發(fā)送許多小的數(shù)據(jù)塊時的效率高得多。
有兩個方法啟用響應(yīng)緩沖。
第一種,您可以使用 Internet Services Manager 為整個應(yīng)用程序啟用響應(yīng)緩沖。我們建議采用這種方法,在 IIS 4.0 和 IIS 5.0 中默認為新的ASP 應(yīng)用程序啟用響應(yīng)緩沖。
第二種,可以在每個 ASP 頁面的接近頂端的地方加入下面的代碼行,從而啟用響應(yīng)緩沖:
<% Response.Buffer = True %>
此代碼行必須在任何響應(yīng)數(shù)據(jù)被寫到瀏覽器之前執(zhí)行(即,在任何 HTML 出現(xiàn)在 ASP 腳本之前以及在使用 Response.Cookies 集合設(shè)置任何 Cookies 之前)。一般來說,最好為整個應(yīng)用程序啟用響應(yīng)緩沖。這樣,您就不必在每個頁面最上面寫入上述的代碼行。
Response.Flush
關(guān)于響應(yīng)緩沖有一個常見的抱怨,就是用戶感覺到 ASP 頁面的響應(yīng)速度很慢(即使整個響應(yīng)時間得到改進),因為他們必須等到整個頁面生成,然后他們才能看到東西。對于響應(yīng)時間得到改進),因為他們必須等到整個頁面生成,然后他們才能看到東西。對于運行時間長的頁面,您可以設(shè)置 Response.Buffer = False,禁用響應(yīng)緩沖。但是,一個更好的策略是利用 Response.Flush 方法。這種方法將 ASP 轉(zhuǎn)換的所有 HTML 送到瀏覽器。例如,在轉(zhuǎn)換 1,000 行的表的前 100 行之后,ASP 可以調(diào)用 Response.Flush,強制將轉(zhuǎn)換的結(jié)果送到瀏覽器,這樣可使用戶在其余的行準備好之前看到頭 100 行。這種技術(shù)可以將響應(yīng)緩沖與瀏覽器逐漸顯示數(shù)據(jù)完美地結(jié)合在一起。(注意在上面的 1,000 行表的舉例中,許多瀏覽器在它們看到關(guān)閉 </table>標記之前不會開始顯示表。檢查您的目標瀏覽器是否支持。為避免這種情況,將表分成多個具有較少行的表,并在每個表之后調(diào)用 Response.Flush。較新版本的 Internet Explorer在表完全下載之前就開始顯示表,如果您指定表列寬,顯示速度就會特別快,這樣做可避免強制 Internet Explorer 通過測量每個單元格的內(nèi)容寬度來計算列寬。)另一個關(guān)于響應(yīng)緩沖的常見的抱怨是,當產(chǎn)生非常大的頁面時,將占用許多服務(wù)器內(nèi)存。撇開產(chǎn)生大頁面的方法不談,這種問題也可通過巧妙使用 Response.Flush 來加以解決。
技巧 15:批處理內(nèi)嵌腳本和 Response.Write 語句
VBScript 語法 <% = expression %>將“expression”的值寫到 ASP 輸出流中。如果響應(yīng)緩沖未啟用,那么執(zhí)行其中的每一條語句,都會以許多小的數(shù)據(jù)包通過網(wǎng)絡(luò)將數(shù)據(jù)寫到瀏覽器中。這樣速度很慢。而且穿插執(zhí)行少量的腳本和 HTML,將引起腳本引擎和HTML 之間的切換,從而降低性能。因此,使用下面的技巧:使用 Response.Write 調(diào)用代替捆綁緊密的內(nèi)嵌表達式。當禁用響應(yīng)緩沖時,這一技巧的效果特別大。最好啟用響應(yīng)緩沖,然后看批處理 Response.Write 是否有助于提高性能。
技巧 16:如果頁面需要很長時間才能完成,那么執(zhí)行前使用 Response.IsClientConnected
如果用戶性急,他們可能會在您開始執(zhí)行他們的請求之前,就會放棄 ASP 頁面。如果他們單擊刷新或移到服務(wù)器上的另一個頁面,在 ASP 請求隊列的末尾就有一個新的請求等候,在隊列的中間有一個斷開連接的請求。當服務(wù)器的負載很高時(因此請求隊列就會很長,響應(yīng)時間也會相應(yīng)地變長),就會經(jīng)常發(fā)生這種情況,這樣只能使情況變得更糟。如果用戶不再連接,執(zhí)行 ASP 頁面(特別是慢的、大的 ASP 頁面)已沒有任何意義
。您可以使用 Response.IsClientConnected 屬性檢查這一情況。如果它返回 False,則應(yīng)調(diào)用 Response.End 并放棄頁的其余部分。事實上,IIS 5.0 已將這一做法編為程序 - 每當 ASP 即將執(zhí)行新請求時,它就會檢查請求在隊列中已等候了多長時間。如果已經(jīng)在那里等候了多于 3 秒鐘,ASP 將檢查客戶機是否仍處于連接狀態(tài),如果沒有連接已經(jīng)在那里等候了多于 3 秒鐘,ASP 將檢查客戶機是否仍處于連接狀態(tài),如果沒有連接,就立即終止請求。您可以在配置數(shù)據(jù)庫中使用 AspQueueConnectionTestTime 設(shè)置將超時時間由 3 秒調(diào)整為其它值。如果頁面要花很長時間才能執(zhí)行完,也可以不時地檢查 Response.IsClientConnected。當啟用了響應(yīng)緩沖時,最好不時地執(zhí)行 Response.Flush,以用戶知道,正在發(fā)生什么事。
注意 在 IIS 4.0 上,除非先執(zhí)行了 Response.Write,否則 Response.IsClientConnected 就不能正常工作。如果啟用了緩沖,您也必須執(zhí)行 Response.Flush。在 IIS 5.0上,卻沒有必要這樣做,- Response.IsClientConnected 工作正常。在任何情況下,Response.IsClientConnected 都會有一些開銷,因此只有在一個操作至少要花(比方說) 500 毫秒(如果您想維持每秒鐘數(shù)十頁的吞吐量,這是一個很長的時間)才使用它。
經(jīng)驗表明,不要每次重復執(zhí)行緊密循環(huán)時都調(diào)用它,如顯示表的許多行時 - 每隔二十或五十行調(diào)用一次可能比較合適。
技巧 17:使用 <OBJECT>標記例示對象
如果要引用不在所有代碼路徑(特別是服務(wù)器或應(yīng)用程序作用域的對象)中使用的對象,使用 Global.asa 中 <object runat=server id=objname> 標記聲明它們,而不使用Server.CreateObject 方法。Server.CreateObject 能立即創(chuàng)建對象。如果以后不再使用該對象,您就浪費了資源。<object id=objname> 標記聲明 objname,但在其方法或?qū)傩缘谝淮问褂靡郧,不會?chuàng)建 objname。這又是一個惰性計算的例子。
技巧 18:對于 ADO 和其它組件使用 TypeLib 聲明
當使用 ADO 時,開發(fā)人員經(jīng)常加入 adovbs.txt,以訪問 ADO 的各種常量。在要使用常量的每個頁面中必須包含此文件。此常量文件相當大,給每個 ASP 頁面的編譯時間和腳技巧 18:對于 ADO 和其它組件使用 TypeLib 聲明本大小增加了許多系統(tǒng)開銷。IIS 5.0 引入了綁定到組件類型庫的功能。這可使您引用類型庫一次,并將其用在每個ASP 頁面上。每個頁面不會產(chǎn)生編譯常量文件的開銷,且組件開發(fā)人員不必建立VBScript#_include 文件以在 ASP 上使用。要訪問 ADO TypeLib,將下面一條語句放在 Global.asa 中。
<!-- METADATA NAME=?Microsoft ActiveX Data Objects 2.5 Library?
TYPE=?TypeLib? UUID=?{00000205-0000-0010-8000-00AA006D2EA4}? -->
或
<!-- METADATA TYPE=?TypeLib?
FILE=?C:\Program Files\Common Files\system\ado\msado15.dll? -->