Session在繁忙站點上使用時有幾個缺陷。繁忙的意思是:站點上每秒有上百的頁面被請求,或者同時有上千的訪問用戶。這個技巧對於那些要求水平擴展強的站點非常重要,也就是指這些站點:它們利用多個服務器完成數據裝載或者處理大量容錯。對於小型站點,比如內部網Intranet,Session是非常值得提倡的。
再次重申,ASP自動地爲每一個首次點擊Web服務器的用戶創建一個Session,每一個Session佔有大約10KB的內存,生存期默認是20分鐘。
使用Session最大的問題不是性能,而是擴展性,Session不能跨越多個Web服務器,一旦在一個服務器上創建了Session,它的數據就駐留在那裏。這意味着,如果在Web上使用Session,你就得爲每一個直接訪問存放Session服務器的用戶請求設計一個策略。這就是將用戶“粘”在Web服務器上,術語“sticky sessions”就來源於此。如果Web服務器遇到障礙,“Stuck”用戶就會丟失他們的Session狀態,因爲Session不保留在磁盤上。
執行粘性session的策略包括硬件與軟件解決方式,比如windows2000高級服務器中的 Network Load Balancing 以及Cisco公司的Local Director,但換取這些要犧牲一定的擴展性。
Application對象也不能跨越服務器。如果需要在Web羣中共享並更新Application數據,就需要使用後臺數據庫。然而,只讀Application數據在Web羣中仍然很有用。
許多對任務要求嚴格的站點都要設立至少2個Web服務器,所以在設計嚴格任務的應用程序時,就需要執行“sticky sessions”,或者簡單地避免使用Session,同時也可以採取其他保存用戶狀態到獨立Web服務器的管理技術。
如果不使用Session,一定要確認將它們關閉,這可以通過Internet服務管理器實現。如果決定使用Session,可以通過幾種方法來最小化它們的影響。
可以將不需要Session的內容(比如幫助畫面,訪問者區域,等等)移動到關閉Session的獨立ASP應用程序中。在基礎頁面上,可以給ASP一個指示,讓它不需要使用Session。將下面的代碼直接加入到ASP頁面的頭部:
$#@60;% @EnableSessionState=False %$#@62;使用這個指示的一個很好? 釋是在框架結構中Session創建了一個有趣的問題。ASP確保在一個時刻只有一個來自Session的請求被執行,這就確保瞭如果瀏覽器爲單個用戶請求多個頁面時,只有一個ASP請求在那時能夠接受Session,如此就避免了存取Session對象時的多線程問題。很不幸,在框架結構中的所有頁面將按照連續的順序顯示出來,一個接一個,而不是同時,所以用戶爲了看到整個框架必須要等很長時間。規則是:如果一定的框架頁面沒有使用Session,就一定要告訴ASP直接使用@EnableSessionState=False。
除了使用Session對象,還有許多其他管理會話狀態的選擇。對於小數量的狀態(小於4KB),我們通常建議使用cookie、查詢字符串變量以及表單隱藏域。對於象購物車一樣的大數量數據,後臺數據庫是最合適的選擇。
技巧7:將代碼裝入COM對象中
如果要編寫很多VBScript或者JScript,爲了提個性能,可以將代碼編寫成COM對象並且編譯使用。編譯代碼基本上比解釋性代碼運行快許多,編譯組件對象可通過“early binding”存取其他COM對象,這比在腳本中調用組件要有效。
這麼做有許多優點:
- COM對象有益於從商業規則中獨立出表達式規則
- COM對象使代碼重用變爲可能
- 許多開發者發現用VB,C++或者Visual J++編寫程序,比ASP更容易調試
技巧8:使用Option Explicit
要在ASP文件中使用Option Explicit定義,並且放置到ASP文件的頭部,從而強迫開發者在使用前聲明所有的變量。許多程序員都認爲這在應用程序調試時非常有用,因爲它避免了產生錯誤類型變量以及偶然創建新變量的可能。
也許更重要的是,聲明的變量要大大快於非聲明變量。
技巧9:拷貝經常使用的數據到腳本變量中
在ASP中存取COM對象時,應該拷貝經常使用的對象數據到腳本變量中,這樣就減少了對COM對象的方法調用。這些調用要比存取腳本變量相對來說費時費力。當存取Collection和Dictionary對象時,使用這項技巧也減少了昂貴的查找操作。
通常,如果要不止一次地存取對象數據,就應將數據放入腳本變量中,對象數據主要也就是Request變量(表單和查詢字符串變量)。比如,站點要傳遞一個叫做UserID的查詢字符串變量,假設它將在一個特殊頁面被引用12次,那麼不需要調用Request(“UserID”)12次,只要在ASP頁面的頭部分配給UserID一個變量,然後在頁面中使用它,這樣做就節省了11次COM方法的調用。
實際中,存取COM屬性或方法是很昂貴的,下面的例子展示了通用代碼:
Foo.bar.blah.baz = Foo.bar.blah.qaz(1)
If Foo.bar.blah.zaq = Foo.bar.blah.abc Then ...
上面的代碼執行後,發生以下事情:
1、變量Foo被當作全局對象
2、變量bar被當作Foo的一員
3、變量blah被當作Foo.bar的一員
4、變量qaz被當作Foo.bar.blah的一員
5、調用Foo.bar.blah.quaz(1)
6、再執行步驟1到3分解baz
7、分解baz做爲Foo.bar.blah的一員
8、再執行步驟1到3分解zaq
9、再執行步驟1到3一次分解abc
如上所示,這非常沒有效率並且很慢。更快的方法是用VBScript編寫代碼,如下:
Set myobj = Foo.bar.blah do the resolution of blah ONCE
Myobj.baz = myobj.qaz(1)
If Myobj.zaq = Myobj.abc Then ...
如果使用VBScript 5.0或者更高版本,可以用With語句編寫:
With Foo.bar.blah .baz = .qaz(1) If .zaq = .abc Then ... ... End With
注意:這個技巧也可以應用在VB編程中。
技巧10:避免再定義數組
爭取不要再定義數組。考慮到性能問題,如果機器的物理內存大小不夠,最好按最差情況或者最佳情況設置數組的初始尺寸,需要時再重新定義。
下面的代碼展示了Dim和Redim的使用:
< %
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"
% >
簡單地定義數組初始尺寸爲合適的大小是非常好的,而不要用Redim加大數組。這麼做也許浪費了一些內存(如果沒有完全地使用空間),但是贏得了速度。