糯米文學吧

位置:首頁 > 範文 > 熱點

ASPNET是怎樣在IIS下工作的

熱點1.16W

與IIS是緊密聯繫的,由於IIS6.0與IIS7.0的工作方式的不同,導致的工作原理也發生了相應的變化。

ASPNET是怎樣在IIS下工作的

IIS6(IIS7的經典模式)與IIS7的集成模式的不同

IIS6的運行過程:

分析上圖可知:

在 User Mode 下, 接收到 http request,然後它會根據 IIS 中的 Metabase 查看基於該 Request 的 Application 屬於哪個 Application Pool, 如果該 Application Pool 不存在,則創建之。否則直接將 request 發到對應 Application Pool 的 Queue中。每個 Application Pool 對應着一個 Worker Process — ,(運行在 User Mode 下)。

在 IIS Metabase 中維護着 Application Pool 和 Worker Process 的Mapping。WAS(Web Administrative Service)根據這樣一個 mapping,將存在於某個 Application Pool Queue 的 request 傳遞到對應的 Worker Process (如果沒有,就創建這樣一個進程)。在 Worker Process 初始化的時候,加載 ISAPI, ISAPI 進而加載 CLR。最後通過 AppManagerAppDomainFactory 的 Create 方法為 Application 創建一個 Application Domain;通過 ISAPIRuntime 的 ProcessRequest 處理 Request,進而將流程進入到 Http Runtime Pipeline。

幾個知識點:

:(Kernel)的一個組件,它負責偵聽(Listen)來自於外部的HTTP請求,根據請求的URL將其轉發給相應的應用程序池 (Application Pool)。當此HTTP請求處理完成時,它又負責將處理結果發送出去.為了提供更好的性能,內部建立了一個緩衝區,將最近的HTTP請求處理結果保存起來。

Application Pool: IIS總會保持一個單獨的工作進程:應用程序池。所有的處理都發生在這個進程裏,包括ISAPI dll的執行。對於IIS6而言,應用程序池是一個重大的改進,因為它們允許以更小的粒度控制一個指定進程的執行。你可以為每一個虛擬目錄或者整個Web 站點配置應用程序池,這可以使你很容易的把每一個應用程序隔離到各自的進程裏,這樣就可以把它與運行在同一台機器上其他程序完全隔離。從Web處理的角度看,如果一個進程死掉,至少它不會影響到其它的進程。

當應用程序池接收到HTTP請求後,交由在此應用程序池中運行的工作者進程Worker Process: 來處理此HTTP請求。

Worker Process: 當工作者進程接收到請求後,首先根據後綴找到並加載對應的ISAPI擴展 (如:aspx 對應的映射是aspnet_),工作者進程加載完aspnet_後,由aspnet_負責加載 應用程序的運行環境即CLR ( Runtime)。

Worker Process運行在非託管環境,而中的對象則運行在託管環境之上(CLR),它們之間的橋樑就是ISAPI擴展。

WAS(Web Admin Service):這是一個監控程序,它一方面可以存取放在InetInfo元數據庫(Metabase)中的各種信息,另一方面也負責監控應用程序池(Application Pool)中的工作者進程的工作狀態況,必要時它會關閉一個老的工作者進程並創建一個新的取而代之。

IIS7的運行過程:

分析上圖可知:

1、當客户端瀏覽器開始 HTTP 請求一個WEB 服務器的資源時, 攔截到這個請求。

2、 聯繫 WAS 獲取配置信息。

3、WAS 向配置存儲中心(ig)請求配置信息。

4、WWW 服務接收到配置信息,配置信息指類似應用程序池配置信息,站點配置信息等等。

5、WWW 服務使用配置信息去配置 處理策略。

6、WAS為請求創建一個進程(如果不存在的話)。

7、工作者進程處理請求並對做出響應。

8、客户端接受到處理結果信息。

除了IIS的整體運行方式不同之外,IIS7相比IIS6最大的不同之處在於它提供了兩種應用程序池管道模式:

經典模式:是與IIS 6或者之前版本保持兼容的一種模式,一個典型問題就是,在處理這種動態網站的時候,它是通過一個所謂的ISAPI程序,作為插件的方式來工作的。針對不同的動態應用程序(例如ASP,PHP等),會需要不同的ISAPI(Internet Server Application Programe Interface,互聯網服務器應用程序接口)。如圖,在IIS中,打開“處理程序映射”,可以看到aspx類型頁面的處理程序為aspnet_。

下圖展示了IIS7經典模式與IIS6的應用程序池管道模式運行原理,針對不同的請求,會指定不同的ISAPI(dll)進行處理:

集成模式:不再像IIS6一樣只限定於aspnet_中,而是被解放出來,從IIS接收到HTTP請求開始,即進入的控制範圍,可以存在於一個請求在IIS中各個處理階段。允許我們將更好地與IIS集成,甚至允許我們在中編寫一些功能(例如Module)來改變IIS的行為(擴 展)。集成的好處是,不再通過ISAPI的'方式,提高了速度和穩定性。至於擴展,則可以使得我們對於IIS,以及其他類型的請求有更多的控制。(例如,我 們希望靜態網頁也具備一些特殊的行為)。如圖

如下圖在IIS7集成模式中,打開處理程序映射,可以看到aspx類型頁面所對應的不再是一個dll,而是一個類型。

