[摘要] 本文主要從ASP.NET在網(wǎng)站開發(fā)中的性能及其安全性入手,介紹了如何將Web應(yīng)用程序運行得越來越快,并且能夠得到擴(kuò)展以處理更多的并發(fā)用戶,以及如何利用ASP.NET的安全系統(tǒng)來實現(xiàn)最高性能的安全代碼。
[關(guān)鍵詞] ASP.NET 性能優(yōu)化 安全性
我們用ASP.NET開發(fā)網(wǎng)站,無論我們寫的ASP.NET應(yīng)用程序有多么好,無論在Web站點中添加了多少很酷的新特性,如果我們的站點在處理用戶請求時哪怕只是讓用戶等待了幾秒鐘,用戶也不會對我們的站點留下好印象。事實上,如果用戶等得太久,他們就會放棄而去訪問另一個站點。那么,如何才能提高站點的響應(yīng)速度,這就要考慮到我們在開發(fā)過程中如何優(yōu)化ASP.NET的性能。
一、性能開發(fā)及其優(yōu)化
性能表示系統(tǒng)執(zhí)行任務(wù)的速度和效率。就Web站點的性能而言,它對整個站點的點擊率起著不可忽視的作用。如果一個性能很差的網(wǎng)站長期沒有改進(jìn),你就會發(fā)現(xiàn)潛在的用戶全都跑光了。
1.利用JIT編譯器提高程序執(zhí)行速度
高性能代碼旨在能少做工作就少做工作,這是不言而明的。
在編譯任何ASP.NET的應(yīng)用程序時,編譯器把源代碼轉(zhuǎn)換為Microsoft中間語言(MSIL)。要在一個具體環(huán)境中執(zhí)行應(yīng)用程序,一個JIT編譯器先接受MSIL輸出并把指令轉(zhuǎn)換為主機(jī)處理的本機(jī)指令,再以即時方式編譯代碼,以便應(yīng)用程序開始執(zhí)行。但是,JIT編譯器不是把程序集中所有的MSIL都在開始執(zhí)行前轉(zhuǎn)換為本機(jī)代碼,只是一次編譯一個方法。JIT編譯器采用的這種方法有兩個性能上的優(yōu)勢。第一個優(yōu)勢:這項技術(shù)把編譯的成本分?jǐn)傇谝粋€較長的時間內(nèi),由于執(zhí)行會比JIT編譯器把所有的MSIL都進(jìn)行編譯看起來要快,這樣感覺到應(yīng)用程序的性能提高了。如果把長時間的暫?;虻却龝r間分成小塊,把它們分散開,你的用戶就不會注意到它們,用戶對你的應(yīng)用程序的性能也會比較滿意。第二個優(yōu)勢:JIT編譯器不編譯在執(zhí)行期間用不到的方法。因此不會做沒有必要的工作,無論什么時候省去不必要的處理工作,你就會發(fā)現(xiàn)可以獲得真正的性能增益。
2.減少運行時的工作
在底層,ASP.NET基礎(chǔ)結(jié)構(gòu)為了讓我們工作輕松,做了大量的基礎(chǔ)工作。雖然把這個體系結(jié)構(gòu)用做一個黑盒很不錯,但有時了解使一切如此無縫的運行的實現(xiàn)細(xì)節(jié)也是很有益的。掌握了這些額外的信息,我們經(jīng)常可以更有效地在運行程序時獲得速度上的優(yōu)勢。其實現(xiàn)主要有以下三種方法:
(1)視圖狀態(tài)的優(yōu)化
視圖狀態(tài)是性能的無聲殺手。自動視圖狀態(tài)管理是服務(wù)器控件的功能, 該功能使服務(wù)器控件可以在往返過程上重新填充它們的屬性值(不需要編寫任何代碼)。但是, 因為服務(wù)器控件的視圖狀態(tài)在隱藏的窗體字段中往返于服務(wù)器, 所以該功能確實會對性能產(chǎn)生影響。因此, 開發(fā)人員應(yīng)該知道在哪些情況下視圖狀態(tài)會有所幫助, 在哪些情況下它影響配器的性能。例如, 如果將服務(wù)器控件綁定到每個往返過程的數(shù)據(jù)上, 則將用數(shù)據(jù)綁定操作獲得的新值替換保存的視圖狀態(tài)。在這種情況下, 禁用視圖狀態(tài)可以節(jié)省處理時間。默認(rèn)情況下, 為所有服務(wù)器控件啟用視圖狀態(tài)。若要禁用視圖狀態(tài),將控件的EnableViewState 屬性設(shè)置為1。
從某種意義上說, 視圖狀態(tài)是有史以來最偉大的事情。畢竟, 視圖狀態(tài)使頁面和控件能夠在回發(fā)之間保持狀態(tài)。因此, 不必像在傳統(tǒng)的ASP中那樣編寫代碼, 以防止在單擊按鈕時文本框中的文本消失, 或在回發(fā)后重新查詢數(shù)據(jù)庫和重新綁定DataGrid。但是, 視圖狀態(tài)也有缺點: 當(dāng)它增長得過大時, 某些控件(例如文本框) 會根據(jù)視圖狀態(tài)做出相應(yīng)判斷; 其他控件(特別是DataGrid 和GridView) 則根據(jù)顯示的信息量確定視圖狀態(tài)。一個糟糕的GridView 容易將瀏覽器和Web 服務(wù)器之間連接的有效帶寬減少50%以上。ASP.NET 2.0能夠提供比ASP.NET 1.x 更簡單的方法將視圖狀態(tài)保留在會話狀態(tài)中。
(2)盡量減少服務(wù)器控件的使用
服務(wù)器端的控件不僅能生成視圖狀態(tài),它們也需要額外的運行時間處理綁定到成員變量。由于它們會使用服務(wù)器資源,即使它們非常易于使用, 但是服務(wù)器控件并不總是完成任務(wù)的最佳選擇, 在許多情況下, 一個簡單的呈現(xiàn)或數(shù)據(jù)綁定代入就可以完成任務(wù)。所以,Web頁面上服務(wù)器端的控件應(yīng)該保持在最低的數(shù)量上。
(3)把異常減到最少
不要依賴代碼中的異常。因為異常大大地降低性能, 所以不應(yīng)該將它們用作控制正常程序流程的方式。
異常是通知程序執(zhí)行期間發(fā)生的錯誤的一個非常有用的設(shè)備。程序不能忽視異常——它們將會改變程序的執(zhí)行流。在ASP.NET運行時的托管環(huán)境中,用try和catch設(shè)置異常處理代碼只對性能有可以忽略不計的影響,但程序拋出異常時卻有性能的損失。如果將try…catch語句使用為if語句,將拋出更少的異常,運行得更快。
3.有效使用內(nèi)存和緩存
只要可能, 就緩存數(shù)據(jù)和頁面輸出。使用ASP.NET 緩存機(jī)制有兩點需要注意。首先, 不要緩存太多項,緩存每個項均有開銷, 特別是在內(nèi)存使用方面。不要緩存容易重新計算和很少使用的項。其次, 給緩存的項分配的有效期不要太短。很快到期的項會導(dǎo)致緩存中不必要的周轉(zhuǎn), 并且經(jīng)常導(dǎo)致更多的代碼清除和垃圾回收工作。高周轉(zhuǎn)率可能說明存在問題, 特別是當(dāng)項在到期前被移除時。
不要給每個請求分配過多內(nèi)存, 因為這樣垃圾回收器將必須更頻繁地進(jìn)行更多工作。另外, 不要讓不必要的指針指向?qū)ο螅?因為它們將使對象保持活動狀態(tài), 并且應(yīng)盡量避免含F(xiàn)inalize 方法的對象, 因為它們在后面會導(dǎo)致更多的工作。特別是在Finalize調(diào)用中永遠(yuǎn)不要釋放資源, 因為資源在被垃圾回收器回收之前可能一直消耗著內(nèi)存。最后這個問題經(jīng)常會對Web 服務(wù)器環(huán)境的性能造成毀滅性的打擊, 因為在等待Finalize 運行時, 很容易耗盡某個特定的資源。
二、安全性
ASP.NET提供了一個很健壯的安全系統(tǒng),我們可以輕松地利用這個安全系統(tǒng)消除在ASP中為Web應(yīng)用程序提供用戶級別的安全性而編寫的大量代碼。這就意味著你需要編寫較少的代碼可以實現(xiàn)標(biāo)準(zhǔn)化的安全。
1.ASP.NET 的配置體系和安全體系
NET 框架提供了一個豐富又靈活的配置系統(tǒng), 使得應(yīng)用程序開發(fā)及管理人員能夠在整個應(yīng)用程序、站點和計算機(jī)中定義和使用可擴(kuò)展的配置數(shù)據(jù)。其中Machine.Config 為整個Web 服務(wù)器提供配置設(shè)置, 每一個ASP.NET Web 應(yīng)用程序根目錄以及各級子文件夾都可以有自己的名稱為Web. Config 的配置文件。配置文件都是基于XML 格式的文本文件, 通常用來保存一些常量或者安全設(shè)置、SQL 連接字符串和其他常規(guī)的配置數(shù)據(jù)等。每一個Web. Config 文件只在該文件夾和其子文件夾下起作用, 每個子文件夾的配置繼承父文件夾的的配置, 并覆蓋相同的選項。對于在Web. Config 中沒有進(jìn)行設(shè)置的屬性, 其取值將繼承Machine. Config 中屬性的設(shè)置。如果配置文件被更改, ASP.NET 將檢測到新的配置并自動使它起作用, 無需重新啟動服務(wù)器。另外, ASP.NET 通過配置IIS 來保護(hù)各級Web. Config 配置文件, 拒絕瀏覽器直接URL 訪問。
2.ASP.NET身份驗證和授權(quán)策略
當(dāng)IIS收到用戶請求時,它首先查看資源是如何受到保護(hù)的。資源可以用匿名訪問保護(hù)(大多數(shù)Web站點都是如此),或者用標(biāo)準(zhǔn)的本地或活動目錄證書保護(hù)。接下來,IIS通過標(biāo)準(zhǔn)的訪問控制列表(ACL)查看用戶對請求的資源是否有訪問權(quán)限。如果任一項檢查失敗,IIS甚至在請求到達(dá)ASP.NET之前就拒絕它。
在上述過程中發(fā)生了兩件事。用戶身份驗證,然后被授權(quán)。如果一個ASP.NET資源被請求,IIS對請求進(jìn)行了身份驗證并授權(quán),下一步是由ASP.NET提供它自己的身份驗證和授權(quán)。這為開發(fā)人員自定義的身份驗證提供了基礎(chǔ)結(jié)構(gòu),不必從頭開發(fā)一個安全基礎(chǔ)結(jié)構(gòu)。
ASP.NET在應(yīng)用程序中為驗證用戶身份提供了三種方法:
(1)Windows身份驗證
Windows身份驗證提供了與傳統(tǒng)的Windows賬號(或者是活動目錄賬號或者是本地賬號)相似的集成。該模式的工作方式和正常的IIS身份驗證相同。在這種模式下,要禁用對你站點的匿名訪問,以保護(hù)你的站點不被未授權(quán)用戶侵入。然后要更新Web. Config文件,指定身份驗證模式為Windows身份驗證,并指定ASP.NET應(yīng)該使用用戶被IIS質(zhì)詢時輸入的證書作為該應(yīng)用程序的證書。
Windows身份驗證是最快的身份驗證模式,因為它依賴于IIS模式,因為你不能控制登錄頁面模式的證書來源——并且該模式要求通過網(wǎng)絡(luò)訪問Windows證書來源,這就意味著它不十分適合于公共的Web應(yīng)用程序,因為你不能控制客戶端或網(wǎng)絡(luò)訪問。
(2)Forms身份驗證
Forms身份驗證允許開發(fā)人員生成他們自己的標(biāo)準(zhǔn)登錄頁面,并根據(jù)Web.Config文件中的條目進(jìn)行身份驗證,或者使用他們自己的身份驗證文件。Forms身份驗證是可自定義性最強(qiáng)的身份驗證方法。因為你能夠控制身份驗證文件和方法。
和Windows身份驗證不同的是Forms身份驗證要求單獨訪問證書來源(即使證書存儲在Web.Config中)。應(yīng)盡量簡化身份驗證例程,并去除總想包括在內(nèi)的外部元素(像檢索個性化設(shè)置、用戶圖片等)。這些工作只能放在其他時間來作,它們只會延緩登錄進(jìn)程。
(3)Passport身份驗證
Passport身份驗證允許你把你的應(yīng)用程序和Microsoft Passport服務(wù)集成在一起。該模式的基本工作方式是當(dāng)檢測一個未進(jìn)行身份驗證的請求時,ASP.NET把登錄證書從一個Passport登錄窗口(在Web服務(wù)器上安裝Passport服務(wù)時也安裝該登錄窗口)發(fā)送到Passport服務(wù)。
Passport身份驗證是最慢的身份驗證方法,因為為了驗證證書,它要求通過Internet進(jìn)行Web服務(wù)類型的通信。Passport方法也是有前途的,因為用戶只要記住一套證書就能登錄到受Passport保護(hù)的Web站點中。
三、結(jié)束語
對網(wǎng)站來說, 性能和安全性十分重要。ASP.NET 提供了若干新的策略和編程方式,在信息產(chǎn)業(yè)高速發(fā)展的今天,只有將這些新的策略和編程方式合理應(yīng)用到站點的開發(fā)中,以此來提高站點的性能和安全性,我們的站點才會受到更多的用戶的親睞。
參考文獻(xiàn):
[1 ]Scott Worle著王文龍劉湘寧譯:ASP. NET技術(shù)內(nèi)幕[M]. 人民郵電出版社,2002
[2 ]K.scott AllenJames Avery著侯譯:ASP. NET性能高級編程[M].清華大學(xué)出版社,2003
[3 ]Patrick A.Lorenz. ASP. NET 2.0 Revealed[M].Wrox Press ,2004
[4]尚俊杰秦衛(wèi)中:ASP.NET 程序設(shè)計案例教程[M].北京:清華大學(xué)出版社,2005