編寫高效能 Web 應用程式的10個技巧

來源:互聯網
上載者:User
web|程式|技巧|效能|技巧|效能 本文討論:
常見的 ASP.NET 效能神話
有用的 ASP.NET 效能技巧和訣竅
在 ASP.NET 中處理資料庫的一些建議
緩衝以及用 ASP.NET 進行幕後處理
本文使用下列技術:ASP.NET,.NET 架構,IIS

  用 ASP.NET 編寫 Web 應用程式其輕鬆程度令人難以置信。它是如此的容易,以至於許多開發人員不用花費多少時間來構築其應用便能獲得非常好的效能。在本文中,我將給出10個編寫高效能 Web 應用程式的技巧。我的評論不僅僅局限與 ASP.NET 應用,因為它們只是 Web 應用程式的一個子集。本文也不是 Web 應用程式效能調整的權威指南——這方面的內容可以寫成一本書。相反,本文可以被視作一個好的起點。
  在廢寢忘食地工作之前,我常常要去攀岩。在攀岩之前,我總是要看一下指南手冊中的線路並閱讀以前來此一遊的人留下的建議和忠告。但是,不管指南手冊有多磨好,在嘗試一次特定的具有挑戰性的攀爬之前,你都必須付諸實際的行動。同樣,在你面臨解決的效能問題或者營運一個高輸送量的網站之前,你只能想方設法編寫高效能 Web 應用程式。
  我們個人經驗來自在微軟 ASP.NET 團隊從事底層架構程式經理,運行和管理 www.asp.net ,並協助架構 Community Server 過程中的經曆,Community Server 是幾個有名的 ASP.NET 應用程式的下一個版本(它將 ASP.NET Forums,.Text 和 nGallery 整合到一個平台)。我確信這些協助過我的技巧也會對你有所裨益。
  你應該考慮將應用程式分離成幾個邏輯層。你可能聽說過術語3-層(或n-層)物理體繫結構。它們通常是跨進程和/或硬體對功能進行物理劃分的規定的體繫結構模式。當系統需要伸縮時,更多的硬體能被添加。然而,總是應該避免與進程和機器忙碌程度相關的效能問題。所以,不管什麼時候,只要可能,都要在相同的應用中一起運行 ASP.NET 頁面及其相關的組件。
  由於代碼和層之間的邊界分離,使用 Web 服務或遠程調用將降低20%以上的效能。
  資料層則稍微有些不同,因為資料庫通常都用專門的硬體。但是,資料庫的處理成本仍然很高,因此最佳化代碼時,資料層的效能應該是首當其充要關注的地方。
  在著手解決你的應用程式的效能問題之前,一定要剖析應用程式,確定問題之所在。擷取關鍵的效能計數器值(如實現垃圾收集所花時間之百分比的效能計數器的值)對於尋找應用程式在何處最耗時也是非常重要的。憑藉直覺常常也能找到耗時所在。
  本文所描述的效能改進有兩種類型:大型最佳化,如使用 ASP.NET Cache,以及不斷重複進行的微型最佳化。這些微型最佳化有時很有意思。對代碼的小小改動便會引起很大的動靜,產產生千次的調用。對於大型最佳化,你可能會看到整體效能的大跳躍。而對微型最佳化,給定請求可能只是毫秒級的調整,但按每天的請求總數計算,其結果的改進可能是巨大的。

資料層的效能

  當調整某個應用程式的效能時,有一個簡單的試金石,你可以用它按先後次序:檢查代碼是否存取資料庫?如果是,多長時間存取一次?注意相同的測試也可以被應用於使用 Web 服務或遠程調用的代碼,但我們本文中不涉及這方面內容。
  如果在特定的代碼流程中必須具有對資料庫的請求以及要考察其它方面,如:想對字串處理進行優先最佳化,那麼暫且把它放一放,先按照上面定好的優先次序來做。除非你有異乎尋常的效能問題,否則你的時間應該用在嘗試最佳化與資料庫的串連所花的時間,返回的資料量以及多長時間往返一次和資料庫的通訊上。
  有了這些概括資訊,下面就讓我們來看看能協助你改善應用程式效能的十個技巧。我將從能獲得最顯著效果的改變開始。