總結與擴展:

對於處理應用程序而言,IIS6及IIS7的經典模式需要aspnet_來處理,而IIS7集成模式不需要aspnet_來處理,而可以直接根據文件擴展名找到相應的處理程序接口。例如aspx的處理程序是HandlerFactory類型。

介紹完IIS的工作原理,來看一下內部的運行機制。

首先看一下IIS處理模型:

上面介紹IIS工作原理時,已經介紹了從發起HTTP請求,到響應請求的過程,這裏主要介紹當請求到達 Runtime之後,運行時所發生的一系列工作。

先看如下的運行時工作序列圖:

請求進入Web服務器後,首先由來判斷請求的頁面是否存在,如果存在的話將把請求信息轉交給 Runtime。在這部分實際是完成兩個步驟,在將請求轉交給 Runtime的同時將請求信息封存在HTTPWorkRequest類中供其它步驟調用。HttpWorkRequest類在以後的操作中至關重要,它第一次將Http請求信息轉換為類信息。

2.當請求到達 Runtime後,接下來的操作將會在託管環境中完成,這時請求就真正進入了中,對請求信息的操作是由的底層類庫來實現。首先 Runtime將會針對請求信息做兩個動作,一是準備HostingEnvironment;二是調用ApplicationManager類為HTTP請求動態的分配AppDomain,並把處理權交給AppDomain。

請求進入AppDomain後,將由對象ISAPIRuntime來接管,一方面經方法ProcessRequest()得到HttpWorkerRequest對象,另一方面由方法StartProcessing()生成HttpRuntime對象,接下來把處理權交給了HttpRuntime(HttpWorkerRequest對象將作為HttpRuntime方法中的參數被使用)。

Runtime接收到Http請求後,方法ProcessRequest處理請求。將對第1步中的HTTPWorkRequest類中的信息進行操作,具體的實現由ProcessRequest方法實現。內部代碼如下:

[AspNetHostingPermission(nd, Level=um)]public static void ProcessRequest(HttpWorkerRequest wr){if (wr == null){throw new ArgumentNullException("wr");}if (UseIntegratedPipeline){throw new PlatformNotSupportedException(tring("Method_Not_Supported_By_Iis_Integrated_Mode", new object[] { "essRequest" }));}ProcessRequestNoDemand(wr);}internal static void ProcessRequestNoDemand(HttpWorkerRequest wr){RequestQueue queue = _theRuntime._requestQueue;if (queue != null){wr = equestToExecute(wr);}if (wr != null){CalculateWaitTimeAndUpdatePerfCounter(wr);tStartTime();ProcessRequestNow(wr);}}internal static void ProcessRequestNow(HttpWorkerRequest wr){_essRequestInternal(wr);}

5.在HttpRunTime中經過一系列的驅動後,將會在ProcessRequestInternal方法中為Http請求分配應用程序。在這一步中還將創建HttpContext對象。

context = new HttpContext(wr, false); // 基於HttpWorkerRequest生成HttpContextIHttpHandler applicationInstance = pplicationInstance(context); // 得到nProcessRequest(context, this._handlerCompletionCallback, context); // 由HttpApplication處理請求

6.經過步驟5後HTTP請求信息才由基本信息轉交給了中的各個對象。接下來的操作會觸發一些列的管道事件,這時的請求才真正轉到HttpModule和HttpHandler中。

接下來我們看看常説的管道事件的創建過程:

internal override void BuildSteps(WaitCallback stepCallback){ArrayList steps = new ArrayList();HttpApplication app = base._application;bool flag = false;UrlMappingsSection urlMappings = onfig()appings;flag = abled && (t > 0);(new datePathExecutionStep(app));if (flag){(new appingsExecutionStep(app));}teEventExecutionSteps(tBeginRequest, steps);teEventExecutionSteps(tAuthenticateRequest, steps);teEventExecutionSteps(tDefaultAuthentication, steps);teEventExecutionSteps(tPostAuthenticateRequest, steps);teEventExecutionSteps(tAuthorizeRequest, steps);teEventExecutionSteps(tPostAuthorizeRequest, steps);teEventExecutionSteps(tResolveRequestCache, steps);teEventExecutionSteps(tPostResolveRequestCache, steps);(new andlerExecutionStep(app));teEventExecutionSteps(tPostMapRequestHandler, steps);teEventExecutionSteps(tAcquireRequestState, steps);teEventExecutionSteps(tPostAcquireRequestState, steps);teEventExecutionSteps(tPreRequestHandlerExecute, steps);(new HandlerExecutionStep(app)); //調用teEventExecutionSteps(tPostRequestHandlerExecute, steps);teEventExecutionSteps(tReleaseRequestState, steps);teEventExecutionSteps(tPostReleaseRequestState, steps);(new FilterExecutionStep(app));teEventExecutionSteps(tUpdateRequestCache, steps);teEventExecutionSteps(tPostUpdateRequestCache, steps);this._endRequestStepIndex = t;teEventExecutionSteps(tEndRequest, steps);(new ExecutionStep());this._execSteps = new cutionStep[t];To(this._execSteps);this._resumeStepsWaitCallback = stepCallback;}

管道事件請求序列圖如下:

標籤:aspnet IIS