ASP.NET程序員應(yīng)用程序域須知
2006-08-14 16:48:51asp.net程序員應(yīng)用程序域須知
本文將討論.net的應(yīng)用程序域,并且它們是如何對(duì)asp.net的執(zhí)行和調(diào)度產(chǎn)生影響的。
當(dāng)在windows中啟動(dòng)notepad程序時(shí),眾所周知程序會(huì)執(zhí)行一個(gè)包含在容器內(nèi)的進(jìn)程??梢詥?dòng)多個(gè)notepad的實(shí)例,并且每個(gè)實(shí)例都會(huì)在一個(gè)專注的進(jìn)行程運(yùn)行。使用任務(wù)管理器,可以看到在系統(tǒng)中當(dāng)前運(yùn)行的所有進(jìn)程的清單。
一個(gè)進(jìn)程包括可執(zhí)行從操作系統(tǒng)中保留的在內(nèi)存中的代碼和程序數(shù)據(jù)。在進(jìn)程之內(nèi)只少有一個(gè)包含在進(jìn)程之內(nèi)的正在執(zhí)行指令的線程,并且在多數(shù)情況下有多個(gè)線程。如果程序打開了任何文件或者資源,這些資源將屬于這個(gè)進(jìn)程。
一個(gè)進(jìn)程也有一個(gè)分界線。包含在進(jìn)程之內(nèi)的錯(cuò)誤代碼不能在當(dāng)前進(jìn)程之外的地區(qū)腐化。在一個(gè)進(jìn)程之內(nèi)很容易通訊,但是專業(yè)技術(shù)要求一個(gè)進(jìn)程對(duì)另一個(gè)進(jìn)程通訊是必需的。每一個(gè)進(jìn)程也在一個(gè)特殊的上下文安全系統(tǒng)中運(yùn)行,這個(gè)安全系統(tǒng)規(guī)定在機(jī)器和網(wǎng)絡(luò)中進(jìn)程做什么。
一個(gè)進(jìn)程是一個(gè)在windows 操作系統(tǒng)中獨(dú)立運(yùn)行的最小單位。這會(huì)給在一個(gè)單一服務(wù)器上對(duì)一大堆應(yīng)用程序的isp提出一個(gè)問題。isp將會(huì)分離每一個(gè)在同一個(gè)服務(wù)器上的與另一個(gè)公司的應(yīng)用程序干擾的asp.net應(yīng)用程序。但是相關(guān)的發(fā)射和執(zhí)行一個(gè)對(duì)成百上千的應(yīng)用程序的過程成本禁止的。
介紹應(yīng)用程序域
.net介紹一個(gè)應(yīng)用程序域的概念,或者appdomain像一個(gè)過程,appdomain是既是容器又是邊界線。.net運(yùn)行時(shí)間使用 appdomain作為代碼和數(shù)據(jù)的容器,就像操作系統(tǒng)一個(gè)過程作為代碼和數(shù)據(jù)的容器一樣。當(dāng)操作系統(tǒng)使用一個(gè)過程來分離不整齊的代碼時(shí),.net運(yùn)行時(shí)間使用一個(gè)appdomain來分離在一個(gè)安全邊線內(nèi)的代碼。
一個(gè)appdomain僅僅屬于一個(gè)單過程,但是單個(gè)過程能夠保持多重的appdomain。一個(gè)appdomain創(chuàng)建起來相對(duì)容易(與一個(gè)過程比較起來),并且與一個(gè)過程比較起來具有少的維護(hù)費(fèi)用。由于這些原因,一個(gè)appdomain是isp(提供成千上萬的應(yīng)用程序)的很好的解決方案。每一個(gè)應(yīng)用程序可以生存在一個(gè)獨(dú)立的appdomain之內(nèi),并且許多這樣的appdomain可以生存于一個(gè)單一的過程(節(jié)省費(fèi)用)之內(nèi)。
appdomain
在同服務(wù)器上創(chuàng)建了兩個(gè)asp.net應(yīng)用程序,并且沒有任何特殊配置。會(huì)發(fā)生什么事情呢?
一個(gè)單一的asp.net手工進(jìn)程使asp.net應(yīng)用程序變成兩方面的主要程序。在windows xp和windows 2000中,這一程序被命名為aspnet_wp.exe,并且這一程序運(yùn)行在本地的aspnet計(jì)數(shù)器的前后安全關(guān)系中。在windows 2003手工程序擁有w3wp.exe并且默認(rèn)運(yùn)行在networ service中。
一個(gè)對(duì)旬可以進(jìn)住在一個(gè)appdomain中。每一個(gè)asp.net應(yīng)用程序?qū)⒕哂兴约旱囊惶兹肿兞浚篶ache, application進(jìn)住進(jìn)同一進(jìn)程,.net appdomain是一個(gè)獨(dú)立的單元。如果存有共享的或靜態(tài)成員的類,并且那些類存在于兩種應(yīng)用程序之內(nèi),每一個(gè)appdomain擁有它自己的靜態(tài)字段的備份—數(shù)據(jù)并不共享。每一個(gè)應(yīng)用程序的數(shù)據(jù)和代碼安全獨(dú)立存在并且在一邊界之內(nèi)由appdomain提供。
為了在appdomain之間通訊或者在appdomain之間交換對(duì)象,需要查看在.net中穿過邊界的通訊技術(shù),例如.net細(xì)微的或web 服務(wù)。
對(duì)將appdomain作為邊界思想的警告之一是asp.net應(yīng)用程序在默認(rèn)情況下會(huì)帶著充分的信任運(yùn)行。充分信任的代碼可以執(zhí)行本地代碼,并且本地代碼可以本質(zhì)地在進(jìn)程之內(nèi)的任何內(nèi)容。需要運(yùn)行帶著部分信任執(zhí)行應(yīng)用程序來約束存取不完整的代碼并且對(duì)安全的appdomain驗(yàn)證所有代碼。
隱藏備份并且重新啟動(dòng)
一旦一個(gè)集合加載到一個(gè)appdomain,沒有辦法從appdomain集合的辦法。不過,從一個(gè)進(jìn)程中移除一個(gè)appdomain是有可能的。
如果將一個(gè)已更新的dll復(fù)制到一個(gè)應(yīng)用程序的子目錄中,從asp.net的運(yùn)行時(shí)間知道有新代碼要執(zhí)行。既然asp.net不能將dll復(fù)制到已存在的appdomain中,它就會(huì)起動(dòng)一個(gè)新appdomain。舊的應(yīng)用程序域是“排水已停止”,那就是,存在的需要被允許完成執(zhí)行并且一旦它們執(zhí)行完成appdomain可以卸載。帶有新代碼的新的appdomain就會(huì)開始并且開始所有的新請(qǐng)求。
典型地說,當(dāng)一個(gè)dll加載進(jìn)一個(gè)進(jìn)程時(shí),進(jìn)程對(duì)dll加鎖并且不能對(duì)磁盤的上的文件進(jìn)行覆蓋。不過,appdomain有一個(gè)眾所周知的特點(diǎn):隱藏復(fù)制那所有的允許保留在磁盤上的那些未被加鎖的可替換的集合。
運(yùn)行時(shí)間對(duì)二進(jìn)制子目錄的帶有shadow copy的asp.net進(jìn)行初始化。appdomain將任何的加鎖之前的dll從二進(jìn)制子目錄中拷貝到一個(gè)臨時(shí)位置并且再將這些dll加載到內(nèi)存。 shadow copy允許沒有將網(wǎng)頁在線的情況下對(duì)所有在二進(jìn)制子目錄中的任何dll進(jìn)行重寫。
熟練掌握domain
應(yīng)用程序域替換os進(jìn)程將為單獨(dú)的.net結(jié)點(diǎn)單元。一個(gè)可理解的應(yīng)用程序域?qū)?huì)給你一個(gè)在asp.net應(yīng)用程序后的手工發(fā)生的概念。使用 appdomain類的currentdomain屬性,可以檢查關(guān)于代碼正在運(yùn)行的appdomain的屬性,包括我們?cè)诖宋恼轮杏懻摰膕hadow copy。