技巧 1 —— 返回多個結果集

  複審你的資料庫代碼,看看是否有多於一次的對資料庫的訪問請求。這樣每次往返資料庫都降低你的應用程式能處理的每秒請求數。通過在單個資料庫請求中返回多結果集,你能降低與資料庫通訊的總體時間。同時你也將使系統更具伸縮性,因為你減少了資料庫伺服器處理請求的負擔。
  雖然你可以用動態 SQL 返回多結果集,我更喜歡使用儲存過過程。是否將商務邏輯駐留在預存程序當中是個有待爭論的問題,但我認為,如果預存程序中的邏輯能約束返回的資料(降低資料集的尺寸,在網路上傳輸的時間以及邏輯層不必過慮資料),這是一件好事情。
  使用 SqlCommand 命令執行個體及其 ExecuteReader 方法來處理強型別的各個業務類,你通過調用 NextResult 可以向前移動結果集指標。Figure 1 示範了處理幾個帶類型的 ArrayLists 例子會話。從資料庫只返回你需要的資料還會降低伺服器上記憶體的分配。

技巧 2 —— 分頁資料存取

  ASP.NET DataGrid 提供了非常好的能力:資料分頁支援。當啟用 DataGrid 中的分頁功能,則每次只顯示固定數量的記錄。此外,分頁使用者介面也會顯示在 DataGrid 底部用於導航記錄。分頁使用者介面允許你向前向後導航所顯示的記錄,一次顯示固定數量的記錄。
  有一個美中不足的是用 DataGrid 分頁需要將所有資料邦定到此柵格控制項(gird)。例如,你的資料層必須返回所有資料,然後 DataGrid 將根據當前頁過濾掉所有顯示的記錄。當你通過 DataGrid 進行分頁時,如果有 100,000 條記錄被返回,那麼每個請求有 99,975 條記錄將被廢棄掉(假設頁尺寸為 25)。當記錄數不斷增加,此應用程式的效能便會遭受痛苦,因為每次請求所要發送的資料會越來越多。
  編寫較好的分頁代碼的一個好的方法是用預存程序。Figure 2 示範了一個用 Northwind 資料庫中 Orders 表通過預存程序分頁的例子。很簡單,只要你在頁面中傳遞索引以及頁尺寸即可。相應的結果集先被計算然後被返回。
  在 Community Server 中,我們編寫了幾個分頁控制項來完成資料分頁。你將會看到,我使用了技巧 1 中討論的思路,從一個預存程序中返回連個結果集:總記錄數和請求的資料。
  返回的總記錄數依賴於所執行的查詢不同而不同。例如,某個 WHERE 子句可被用於約束返回的資料。為了計算在分頁使用者介面顯示的總頁數,返回的總記錄數必須是已知的。例如,如果有 1,000,000 條記錄,用一個 WHERE 子句對之過濾後為 1,000 條記錄,則分頁邏輯必須要知道總記錄數以便在分頁使用者介面中正確呈現。

