提高ASP.NET性能與可伸縮性的幾個個常用方法剖析
在ASP.NET中,有很多提高性能和可伸縮性的方法,本篇就為朋友們介紹7個,朋友們可以適當的應用在項目之中。
本篇的議題如下:
ASP.NET管道優化
ASP.NET處理配置的優化
ASP.NET管道優化
我們知道,在ASP.NET的處理機制的設計是基於管道模型的,ASP.NET的管道中,有很多的HttpModule。每個要處理的請求經過ASP.NET管道的時候,都會被其中的HttpModule攔截,進行相關的處理之后,再將請求發送給下一個HttpModule。例如,SessionStateModule會攔截請求,並且解析請求中的Session Cookie,然后加載合適的Session到HttpContext中(要知道,每一個Session都會有一個保存在Cookie中的Session Key)。
同時,並且不是在管道中的所有的HttpModule都是必須的,例如,如果我們沒有在項目中使用Membership和Profiler Provider,那么沒我們就沒有必要使用FormsAuthenticate模塊,再如,如果我們沒有使用Windows 身份驗證,那么,我們就可以移除WindowsAuthenticate模塊。
在默認情況下,每次ASP.NET運行時在啟動的時候,都會根據配置文件去加載相應的HttpModule,根據IIS的版本不同,要查看的配置文件也不一樣。
對於IIS 6而言,默認的定義了加載HttpModule的文件就是machine.config(位於:
$WINDOWS$\Microsoft.NET\Framework\$VERSION$\CONFIG)。
對於IIS 7(以及以后版本),默認的配置文件是applicationHost.config(位於:%SystemRoot%\system32\inetsrv)。
我們這里以IIS 6為例子,machine.config配置如下:
我們可以在我們站點的web.config移除我們不需要的Module,如下:
ASP.NET處理配置的優化
ASP.NET處理模型的配置定義了一些ASP.NET在處理請求的時候的一些特性,例如開啟多少個線程進行請求的處理,每一個請求處理線程的過期時間時候多少等。
很多的時候,需要我們自己根據實際情況去修改默認的配置,特別是隨着現在硬件變得越來越便宜和功能越來越強大,對配置對相應的修改,可以極大的提升站點的性能。
以IIS 6而言,默認的處理模型的配置文件依然在machine.config中,如下:
對於IIS 7而言,配置在applicationHost.config,其中,節點的名稱和IIS 6一樣。
這里,我們依然以IIS 6為例子,如下:
首先,看到如此眾多的配置項不要驚慌,要淡定,因為其中每一個項都是非常有用的。下面我們就挑幾個比較常用的,也是重點的來看看。
maxWorkerThreads:這個可以說是見名知意了,就是每一個站點的線程池可以啟動的最多的處理線程的數目。在IIS 6中,每一個邏輯可以開啟的最大線程數目是20個,雙核的CPU那就是40個了。
如果我們的服務器的配置不錯,我們可以將這個數目變大一點,例如100等。這里需要注意的就是,我們要根據實際的情況要配置這個數目,但是我們有一些大致的指導方針:每個線程的開啟需要大約4M的內存,如果我們的服務器的物理內存是2G,那么在理論上,我們是可以同時跑500的處理線程的。
但是很多時候,我們的服務器的內存不可能全部用在這里。因為服務器上面的內存要被用在內核模式和用戶模式。所謂的內核模式,就是Windows內部核心的操作,例如管理線程,進程,管理I/O設備的驅動等。用戶模式就是除了內核模式以外的操作,例如位來自用戶應用程序的請求提供服務,包括IIS,SQL Server等。所有用戶模式的應用程序通過運行在內核模式的執行層訪問資源,例如,如果應用程序要進行磁盤的I/O,那么該請求就會提交到內核模式的執行層,由它來執行請求並且將結果返回給發出請求的用戶模式的進程。
這里面的東西很多,我們就不扯遠了。還是言歸正傳。
如果我們的一個ASP.NET的站點應用不是消耗CPU的操作的應用,那么,我們可以適當的增加更多的處理線程。例如,如果我們的應用程序只要是為外界提供Web服務,或者進行文件的上傳和下載,而這些操作對CPU的壓力不大,這個時候,我們可以配置更多的處理線程。
這里有一點需要注意的就是:盡管,我們配置了100個或者更多,也不見得這100線程就會理解使用,而且還有一個負面的作用就是:線程越多,CPU調度就越復雜。這里我想起了之前有朋友問我一個問題:我們已經配置了最大的處理線程是1000,為什么我們的站點的並發處理能力沒有達到1000呢?我當是給這個一個最簡單的回復:你手里有了1000萬元,你會一下子全部花完嗎?CPU也是這樣,通過配置maxWorkerThreads,我們告訴服務器,最大的限度可以到某個數目,但是不見得服務器就一定按照這個最大的限度來,因為有很多的東西需要服務器去考慮和計算,例如之前的內存問題,等。
另外,如果ASP.NET線程池中沒有可以用來處理請求的線程,那么之后發給站點的請求就會加入到等待隊列中。
需要大家配置之后,多多的進行測試。
另外,為大家給出下面的一個處理線程數目的表格,進行參考:
maxIOThreads:默認是每個邏輯處理有20個線程。I/O處理線程用來處理對I/O的請求,例如對文件的讀和寫的操作,數據庫的操作,Web Service的調用。在設置這個配置的時候,需要考慮站點中文件的上傳、下載的情況,考慮的要點可以參考上面的maxWorkderThreads,另外需要注意的就是,文件的上傳、下載是一個非常消耗內存與磁盤的操作,如果站點有很多的文件要上傳寫入和下載,那么建議重新用另外的服務器去處理,並且將相關的文件緩存在內存中,即,搭建文件緩存服務器。
memoryLimit:配置在IIS 6中w3pw.exe進程可以使用的最大的內存容量,這是一個百分比值。如果站點的處理進程使用內存超過了這個容量限制,那么IIS就會重新的啟動一個進程,並且將請求給這個新的進程,原先的舊的進程就被殺死了(注:這里說的是進程)。如果我們的服務器上只運行一個ASP.NET的站點,而且沒有其他消耗內存的應用,那么,我們可以嘗試將這個配置改為80(即,服務器RAM的80%)。
如果我們的服務器上面有可能導致內存泄露的應用在運行,例如在應用中有COM組件等,那么可以把這個配置值設置的小一點,這樣就可以在站點發生了內存泄露問題之后,我們的處理進程可以快速的被殺死,從而回收一些內存資源。當然,這種設置最小值的的方法只是一個臨時的解決方案,最終還需我們去徹底的解決內存泄露問題。
除了可以設置processModel之外,我們還可以設置其他的配置,例如:system.net節點,我們可以設置一個IP地址的最大的請求連接數(默認是2),如下:
今天就暫時到這里!