請求|請求 處理ASP請求
圖1說明了一個典型的ASP請求的處理流程。該請求由WAM對象進行初始化處理。該WAM對象再把它發送給ASP-RunTime。ASP-RunTime通過建立一個內部頁面對象對其進行響應。
WAM對象是一個自由線程對象。當它調用諸如ASP.DLL的ISAPI擴充時,它使用由IIS-RunTime維護的線程池所分配的MTA模型的線程。
建立ISAPI擴充時面對的一個棘手的問題是,如何處理由這一MTA線程池所帶來的線程並發與同步的問題。ASP-RunTime通過在運行ASP指令碼前把每個ASP請求切換至一個單一執行緒 Apartment(STA),從而使問題得到簡化。ASP-RunTime管理一個獨立的STA輔助線程池(在後台,ASP實際上通過使用COM+線程池來實現這一點)。ASP設計師建立了這種線程池方案,以在並發和資源利用之間提供一種最佳化平衡,同時消除對程式員實現同步的需要。
圖 1
圖2說明了ASP-RunTime是怎樣把每個請求從MTA線程切換到STA線程的。ASP-RunTime調度機制把每個請求都放到一個中央請求隊列中。由ASP管理的線程池中的STA線程監視該隊列並以先進先出方式處理請求。注意,這一線程池的大小是動態變化的。ASP-RunTime在通訊高峰期會產生額外的線程,而在通訊較少時釋放線程。
圖 2
切換到STA線程有效地解決了並發性問題,但是這樣對於效能也有明顯的影響。在一個單獨的MTA線程中隊每個請求進行處理的ISAPI擴充DLL都能提供更快的回應時間。
IIS提供了一種方法以對STA線程池和請求隊列的最大尺寸進行設定。線程池的大小由IIS中繼資料庫中AspProcessorThreadMax主鍵控制。該主鍵的預設設定是每進程每處理器25(評論:此數字最好能找到微軟的相關文檔證明一下。有人說這個數目是10個/CPU)。也就是說,在一台四處理器電腦中,每個處理ASP的進程可以最多有100個輔助線程。除非對調整線程池的相關問題已經考慮成熟,否則應該避免改變該索引值。注意,你不能使用Internet Server Manager來改變這個設定。必須使用管理指令碼或者VB應用來進行修改。
IIS為ASP請求隊列設定了一個最大容量。預設情況下,ASP-RunTime允許隊列最多容納3000個請求(微軟的另一篇文檔指出,這個隊列只能容納500個請求)。一旦超出,後來進入的ASP請求就會被拒絕,返回錯誤資訊為“Server Too Busy”。
可以使用IIS管理對象和ADSI來編程修改AspProcessorThreadMax主鍵和AspRequestQueueMax主鍵。例如,在一個Standard EXE項目中,引用Active DS類型庫,編寫如下代碼:
Dim MyWebServer As ActiveDS.IADs
Set MyWebServer = GetOject(“IIS://Localhost/W3SVC”)
MyWebServer.Put “AspProcessorThreadMax”, 30
MyWebServer.Put “AspRequestQueueMax”, 1500
MyWebServer.SetInfo
下面簡單總結一下在單一處理器電腦上以預設方式安裝的IIS中,ASP線程池是怎麼工作的。該線程池對於每個處理器有25個STA輔助線程可用。當一個請求到達時,就被放到請求隊列中,ASP-RunTime從線程池中調度一個空閑STA線程,如果存在一個可用的話(注意,這種方案允許線程池中的任何線程都可以對請求進行處理)。如果沒有閒置輔助線程,請求就排入佇列。只要隊列沒有達到預設最大容量,所有請求都將得到處理。
來自Ted Pattison的《Programming Distributed Application with Visual Basic 6.0》