技巧 3 —— 串連池

  建立 Web 應用程式與 SQL Server 之間的 TCP 串連是一項昂貴的操作。微軟的開發人員利用串連池技術已經有好長一段時間了,這個技術使他們能重用到資料庫的串連。而不是每次請求都建立新的 TCP 串連,新串連僅在串連池中得不到串連時才建立。當串連被關閉時,它被返回到串連池中,在那裡它仍然保持與資料庫的串連,與完全斷開 TCP 串連相反。
  當然,你需要提防泄漏的串連。當你處理完畢,一定要關閉串連。重申一次:不管人們怎麼吹噓微軟 .NET 架構中的垃圾收集特性,每當你處理完畢,一定要顯式地調用連線物件的 Close 或 Dispose 方法。不要指望通用語言執行平台(CLR)來為你定時清除和關閉串連。CLR 最終將銷毀類並強行關閉串連,但你無法保證該對象的垃圾收集屆時會起作用。
  為了充分用好串連池,有幾條規則必須瞭然於心。首先,開啟串連,進行處理,然後關閉串連。寧願每個請求的串連開啟和關閉多次,也不要保持串連開啟狀態以及在不同的方法間將它傳來傳去。其次,使用相同的串連串(如果你使用整合身份檢查,那麼也要用相同的線程身份)。如果你不用相同的串連串,例如,根據登入使用者來定製串連串,你將無法得到串連池所提供的相同的最佳化值。當類比大使用者量情形時,如果你使用整合身份檢查,那麼你的串連池將效力大減。.NET CLR 資料效能計數器在試圖跟蹤任何與串連池有關的效能問題時是非常有用的。
  不管什麼時候,只要你的應用程式串連到運行在其它進程中的資源,比如某個資料庫,你都應該針對串連到資源所耗時間,發送和接收資料所耗時間以及往返次數進行最佳化。為了實現較好的效能,應該首當其充最佳化應用程式中任何種類的忙碌進程。
  應用程式層包含到資料層的串連以及將資料轉換成有意義的類執行個體和業務處理的邏輯。以 Community Server 為例,你要在其中處理 Forums 和 Threads 集合;以及應用許可這樣的商務規則;尤其重要的是緩衝(Caching)邏輯也實現其中。

技巧 4 —— ASP.NET Cache API

  在編寫代碼之前要做的頭等大事之一是最大限度地構建應用程式層並發掘 ASP.NET 的 Cache 特性。
  如果你的組件在 ASP.NET 應用程式內運行,那麼你只需要在應用程式工程中引用 System.Web.dll 即可。當你需要訪問 Cache 時,用 HttpRuntime.Cache 屬性(相同的對象也可以通過 Page.Cache 和 HttpContext.Cache 訪問)。
  緩衝資料有幾個準則。首先,如果資料能被使用多次,緩衝是個好的後選方案。其次,如果資料對給定請求或使用者是一般的資料而非專用資料,那麼最好是選擇緩衝。如果資料使用者或請求專用,如果需要儲存期很長但可能不被經常使用,那麼仍然要用緩衝。第三,常常被忽略的一個準則是有時緩衝太多的東西。一般來說,在x86機器上,為了降低記憶體不足錯誤的幾率,運行某個進程不要超過800MB私人位元組。因此,緩衝應該有個上限。換句話說,你也許能重用某個計算的結果,但如果該計算有10個參數,你可能試圖針對10個置換進行緩衝,這樣做可能會給你帶來麻煩。ASP.NET 提供的最常見的容錯是由覆蓋緩衝導致的記憶體不足錯誤,尤其是大型資料集。
  Cache 有幾個重要特性是必須要瞭解的。第一個是 Cache 實現了最近最少使用(least-recently-used)演算法,允許 ASP.NET 強制 Cache 清除操作 —— 如果可用記憶體下降到低水平 —— 則自動從 Cache 中刪除不使用的項目。第二個是 Cache 支援依賴性到期特性,它能強制包括時間,索引值,檔案失效。時間常常被使用,但 ASP.NET 2.0 引入了具有更強大的失效類型:資料庫緩衝失效。也就是當資料庫中的資料改變時,緩衝中的條目會自動刪除。有關資料庫緩衝失效的更多資訊參見 Dino Esposito 在 MSDN 雜誌 2004 年七月刊的 Cutting Edge 專欄文章。該緩衝的體繫結構,參見 Figure 3。


Figure 3 ASP.NET Cache

技巧 5 —— 預請求緩衝(Per-Request Caching)


  在本文前面,我曾提到對頻繁執行的代碼塊所做的小小改動可能產生很大的,整體效能的提升。我把其中一個我特別中意的叫做預請求緩衝(per-request caching)。



相關文章

Beyond APAC's No.1 Cloud

19.6% IaaS Market Share in Asia Pacific - Gartner IT Service report, 2018

Learn more >

Apsara Conference 2019

The Rise of Data Intelligence, September 25th - 27th, Hangzhou, China

Learn more >

Alibaba Cloud Free Trial

Learn and experience the power of Alibaba Cloud with a free trial worth $300-1200 USD

Learn more >

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。