提高ASP.NET效能與延展性的幾個個常用方法剖析
在ASP.NET中,有很多提高效能和延展性的方法,本篇就為朋友們介紹7個,朋友們可以適當的應用在項目之中。
本篇的議題如下:
ASP.NET管道最佳化
ASP.NET處理配置的最佳化
/Files/yanyangtian/提高ASP.NET效能與延展性的幾個常用方法剖析.pdf
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),如下:
今天就暫時到這裡!