當(dāng)前位置:工程項目OA系統(tǒng) > 泛普各地 > 陜西OA系統(tǒng) > 西安OA系統(tǒng) > 西安OA快博
從底層了解ASP.NET構(gòu)架
ASP.NET是一個用于構(gòu)建Web程序的強大平臺,提供了巨大的彈性和能力以至于它可以構(gòu)建任意的Web程序。許多人僅僅對處于ASP.NET高層次的框架如:WebForms和WebServices比較熟悉,因此,在這篇文章里,我將會闡述有關(guān)ASP.NET比較底層的知識,并且將會解釋,如何將請求從Web Server移交給ASP.NET運行時,然后通過ASP.NET HTTP管道處理這些請求。
了解一個平臺的內(nèi)部工作機(jī)制總是會讓人感到一些滿足和安慰,深入了解也能幫助寫出更好的程序。知道了工具有什么用途,以及它們?nèi)绾谓M裝成復(fù)雜框架的一部分,這些將會使你很容易的找到問題的解決方案,以及在修改和調(diào)試錯誤時,都顯得非常重要。這篇文章的目的就是從底層了解ASP.NET以及幫助你理解請求如何流入ASP.NET處理管道里。同時,將會了解ASP.NET引擎的核心,以及一個Web請求如何在這里結(jié)束。這里講到的許多知識都是你日常工作中沒必要知道的,但是,如果理解了ASP.NET如何把請求路由到應(yīng)用程序的代碼里(通常比較高層次的),這將非常有用。
注意:整個ASP.NET引擎完全構(gòu)建在托管代碼里,其所有的擴(kuò)展性都是通過托管代碼去構(gòu)建。
使用ASP.NET的大多數(shù)人都比較熟悉WebForms和WebServices。這些高層次的實現(xiàn),使得構(gòu)建Web程序變得非常容易。ASP.NET被設(shè)計為驅(qū)動引擎,它把底層的接口提供給Web Server,為高層次Web應(yīng)用程序的前端和末端提供了路由服務(wù)。WebForms和WebServices是建立在ASP.NET框架之上,有關(guān)HTTP處理的兩種最常用的方式。
其實,在較低的層次上,ASP.NET也提供了足夠多的靈活性。HTTP運行時和請求管道提供了同樣的能力,可以構(gòu)建類似于WebForms和WebServices的實現(xiàn),當(dāng)然,這些已經(jīng)使用.NET托管代碼實現(xiàn)了。如果需要構(gòu)建一個自定義HTTP處理平臺,而這個平臺要比WebForms所處的層次低一點,那么就會用到所有這些類似的功能。
構(gòu)建大多的Web界面,使用WebForms無疑是最容易的方法,但是,如果想自定義一個內(nèi)容處理器,或者需要對流入和流出的內(nèi)容做特殊的處理,或者需要為一個應(yīng)用程序定制一個應(yīng)用服務(wù)器接口,那么使用這些低層次的處理或者模塊將會得到更好的性能,以及可以在真正的請求處理中獲得更多的控制權(quán)。盡管那些高層次的實現(xiàn),如:WebForms和WebServices已提供了類似的功能,但由于它們針對請求添加了太多的控制(導(dǎo)致性能下降)。所以完全可以另辟佳境,在較低層次上處理這些請求。
ASP.NET是什么?
讓我們從最簡單的定義開始,ASP.NET是什么?我通常喜歡用如下語句來描述ASP.NET。ASP.NET是完全使用托管代碼處理Web請求的一個成熟引擎平臺。它不僅僅只是WebForms和WebServices。
ASP.NET是一個請求處理引擎。它獲取客戶端請求,然后通過它內(nèi)置的管道,把請求傳到一個終點,在這個終點,開發(fā)者可以添加處理這個請求的邏輯代碼。實際上這個引擎和HTTP或者Web Server是完全分開的。事實上,HTTP運行時是一個組件,你可以把它宿主在IIS之外的應(yīng)用程序上。甚至完全可以和其它的服務(wù)組合在一起。例如可以把HTTP運行時宿主在Windows桌面應(yīng)用程序里。
通過使用內(nèi)置的管道路由請求,HTTP運行時提供了一套復(fù)雜的,但卻很優(yōu)雅的機(jī)制。在處理請求的每一個層面都牽涉到許多對象,但大多數(shù)對象都可以通過派生或者事件接口來擴(kuò)展。所以,此框架具有非常高的可擴(kuò)展性。通過這一套機(jī)制,可以進(jìn)入較低層次的接口如:緩存,身份驗證,授權(quán)等是有可能的。你可以在處理請求之前或之后過濾內(nèi)容,或者僅僅把匹配指定簽名的客戶端請求直接路由到你的代碼里或轉(zhuǎn)向其它的URL。針對同一件事情,可以通過不同的處理方法完成,而且實現(xiàn)代碼都非常的直觀。除此之外,在容易開發(fā)和性能之間,HTTP運行時還提供了最佳的靈活性。
整個ASP.NET引擎完全構(gòu)建在托管代碼里,所有的擴(kuò)展性功能都是通過托管代碼的擴(kuò)展提供。對于功能強大的.NET框架而言,使用自己的東西,構(gòu)建一個成熟的、高性能的引擎體系結(jié)構(gòu)已經(jīng)成為一個遺囑。盡管如此,但重要的是,ASP.NET給人印象最深的是高瞻遠(yuǎn)矚的設(shè)計,這使得在其之上的工作變得非常容易,并且提供了幾乎可以鉤住請求處理當(dāng)中任意部分的能力。
使用ASP.NET可以完成一些任務(wù),之前這些任務(wù)是使用IIS上的ISAPI擴(kuò)展和過濾來完成的。盡管還有一些限制,但與ASP相比,已經(jīng)有了很大的進(jìn)步。ISAPI是底層Win32樣式的API,僅它的接口就有1MB,這對于大型的程序開發(fā)是非常困難的。由于ISAPI是底層的接口,因此它的速度也是非常的快。但對于企業(yè)級的程序開發(fā)是相當(dāng)?shù)碾y于管理的。所以,在一定的時間內(nèi),ISAPI主要充當(dāng)其它應(yīng)用程序或平臺的橋接口。但是無論如何,ISAPI沒有被廢棄。事實上,微軟平臺上的ASP.NET和IIS的接口是通過宿主在.NET里的ISAPI擴(kuò)展來通信的,然后直達(dá)ASP.NET運行時。ISAPI提供了與Web Server通信的核心接口,然后ASP.NET使用非托管代碼獲取請求以及對客戶端請求發(fā)出響應(yīng)。ISAPI提供的內(nèi)容經(jīng)由公共對象類似于HttpRequest和HttpResponse,通過一個設(shè)計優(yōu)良的、可訪問的接口,以托管對象的方式暴露非托管數(shù)據(jù)。
從瀏覽器到ASP.NET
讓我們從一個典型的ASP.NET Web請求的生命周期的起點開始。用戶通過在瀏覽器中鍵入一個URL,點擊一個超鏈接,提交一個HTML表單(一個post請求),或者一個客戶端程序調(diào)用基于ASP.NET的WebService(通過ASP.NET提供服務(wù))。在服務(wù)器端,IIS5或者IIS6將會收到這個請求。ASP.NET的底層通過ISAPI擴(kuò)展與IIS通信,然后,通過ASP.NET,這個請求通常被路由到一個帶有.aspx擴(kuò)展名的頁面。但是,這個處理過程如何工作,則完全依賴于HTTP處理器(handler)的執(zhí)行。這個處理器將被安裝用于處理指定的擴(kuò)展。在IIS中,.aspx經(jīng)由"應(yīng)用程序擴(kuò)展"被映射到ASP.NET ISAPI的dll文件:aspnet_isapi.dll。每一個觸發(fā)ASP.NET的請求,都必須經(jīng)由一個已經(jīng)注冊的,并且指向aspnet_isapi.dll的擴(kuò)展名來標(biāo)識。
注意:ISAPI是自定義Web請求處理中第一個并且具有最高性能的IIS入口點。
依靠擴(kuò)展名,ASP.NET把一個請求路由到一個恰當(dāng)?shù)奶幚砥?,該處理器則負(fù)責(zé)處理這個請求。舉個例子,WebServices的擴(kuò)展名.asmx不會把一個請求路由到磁盤上的某一個頁面,而是會路由到在定義中附加了指定特性(WebMethodAttribute)的類,此特性會把它標(biāo)識成一個Web Services的實現(xiàn)。許多其它的處理器將隨著ASP.NET一起被安裝。當(dāng)然也可以定義你自己的處理器。在IIS里所有的HttpHandler被映射并指向ASP.NET ISAPI擴(kuò)展,并且這些HttpHandler也都在web.config里配置,用于把請求路由到指定的HTTP處理器里執(zhí)行。每一個處理器都是一個.NET類,用于處理指定的擴(kuò)展。而這些處理器可以處理簡單到只有幾行代碼的Hello World,也可以處理復(fù)雜到類似ASP.NET的頁面以及執(zhí)行WebService。就目前而言,僅僅需要理解擴(kuò)展就是一種基本的映射機(jī)制,ASP.NET用它可以從ISAPI里獲取一個請求,然后把請求路由到指定處理該請求的處理器中。
ISAPI連接
ISAPI是底層非托管的Win32 API。它定義的接口非常的單一并且性能最優(yōu)。用這些接口處理原始指針(raw pointer),而函數(shù)指針列表(function pointer tables)則用于回調(diào)。ISAPI提供了最低層的、高性能的接口,開發(fā)者和工具廠商可以使用這些接口深入到IIS里。由于ISAPI是非常低層的,所以不太適合使用它構(gòu)建應(yīng)用級的程序。ISAPI趨向于被當(dāng)作橋接口使用,用于給高層次的工具提供應(yīng)用服務(wù)類型的功能。例如,ASP和ASP.NET都是被當(dāng)作冷聚變(cold fusion)構(gòu)建于ISAPI之上。大多Perl、PHP和JSP的執(zhí)行如同許多第三方解決方案一樣,可以在IIS運行。ISAPI是個非常好的工具,它給高層次的應(yīng)用程序提供了高性能垂直訪問接口。這使得那些高層次的應(yīng)用程序需要的信息可以從ISAPI提供的信息中提煉。在ASP和ASP.NET里,引擎可以提煉ISAPI接口提供的表單里的對象如:Request和Response,這些對象可以從ISAPI請求的信息中讀取它們各自的內(nèi)容。
作為約定,ISAPI支持ISAPI擴(kuò)展(extensions)和ISAPI過濾(filters)。擴(kuò)展是請求處理接口,提供了跟Web Server輸入和輸出相關(guān)的邏輯處理。從本質(zhì)上來說,它是一個事務(wù)接口。ASP和ASP.NET都被看作ISAPI擴(kuò)展的實現(xiàn)。ISAPI是鉤子接口,它允許你查看進(jìn)入IIS的每一個請求并且可以修改請求的內(nèi)容(包括輸入和輸出)或者改變模塊(如:身份驗證等)的行為。順便提一下,ASP.NET通過兩個方面的內(nèi)容:HTTP處理器(對應(yīng)ISAPI擴(kuò)展)和HTTP 模塊(對應(yīng)ISAPI過濾)映射到ISAPI。這些相關(guān)的內(nèi)容將會在后面詳細(xì)描述。
ISAPI是代碼的初始點,標(biāo)識ASP.NET一個請求的開始。ASP.NET映射了不同的擴(kuò)展到它的ISAPI擴(kuò)展,ISAPI擴(kuò)展位于.NET Framework目錄:
<.NET FrameworkDir>aspnet_isapi.dll
可以在IIS服務(wù)管理器里看到這些映射。打開Web站點的根目錄的屬性,選擇主目錄選項卡,然后查看配置|應(yīng)用程序映射。
通過這種機(jī)制,在Web Server里,請求就可以被路由到ASP.NET的處理管道里。盡管.NET需要很多擴(kuò)展名,但不必手工設(shè)置它們,可以使用aspnet_regiis.exe實用工具確保所有的腳本映射都被注冊。
cd <.NetFrameworkDirectory> aspnet_regiis - i 這將會把ASP.NET運行時的個別版本,通過腳本映射注冊到整個Web站點,并且安裝客戶端腳本庫,這些腳本庫將會被瀏覽器上的控件所使用。
注意:它是注冊了安裝在上面目錄里的CLR的那個版本。aspnet_regiis有一個可選項,可以使你單獨配置一個虛擬目錄。
每一個.NET框架的版本,都擁有各自的aspnet_regiis,對于不同版本的.NET框架,你需要運行適當(dāng)版本的aspnet_regiis,注冊到整個站點或者虛擬目錄。從ASP.NET2.0開始,在IIS控制臺里,有一個IIS ASP.NET配置頁面,在這個頁面可以挑選.NET的版本。
IIS5和IIS6的不同之處
當(dāng)一個請求進(jìn)來的時候,IIS會檢查腳本映射,然后把請求路由到aspnet_isapi.dll。接下來這個DLL文件的操作是什么呢?在IIS5和IIS6里,這個請求又是如何到達(dá)ASP.NET運行時的呢?它們兩者的處理方式有沒有重大變化呢?
站在比較高的角度,觀看請求從IIS到ASP.NET運行時的流程,然后直達(dá)請求處理管道。IIS5和IIS6與ASP.NET的接口采用了不同的方式,但從請求到達(dá)ASP.NET管道后的整個過程是完全一樣的。
IIS5直接把aspnet_isapi.dll寄宿在inetinfo.exe進(jìn)程里,或者它們中的一個將會與工作進(jìn)程隔離,如果擁有隔離權(quán)限,那么可以把Web站點和虛擬目錄隔離的級別設(shè)置為中等或者高級。當(dāng)?shù)谝粋€ASP.NET請求進(jìn)來的時候,DLL將會在另一個EXE-aspnet_wp.exe里分配一個新的進(jìn)程,然后把相關(guān)信息路由到這個新分配的進(jìn)程里。接著這個新的進(jìn)程會依次加載和寄宿.NET運行時。每一個進(jìn)入到ISAPI DLL的請求,都將通過調(diào)用命名管道路由給這個工作者進(jìn)程。
注意:IIS6與之前的Web Server不同,已經(jīng)對ASP.NET進(jìn)行了優(yōu)化處理。IIS6中使用了應(yīng)用程序池。
值得注意的是,IIS6改變了這個處理模型,IIS不再直接寄宿像ISAPI擴(kuò)展的任何外部可執(zhí)行代碼。代替的是,IIS總會保持一個單獨的工作進(jìn)程:應(yīng)用程序池。所有的處理都發(fā)生在這個進(jìn)程里,包括ISAPI dll的執(zhí)行。對于IIS6而言,應(yīng)用程序池是一個重大的改進(jìn),因為它們允許以更小的粒度控制一個指定進(jìn)程的執(zhí)行。你可以為每一個虛擬目錄或者整個Web站點配置應(yīng)用程序池,這可以很容易的把每一個應(yīng)用程序隔離到各自的進(jìn)程里,這樣就可以把它與運行在同一臺機(jī)器上其他程序完全隔離。從Web處理的角度看,如果一個進(jìn)程死掉,至少它不會影響到其它的進(jìn)程。
另外,應(yīng)用程序池是高度可配置的。通過設(shè)置應(yīng)用程序池的執(zhí)行許可,可以配置它們的執(zhí)行安全環(huán)境。并且可以為指定的應(yīng)用程序按照相同的粒度定制這些配置。對于ASP.NET而言,IIS6最大的改進(jìn)是使用應(yīng)用程序池代替了machine.config里的ProcessModel實體的大部分功能。在IIS5里,這個實體是很難管理的,因為它的設(shè)置是全局的,而且不能夠在指定Web程序的web.config里覆蓋這些設(shè)置。當(dāng)IIS6運行的時候,ProcessModel里的大部分配置將被忽略,取而代之的是讀取應(yīng)用程序池的配置。注意我這里說的是大部分,另外的一些配置,像線程池的大小和IO線程數(shù)目等仍然需要通過這個節(jié)點配置,這是因為,在服務(wù)器的應(yīng)用程序池里沒有提供類似功能的配置。
由于應(yīng)用程序池是在外部執(zhí)行的,所以這些執(zhí)行可以很容易的被監(jiān)控和管理。IIS6還提供了許多性能計數(shù)器,可以對重啟和超時選項進(jìn)行跟蹤。在許多情況下,這可以幫助應(yīng)用程序糾正問題。最后,IIS6的應(yīng)用程序池的實現(xiàn)不依賴COM+,正如IIS5隔離進(jìn)程一樣,這提高了程序的性能和穩(wěn)定性,特別是那些需要在內(nèi)部使用COM對象的程序。
IIS6應(yīng)用程序池也包含了ASP.NET固有的東西,ASP.NET可以和新的底層API通信,這些API允許直接訪問HTTP緩沖存儲器的API,而HTTP緩沖存儲器的API可以直接進(jìn)入Web Server的緩沖存儲器,卸載ASP.NET級別的緩存。
在IIS6里,ISAPI擴(kuò)展運行在應(yīng)用程序池的工作進(jìn)程里。.而NET運行時也運行在這個進(jìn)程里,所以ISAPI擴(kuò)展和.NET運行時的通信是發(fā)生在進(jìn)程內(nèi)的。這就使得比必須使用命名管道接口的IIS5具有更高的性能。盡管IIS的宿主模型不同,但是真正進(jìn)入托管代碼的接口是類似的,僅僅在獲取被路由的請求時有一些變動。
進(jìn)入.NET運行時
進(jìn)入.NET運行時的真正登錄點發(fā)生在一些沒有正式文檔的類和接口之間。在微軟外面的世界,這些接口鮮為人知。微軟的民間也不太熱衷于討論這些細(xì)節(jié),可能是因為他們認(rèn)為這些,對于使用ASP.NET構(gòu)建程序的開發(fā)者沒有太多的影響。
工作進(jìn)程aspnet_wp.exe(IIS5)和w3wp.exe(IIS6)宿主在.NET運行時里。ISAPI DLL通過底層的COM調(diào)用一小撮非托管類型的接口,其實,最終調(diào)用的是ISAPIRuntime派生類的實例。進(jìn)入運行時的第一個登錄點是未歸檔ISAPIRuntime類,它通過COM把接口IISAPIRuntime暴露給調(diào)用者。這些COM接口是底層的IUnknown,基于這些接口,就意味著從ISAPI擴(kuò)展到ASP.NET之間的調(diào)用屬于內(nèi)部調(diào)用。圖3是使用有名的反射工具Refector(http://www.aisto.com/roeder/dotnet/)看到的IISAPIRuntime接口的簽名。Refector是一個可以查看和反編譯程序集的工具,使用它可以很容易的查看元數(shù)據(jù)、反編譯代碼,就像圖3中看到的那樣。使用它一步一步地探究處理的過程,這是個非常不錯的方法。
如果想深入了解底層的接口,打開Refector工具,然后指向System.Web.Hosting命名空間。進(jìn)入ASP.NET的登錄點以一個托管的COM接口出現(xiàn),該接口將在ISAPI dll里被調(diào)用。該登錄點接收一個指向ISAPI ECB非托管類型的指針。ECB擁有訪問整個ISAPI接口的權(quán)限,它可以獲取請求的數(shù)據(jù)以及把返回的數(shù)據(jù)發(fā)回IIS。
IISAPIRuntime接口擔(dān)當(dāng)著來自于ISAPI擴(kuò)展(在IIS6里是直接通信的,在IIS5里間接的通過命名管道通信的)的非托管代碼和托管代碼之間的橋梁。如果留意一下這個類,就會發(fā)現(xiàn)ProcessRequest方法的簽名像下面的樣子:
[return: MarshalAs(UnmanagedType.I4)] int ProcessRequest([In] IntPtr ecb, [In, MarshalAs(UnmanagedType.I4)] int useProcessModel);
ecb參數(shù)是ISAPI擴(kuò)展控制塊(extension control block),它被作為非托管資源傳給ProcessRequest方法。此方法將獲取ECB,然后把它作為基本的輸入和輸出接口,用于Request和Response對象。ISAPI ECB包含著所有底層的請求信息,這其中包括服務(wù)器變量,用于表單變量(form variables)的輸入流,以及用于寫數(shù)據(jù)并把數(shù)據(jù)發(fā)送到客戶端的輸出流中。一個單獨的ECB引用基本上提供了一個ISAPI請求可以訪問的所有功能。ProcessRequest既是登錄點也是登出點,在這里非托管資源最先與托管代碼相聯(lián)系。
ISAPI擴(kuò)展以異步的方式處理請求。所以,當(dāng)ISAPI擴(kuò)展調(diào)用了工作進(jìn)程或者IIS的線程后,會立即返回,但會為當(dāng)前有效的請求保留ECB。因此,ECB需要包含這樣的機(jī)制,即當(dāng)請求結(jié)束的時候通知ISAPI(通過ecb.ServerSupportFunction實現(xiàn)),然后ISAPI擴(kuò)展釋放ECB資源。接著以異步的方式立即釋放ISAPI工作線程,和卸載由ASP.NET托管的那個隔離的處理線程。
ASP.NET得到ecb引用后,會在內(nèi)部使用它來獲取當(dāng)前請求的相關(guān)信息,如服務(wù)器變量,POST的數(shù)據(jù)以及返回輸出到客戶端的數(shù)據(jù)。Ecb將繼續(xù)存活直到這個請求結(jié)束或者IIS超時,在這之前,ASP.NET將會與ecb繼續(xù)保持通信。當(dāng)請求結(jié)束的時候,輸出的內(nèi)容會寫進(jìn)ISAPI的輸出流里(通過ecb.WriteClient()實現(xiàn))。然后ISAPI擴(kuò)展會被通知請求已經(jīng)結(jié)束,讓它知道ECB可以被釋放了。這個執(zhí)行過程是非常高效的,這是因為.NET類本質(zhì)上只是擔(dān)當(dāng)著一個相當(dāng)瘦小的包裝器,而它包裝的內(nèi)容就是具有高性能的非托管ISAPI ECB。(ITPUB)
- 1業(yè)務(wù)過程執(zhí)行的7個謬誤
- 2樓市現(xiàn)狀誰都不敢動 明年剛需濤聲依舊
- 3多地感受今冬最冷一天 專家稱,最冷時段還未到來
- 4網(wǎng)絡(luò)監(jiān)控激發(fā)管理凝聚力
- 5移動安全生死一線
- 6專家解答CIO"議事規(guī)則"
- 72012太陽能等新能源補貼超200億元
- 8反垃圾郵件的核心指標(biāo)
- 9新光增持中百集團(tuán)成第一大單一股東
- 10中國強硬令菲律賓震驚 菲媒鼓吹建同盟應(yīng)對危機(jī)
- 11JAVA新技術(shù)在協(xié)同BPM軟件中的應(yīng)用
- 12NetFlow網(wǎng)絡(luò)流量監(jiān)測技術(shù)的應(yīng)用和設(shè)計
- 13升級后的網(wǎng)絡(luò)管理
- 14OA系統(tǒng)為客戶打造“財務(wù)預(yù)算管理與網(wǎng)上報銷”
- 15十二個最不安全的常用應(yīng)用程序
- 16男子飯店挑選活魚當(dāng)面做記號 上桌后仍舊被掉包
- 17選擇合適的數(shù)據(jù)挖掘算法
- 18鏈家地產(chǎn):國土部發(fā)文調(diào)控土地市場
- 19XX市民宗委信息化服務(wù)平臺需求分析報告
- 20陳年給如風(fēng)達(dá)打氣:雖有調(diào)整 仍是凡客核心
- 21新一代中小企業(yè)網(wǎng)絡(luò)運行管理標(biāo)準(zhǔn)
- 22怎樣為數(shù)據(jù)中心“減肥”
- 23微軟官方密碼強度測試工具測密碼安全
- 24避開誤區(qū) 中小企業(yè)網(wǎng)絡(luò)建設(shè)幾大問題須知
- 25怎樣鑒別硬件防火墻性能的差異
- 26解密FBI電話及網(wǎng)絡(luò)監(jiān)控技術(shù)
- 27企業(yè)信息化大講堂之路由器基礎(chǔ)知識
- 28RFID在務(wù)實中演進(jìn)
- 29長沙救助站否認(rèn)毆打暗訪記者 稱其疑似精神病
- 30中小企業(yè)試水虛擬化的幾大技巧
成都公司:成都市成華區(qū)建設(shè)南路160號1層9號
重慶公司:重慶市江北區(qū)紅旗河溝華創(chuàng)商務(wù)大廈18樓