[點(diǎn)晴永久免費(fèi)OA]IIS處理并發(fā)請求時(shí)出現(xiàn)的問題及解決
原文鏈接:http://www.cnblogs.com/hgamezoom/p/3082538.html 一個(gè)ASP.NET項(xiàng)目在部署到生產(chǎn)環(huán)境時(shí),當(dāng)用戶并發(fā)量達(dá)到200左右時(shí),IIS出現(xiàn)了明顯的請求排隊(duì)現(xiàn)象,發(fā)送的請求都進(jìn)入等待,無法及時(shí)響應(yīng),系統(tǒng)基本處于不可用狀態(tài)。因經(jīng)驗(yàn)不足,花了很多時(shí)間精力解決這個(gè)問題,本文記錄了我查找問題的過程和最后解決方案,供大家參考。
軟硬件環(huán)境: IBM刀片服務(wù)器,Intel至強(qiáng)處理器,4物理核,16個(gè)邏輯核心,內(nèi)存32G Windows Server2008 Enterprise R2, ASP.NET 4.0 Webform IIS7.5 集成模式
當(dāng)發(fā)現(xiàn)請求明顯延遲,沒有被即時(shí)處理的現(xiàn)象,首先就要查看Windows自帶的性能日志Performance Monitor。 由于我注意到只有對于.aspx或.ashx的請求才會延遲,而.htm或.jpg文件都是即時(shí)響應(yīng)的,所以很明顯問題出在ASP.NET上,于是我選擇了性能監(jiān)視器中的ASP.NET 4.0中的2個(gè)主要計(jì)數(shù)器:Requests Current(當(dāng)前請求數(shù)), Requests Queued(被排隊(duì)的請求數(shù))進(jìn)行觀察。通過觀察發(fā)現(xiàn),當(dāng)前請求數(shù)達(dá)到200左右時(shí),被排隊(duì)的請求數(shù)就從0開始上升,一直到50左右,如果請求數(shù)繼續(xù)上升,則被排隊(duì)數(shù)也隨之上升。當(dāng)被排隊(duì)的請求數(shù)>0時(shí),就意味著這個(gè)時(shí)候去訪問任何.aspx頁面,頁面都會處于長時(shí)間等待中,沒有任何響應(yīng),直到IIS處理完了其他請求,才會開始處理隊(duì)列中的請求。也就是說,當(dāng)排隊(duì)數(shù)長期>0時(shí),系統(tǒng)基本處于不可用的狀態(tài)。 由于這個(gè)系統(tǒng)的頁面布局比較復(fù)雜,采用了大量的Ajax+.ashx的方式,將內(nèi)容分批展示在頁面上,所以對服務(wù)器的請求總數(shù)會比傳統(tǒng)aspx模式來的多一些,一個(gè)頁面全部加載完畢可能需要5-10秒,但我想這不應(yīng)該是造成問題的主要原因,就算系統(tǒng)性能較差,IIS也應(yīng)該足以承受這么小的并發(fā)量的。 為探究到底是系統(tǒng)寫的有問題,還是IIS本身的問題,我拋開我們的系統(tǒng),寫了一個(gè)簡單的頁面,就一個(gè)aspx文件,page_load里sleep 10秒。假設(shè)這就是一個(gè)性能比較差的網(wǎng)站,每個(gè)頁面都要10秒才能展現(xiàn),我將其部署在IIS上測試其性能,我使用的是Microsoft Web Application Stress Tool,模擬發(fā)起80個(gè)線程,每個(gè)連接有4個(gè)Socket,總共相當(dāng)于320個(gè)并發(fā)請求。 測試開始后,可以從下圖中看到,當(dāng)前請求數(shù)立刻攀升到300左右(圖中紅線),然后隊(duì)列中的請求數(shù)也上升到300左右(圖中綠線),就是說在300個(gè)并發(fā)請求下,幾乎所有的請求都被排隊(duì)了,系統(tǒng)基本不可用,通過簡單的測試,這個(gè)問題已經(jīng)得以重現(xiàn)了。
隨著時(shí)間推移,發(fā)現(xiàn)綠線慢慢減少,從300下降到100多,就是系統(tǒng)可用性漸漸提高,有一部分用戶可以正常使用,但大部分還在排隊(duì)。
過了6,7分鐘,隊(duì)列中的請求數(shù)下降到0左右,并有一些小幅波動(dòng)。這個(gè)時(shí)候大部分請求可以被正常處理了。 按照這個(gè)現(xiàn)象分析的話,應(yīng)該是IIS發(fā)現(xiàn)有大量請求在隊(duì)列中,就會試圖增加處理線程數(shù)以滿足要求,但是增長速度有些緩慢。
那是不是系統(tǒng)經(jīng)過了6,7分鐘的適應(yīng)期之后,以后就一直可以在這個(gè)并發(fā)量下穩(wěn)定運(yùn)作了呢?事實(shí)并非如此。我將壓力測試停了幾秒,當(dāng)服務(wù)器的請求數(shù)降為0以后,再重新開啟320個(gè)請求的測試,IIS如何表現(xiàn)?從下圖可以看到,只要請求數(shù)有明顯上升,則等待隊(duì)列又開始達(dá)到最高值,然后緩慢下降,重復(fù)上面的過程。總結(jié)下來就是,當(dāng)出現(xiàn)較大并發(fā)時(shí),IIS的處理請求能力完全跟不上,需要很長時(shí)間才能開出足夠的線程。
然后我做了一個(gè)測試,看看IIS默認(rèn)情況到底能承受多少請求而不排隊(duì)?似乎是在100個(gè)并發(fā)左右,表現(xiàn)尚可,未出現(xiàn)排隊(duì)。
當(dāng)200個(gè)左右就不行了。
然后我將測試程序從sleep10秒改成3秒,對于一個(gè)應(yīng)用系統(tǒng)來說,頁面平均3秒處理時(shí)間的性能該還算比較正常了。但可惜的是,排隊(duì)現(xiàn)象與處理時(shí)間并無太大關(guān)系,排隊(duì)仍然很嚴(yán)重。
針對以上問題,查閱了相關(guān)資料,是否出現(xiàn)排隊(duì)是和應(yīng)用程序池的可用線程有關(guān),通過2個(gè)方法可以查看系統(tǒng)總線程數(shù)和當(dāng)前可用線程數(shù)。 ThreadPool.GetAvailableThreads( out availableWorker, out availableIO); ThreadPool.GetMaxThreads(out maxWorker, out maxIO); 在隊(duì)列請求數(shù)達(dá)到120左右時(shí),通過此方法,得到maxWorker=1600,而availableWorker=1472 因?yàn)榉?wù)器是16核的,ASP.NET4.0默認(rèn)每核可以使用100個(gè)線程,所以maxWorker是1600,1600-120=1480,大致相等。 就是說當(dāng)前有120個(gè)線程被用來處理請求,還有1400多個(gè)處于空閑。關(guān)鍵問題就是為什么這些空閑線程沒有被及時(shí)啟用?
ASP.NET提供的線程配置參數(shù)中,有一個(gè)參數(shù)是非常重要,但是可能被大家忽略的,就是minWorkerThreads。 意指最小工作線程,根據(jù)我們以上的測試結(jié)果,IIS托管線程啟動(dòng)非常慢,微軟也認(rèn)識到了這個(gè)問題,所以提供此參數(shù)用于設(shè)置正常情況下的最小工作線程數(shù)。比如我們系統(tǒng)白天的并發(fā)在200-300之間,則可以設(shè)置最小線程為300,這樣系統(tǒng)響應(yīng)速度可以大幅提高。 據(jù)此,我對配置文件(machine.config)進(jìn)行了如下修改。注意都是針對單個(gè)CPU的,系統(tǒng)會自動(dòng)乘以邏輯CPU的數(shù)量。 <system.web> 相當(dāng)于最小工作線程設(shè)置成了50*16=800。
重啟IIS后進(jìn)行測試,我們得到了以下結(jié)果:
可以看到,由于設(shè)置了合理的最小工作線程數(shù),使得IIS無需不斷創(chuàng)建新線程來處理請求,系統(tǒng)的響應(yīng)能力已可以滿足并發(fā)要求。
除此之外,在IIS6之后引入了一個(gè)新功能叫Web Garden,其設(shè)計(jì)目的是為了在CPU占用較低,但是并發(fā)請求數(shù)比較多的情況下,提升服務(wù)器性能。這正符合我當(dāng)前的情況,于是我啟用了Web Garden,將工作進(jìn)程數(shù)從1調(diào)整到5,在任務(wù)管理器中可以看到w3wp進(jìn)程從原來的1增加到了5,然后重新測試。
同樣的320個(gè)請求下,可以看到除了一開始的幾秒出現(xiàn)了一些排隊(duì),后面基本上表現(xiàn)良好,沒有請求進(jìn)入隊(duì)列。
通過以上兩種方式,都可以有效解決本文開頭提出的問題。但Web Garden是工作在多進(jìn)程模式下,如果應(yīng)用中用到了依賴進(jìn)程的Session和Cache等對象都必須另想辦法,不能保存在服務(wù)器內(nèi)存中,而且Web Garden的多個(gè)進(jìn)程切換時(shí)會有上下文復(fù)制,其資源消耗相對單進(jìn)程要大,這些是需要考慮的因素。 該文章在 2018/9/8 18:06:03 編輯過 |
關(guān)鍵字查詢
相關(guān)文章
正在查詢... |