2019/3/25 9:28:55
六、 後台處理(lǐ)
通過上(shàng)面的(de)方法你(nǐ)的(de)應用(yòng)程序應該運行(xíng)得很快了,是不是?但(dàn)是在某些時候,程序中的(de)一次請求中可(kě)能(néng)要執行(xíng)一個(gè)非常耗時的(de)任務。如(rú)發送郵件(jiàn)或者是檢查提交的(de)數據的(de)正确性等。
當我們把asp.net Forums 1.0集成在CS中的(de)時侯,發現提交一個(gè)新的(de)帖子的(de)時候會(huì)非常的(de)慢(màn)。每次新增一個(gè)帖子的(de)時侯,應用(yòng)程序首先要檢查這個(gè)帖子是不是重複提的(de),然後用(yòng)“badword”過濾器(qì)來過濾,檢查圖片附加碼,作帖子的(de)索引,把它添加到(dào)合适的(de)隊列中,驗證它的(de)附件(jiàn),最後,發郵件(jiàn)到(dào)它的(de)訂閱者郵件(jiàn)箱中。顯然,這個(gè)工(gōng)作量很大(dà)。
結果是它把大(dà)量的(de)時間都(dōu)花在做索引和(hé)發送郵件(jiàn)中了。做帖子的(de)索引是一項很耗時的(de)操作,而發郵件(jiàn)給訂閱都(dōu)需要連接到(dào)SMTP服務,然後給每一個(gè)訂閱者都(dōu)發一封郵件(jiàn),随著(zhe)訂閱用(yòng)戶的(de)增加,發送郵件(jiàn)的(de)時間會(huì)更長。
索引和(hé)發郵件(jiàn)并不需要在每次請求時觸發,理(lǐ)想狀态下,我們想要批量的(de)處理(lǐ)這些操作,每次隻發25封郵件(jiàn)或者每隔5分(fēn)鍾把所有(yǒu)的(de)要發的(de)新郵件(jiàn)發一次。我們決定使用(yòng)與數據庫原型緩存一樣的(de)代碼,但(dàn)是失敗了,所以又(yòu)不得不回到(dào)VS.NET 2005。
我們在System.Threading命名空間下找到(dào)了Timer類,這個(gè)類非常有(yǒu)用(yòng),但(dàn)卻很少(shǎo)有(yǒu)人(rén)知道,Web開(kāi)發人(rén)員則更少(shǎo)有(yǒu)人(rén)知道了。一旦他(tā)建了該類的(de)實例,每隔一個(gè)指定的(de)時間,Timer類就會(huì)從線程池中的(de)一個(gè)線程中調用(yòng)指定的(de)回調函數。這意味著(zhe)你(nǐ)的(de)asp.net應用(yòng)程序可(kě)以在沒有(yǒu)請求的(de)時候也(yě)可(kě)以運行(xíng)。這就是後以處理(lǐ)的(de)解決方案。你(nǐ)就可(kě)以讓做索引和(hé)發郵件(jiàn)工(gōng)作在後台運行(xíng),而不是在每次請求的(de)時候必須執行(xíng)。
後台運行(xíng)的(de)技術(shù)有(yǒu)兩個(gè)問題,第一是,當你(nǐ)的(de)應用(yòng)程序域卸載後,Timer類實例就會(huì)停止運行(xíng)了。也(yě)就是不會(huì)調用(yòng)回調方法了。另外,因爲CLR的(de)每個(gè)進程中都(dōu)有(yǒu)許多的(de)線程在運行(xíng),你(nǐ)将很難讓Timer獲得一個(gè)線程來執行(xíng)它,或者能(néng)執行(xíng)它,但(dàn)會(huì)延時。Asp.net層要盡量少(shǎo)的(de)使用(yòng)這種技術(shù),以減少(shǎo)進程中線程的(de)數量,或者隻讓請求用(yòng)一小(xiǎo)部分(fēn)的(de)線程。當然如(rú)果你(nǐ)有(yǒu)大(dà)量的(de)異步工(gōng)作的(de)話(huà),那就隻能(néng)用(yòng)它了。
這裏沒有(yǒu)足夠的(de)空間有(yǒu)貼代碼,你(nǐ)可(kě)以從http://www.rob-howard.net/中下載示例程序,請下載Blackbelt TechEd 2004的(de)示例程序。
七、 頁面輸出緩存和(hé)代理(lǐ)服務
Asp.net是你(nǐ)的(de)界面層(或者說應該是),它包含頁面,用(yòng)戶控件(jiàn),服務器(qì)控件(jiàn)(HttpHandlers 和(hé)HttpModules)以及它們生成的(de)内容。如(rú)果你(nǐ)有(yǒu)一個(gè)Asp.net頁面用(yòng)來輸出html,xml,imgae或者是其它的(de)數據,對每一個(gè)請求你(nǐ)都(dōu)用(yòng)代碼來生成相(xiàng)同的(de)輸出内容,你(nǐ)就很有(yǒu)必要考慮用(yòng)頁面輸出緩存了。
你(nǐ)隻要簡單的(de)把下面的(de)這一行(xíng)代碼複制(zhì)到(dào)你(nǐ)的(de)頁面中就可(kě)以實現了:
<%@ PageOutputCache VaryByParams=”none” Duration=”60” %>
你(nǐ)就可(kě)以有(yǒu)效的(de)利用(yòng)第一次請求裏生成的(de)頁面輸出緩存内容,60秒後重新生成一道頁面内容。這種技術(shù)其實也(yě)是運用(yòng)一些低層的(de)Cache API來實現。用(yòng)頁面輸出緩存有(yǒu)幾個(gè)參數可(kě)以配置,如(rú)上(shàng)面所說的(de)VaryByParams參數,該參數表示什(shén)麽時候觸發重輸出的(de)條件(jiàn),也(yě)可(kě)以指定在Http Get或Http Post 請求模式下緩存輸出。例如(rú)當我們設置該參數爲VaryByParams=”Report”的(de)時候,default.aspx?Report=1或者default.aspx?Report=2請求的(de)輸出都(dōu)會(huì)被緩存起來。參數的(de)值可(kě)以是多個(gè)用(yòng)分(fēn)号隔開(kāi)參數。
許多人(rén)都(dōu)沒有(yǒu)意識到(dào)當用(yòng)頁面輸出緩存的(de)時候,asp.net也(yě)會(huì)生成HTTP頭集(HTTP Header)保存在下遊的(de)緩存服務器(qì)中,這些信息可(kě)以用(yòng)于Microsoft Internet安全性中以及加速服務器(qì)的(de)響應速度。當HTTP緩存的(de)頭被重置時,請求的(de)内容會(huì)被緩在網絡資源中,當客戶端再次請求該内容時,就不會(huì)再從源服務器(qì)上(shàng)獲得内容了,而直接從緩存中獲得内容。
雖然用(yòng)頁面輸出緩存不提高(gāo)你(nǐ)的(de)應用(yòng)程序性能(néng),但(dàn)是它能(néng)減少(shǎo)了從的(de)服務器(qì)中加載已緩存頁面内容的(de)次數。當然,這僅限于緩存匿名用(yòng)戶可(kě)以訪問的(de)頁面。因爲一旦頁面被緩存後,就不能(néng)再執行(xíng)授權操作了。
八、 用(yòng)IIS6.0的(de)Kernel Caching
如(rú)果你(nǐ)的(de)應用(yòng)程序沒用(yòng)運行(xíng)在IIS6.0(windows server 2003)中,那麽你(nǐ)就失去了一些很好的(de)提高(gāo)應用(yòng)程序性能(néng)的(de)方法。在第七個(gè)方法中,我講了用(yòng)頁面輸出緩存提高(gāo)應用(yòng)程序的(de)性能(néng)的(de)方法。在IIS5.0中,當一個(gè)請求到(dào)來到(dào)IIS後,IIS會(huì)把它轉給asp.net,當應用(yòng)了頁面輸出緩存時,ASP.NET中的(de)HttpHandler會(huì)接到(dào)該請求,HttpHandler從緩存中把内容取出來并返回。
如(rú)果你(nǐ)用(yòng)的(de)是IIS6.0,它有(yǒu)一個(gè)非常好的(de)功能(néng)就是Kernel Caching,而且你(nǐ)不必修改asp.net程序中任何代碼。當asp.net接到(dào)一個(gè)已緩存的(de)請求,IIS的(de)Kernel C
深圳市南山區南山街(jiē)道南海(hǎi)大(dà)道西(xī)桂廟路(lù)北陽光(guāng)華藝大(dà)廈1棟4F、4G-04
咨詢電話(huà):136 8237 6272
大(dà)客戶咨詢:139 0290 5075
業(yè)務QQ:195006118
技術(shù)QQ:179981967