技巧|效能 技巧 1:將經常使用的資料緩衝在 Web 服務器上
典型的 ASP 頁從後端資料存放區中檢索資料,然後將結果轉換成超文字標記語言 (HTML) (HTML)。無論資料庫的速度如何,從記憶體中檢索資料總要比從後端資料存放區中檢索資料快得多。從本地硬碟讀取資料通常也比從資料庫中檢索資料更快。因此,通常可以將資料緩衝在 Web 服務器上(儲存在記憶體或磁碟中),來提高效能。 緩衝是傳統的以空間換取時間的做法。如果您緩衝的內容正確,那麼您可以看到效能會有顯著的提高。為使緩衝有效,必須儲存那些經常重複使用的資料,且要重新計算這些資料需要(適度)大的開銷。如果緩衝的都是些陳舊的資料,就會造成記憶體浪費。 不經常發生改變的資料是很好的緩衝候選資料,因為您不必擔心隨著時間的遷移該資料與資料庫同步的問題。組合框列表、參考資料表、DHTML 片段、擴充標記語言 (XML) 字串、功能表項目和網站組態變數(包括資料來源名稱 (DSN)、網際網路通訊協定 (IP) (IP) 地址和 Web 路徑)都是很好的緩衝候選內容。注意您可以快取資料的“表示”,而不快取資料本身。如果 ASP 頁很少更改,且緩衝的開銷也很大(例如,整個產品目錄),則應考慮事先產生 HTML,而不是在響應每個請求時重新顯示。 應將資料緩衝在哪裡,有哪些緩衝策略?通常,資料緩衝在 Web 服務器的記憶體或磁碟中。
技巧 2: 將經常使用的資料緩衝在 Application 或 Session 對象中
ASP Application 和 Session 對象為將資料緩衝在記憶體中提供了方便的容器。您可以將資料指派到 Application 和 Session 對象中,這些資料在 HTTP 調用之間保留在記憶體中。Session 資料是按每個使用者分別儲存的,而Application 資料則在所有使用者之間共用。 什麼時候將資料裝載到 Application 或 Session 中呢?通常,資料是在啟動Application 或 Session 時裝載。要在 Application 或 Session 啟動過程中裝載資料,應將適當的代碼分別添加到Application_OnStart() 或 Session_OnStart() 中。這些函數應在 Global.asa 中,如果沒有,則可以添加這些函數。還可以在第一次需要時裝函數應在 Global.asa 中,如果沒有,則可以添加這些函數。還可以在第一次需要時裝載該資料。為此,在 ASP 頁中添加一些代碼(或編寫一個可重複使用的指令碼函數),以檢查資料是否存在,如果不存在,就裝載資料。這是一個傳統的效能技術,稱為“惰性計算” - 在您知道需要某一個值以前不計算該值。例如: 可以為所需要的每個資料區塊編寫類似的函數。 應以什麼格式儲存資料?可以儲存任何變體類型,因為所有指令碼變數都是變體型。例如,您可以儲存字串、整數或數組。通常,您將以這些變數類型之一儲存 ADO 記錄集的內容。要從 ADO 記錄集擷取資料,您可以手工將資料複製到 VBScript 變數,一次一個欄位。使用一個 ADO 記錄集持久函數 GetRows()、GetString() 或Save()(ADO 2.5),可加快速度且更容易一些。 在適當的條件下,可以將 ADO 記錄集本身緩衝在 Application 或 Session 範圍中。有兩個警告:
必須將 ADO 標記為自由線程
必須使用中斷連線的記錄集。
如果不能保證滿足這兩個要求,則不要緩衝 ADO 記錄集。在下面的“非敏捷組件”和“不要緩衝串連”技巧中,我們將討論將 COM 物件儲存在 Application 或 Session 範圍中的危險性。 當您將資料存放區在 Application 或 Session 範圍時,資料將保留在那裡,直到您以編程方式改變它、Session 到期或 Web 應用程式重新啟動為止。如果資料需要更新怎麼辦?要手工強制對 Application 資料進行更新,您可以訪問只有管理員才可訪問的 ASP 頁來更新資料。或者,您可以通過函數定期自動重新整理資料。下面例子儲存帶有快取資料的時間戳記,並隔一段時間後重新整理資料。 Session[/b] 或 Application對象中緩衝大的數組不是一個好的做法。在訪問數組的任何元素之前,指令碼語言的文法要求必須臨時複製整個數組。數組能快速查尋和儲存在記憶體中是鄰近的關鍵資料對。索引一個詞典比索引一個數組要慢得多。應針對您的實際情況,選擇提供最佳效能的資料結構。
技巧 3:將資料和 HTML 緩衝在 Web 服務器的磁碟上
有時,資料可能太多,無法都緩衝在記憶體中。“太多”只是一個說法,這要看您想消耗多少記憶體,以及需緩衝的項目數和檢索這些項目的頻率。在任何情況下,如果資料太多多少記憶體,以及需緩衝的項目數和檢索這些項目的頻率。在任何情況下,如果資料太多而無法都緩衝在記憶體中,則考慮將資料以文本或 XML 檔案快取在 Web 服務器的硬碟上。可以同時將資料緩衝在磁碟和記憶體中,為您的網站建立最適宜的緩衝策略。 注意當測量單個 ASP 頁的效能時,檢索磁碟上的資料可能不一定要比從資料庫檢索資料更快。但緩衝會降低資料庫和網路上的負載。在高負載的情況下,這樣做可大大改善總體輸送量。當緩衝開銷很大的查詢結果(如多表聯結或複合預存程序)或大的結果集時,這是非常有效。與往常一樣,要測試一下幾種方案的優劣。 ASP 和 COM 提供一些建立基於磁碟的緩衝方案的工具。ADO 記錄集 Save() 和 Open() 函數儲存和裝載磁碟中的記錄集。可以使用這些方法重新編寫上面 Application 資料緩衝技巧中的程式碼範例,用檔案的 Save() 代替寫到Application 對象中的代碼。 有一些其它組件可以用於檔案:
Scripting.FileSystemObject 可使您建立、讀和寫檔案。
與 Internet Explorer 一起提供的 Microsoft® XML 解析器 (MSXML) 支援儲存和裝載 XML 文檔。
LookupTable 對象(例如,用在 MSN 上)是從磁碟裝載簡單列表的最好選擇。最後,應考慮將資料的表示緩衝在磁碟上,而不是資料本身。預先轉換的 HTML 可以用.htm 或 .asp 檔案儲存體在磁碟上,超級連結可以直接指向這些檔案。可以使用商用工具,如 XBuilder,或 Microsoft® SQL Server™ Internet 發布功能將產生HTML 的過程自動化。或者,您可以將 HTML 程式碼片斷放在 .asp 檔案中。還可以使用FileSystemObject 從磁碟讀取 HTML 檔案,或使用 XML 儘早轉換。
技巧 4:避免將非敏捷的組件緩衝在 Application 或 Session 對象中
儘管將資料緩衝在 Application 或 Session 對象中是一個好的做法,但緩衝 COM 物件卻有嚴重的陷阱。通常,人們傾向於將經常使用的 COM 物件緩衝到 Application 或 Session 對象中。很遺憾,許多 COM 物件(包括所有以 Visual Basic 6.0 或更低版本ession 對象中。很遺憾,許多 COM 物件(包括所有以 Visual Basic 6.0 或更低版本編寫的對象)當儲存在 Application 或 Session 對象時,會引起嚴重的瓶頸。 具體來講,當任何不敏捷的組件緩衝在 Session 或 Application 對象時,將引起效能瓶頸。敏捷的組件是被標記為 ThreadingModel=Both 的組件,它聚集 Free-threaded marshaler (FTM);或被標記為ThreadingModel=Neutral 的組件。(Neutral 模型是 Windows® 2000 和 COM+ 的新增模型。) 下列組件不是敏捷的:
自由線程的組件(除非它們聚集 FTM)。
Apartment 執行緒元件。
單執行緒元件。
配置的組件(Microsoft Transaction Server (MTS)/COM+ 庫和伺服器程式包/應用程式)不是敏捷的,除非它們是 Neutral 線程。Apartment 執行緒元件和其它非敏捷的組件在頁範圍內是最適合的(即,它們在單個 ASP 頁上建立和銷毀)。 在 IIS 4.0 中,被標記為ThreadingModel=Both 的組件被認為是敏捷的。在 IIS 5.0 中,只有這一點還不夠。組件必須不僅被標記 Both,還必須聚集 FTM。有關敏捷性的文章講述了如何使以 Active Template Library 編寫的 C++ 組件聚集 FTM。要注意如果組件緩衝介面指標,那麼那些指標本身必須是敏捷的,或必須儲存在 COM 共用介面表 (GIT) 中。如果您不能重新編譯 Both 執行緒元件以聚集 FTM,那麼您可以將組件標記為 ThreadingModel=Neutral。或者,如果您不想讓 IIS 執行敏捷性檢查(因此,您可以允許非敏捷的組件儲存在Application 或 Session 範圍中),您可以在設定資料庫中將 AspTrackThreading Model 設定為 True。不建議更改 AspTrackThreadingModel。 如果您想將以Server.CreateObject 建立的非敏捷的組件儲存在 Application 對象中,IIS 5.0 將出現一個錯誤。您可以在Global.asa 中使用 避免這一錯誤,但不建議這樣做,因為這會導致彙集和序列化,關於這一點將在下面講述。 如果您緩衝非敏捷的組件會出現什麼毛病?緩集和序列化,關於這一點將在下面講述。 如果您緩衝非敏捷的組件會出現什麼毛病?緩
存在 Session 對象中的非敏捷的組件將 Session 鎖定於 ASP 工作者線程。ASP 維護一個工作者線程池來處理請求。通常情況下,一個新請求總是由第一個可用的工作者線程來處理。如果 Session 被鎖定於一個線程,那麼請求必須等到其相關的線程可用為止。
將非敏捷的組件儲存在Application 範圍對效能的影響甚至更壞。ASP 必須建立一個特殊的線程運行儲存在
Application 範圍中的非敏捷組件。這會有兩個結果:所有調用都必須彙集到此線程,且所有調用都排成長隊。“彙集”的意思是參數必須儲存在記憶體的共用地區;執行一個開銷很大的到特殊線程的環境切換;動作項目的方法;將結果彙集到共用地區;執行另一個開銷很大的環境切換,將控制返回到原始的線程。“序列化”意思是指每次只運行一個方法。兩個不同的 ASP 工作者線程不能同時在共用組件上執行多個方法。這樣就杜絕了並發性,特別是在多處理器電腦上。更糟的是,所有非敏捷的 Application 範圍的組件共用一個線程(主機 STA),因此序列化的影響甚至更顯著。 如之奈何?下面是一些一般的規則。如果您使用 Visual Basic (6.0) 或更早版本編寫對象,那麼不要將它們緩衝在 Application 或 Session 對象中。如果您不知道對象的執行緒模式,不要緩衝它。不要緩衝非敏捷的對象,而應在每個頁面建立和釋放它們。對象直接在 ASP 工作者線程上運行,因此沒有彙集或序列化。如果 COM 物件在 IIS 伺服器上運行,且如果它們不花長時間初始化和刪除,效能尚可。注意單線程對象不應該這樣使用。小心 - VB 可建立單線程對象!如果