熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> .NET編程 >> 正文

提高ASP.Net應用程序性能的十大方法(上)

2022-06-13   來源: .NET編程 
  本文討論:

  ●提高aspnet應用程序性能的常說的神話

  ●有用的提高aspnet應用程序性能的技巧

  ●Aspnet應用程序操作數據庫的建議

  ●Aspnet中的緩存與後台處理進程

  現在寫一個aspnet的web應用程序變得非常的簡單許多的程序員都不願花時間去構建一個性能良好的應用程序本文將要討論提高web應用程序性能的十大方法我將不限於只討論aspnet應用程序的內容因為它們只是web應用程序的一個子集本文也不能提供一個完整提高web應用程序性能的指南因為這需要一本書的篇幅本文只提供一個提高web應用程序性能的良好的開端(剩下的只有我們自己慢慢研究了)

  在工作這外我經常去攀巖在每次攀巖之前我都會重溫一下攀巖線路圖及看一下前面的成功的攀巖者的建議因為我們需要它們的成功經驗同樣的當你需要修改某個有性能問題的程序或者是要開發一個高性能的站點時你也需要學習怎麼樣寫一個高性能的web應用程序

  我個人的經驗主要來源於在微軟的aspnet組擔任程序經理運行和管理wwwaspnet網站和協助開發Community Server(它是aspnet ForumsText and nGallery的集成升級版本軟件)我想這些經驗能我讓來幫助大家

  你也許會想到把你的應用程序劃分成不同的邏輯層你也可能聽過三層物理架構或N層架構這是最常用的架構模式它把不同的程序功能物理的分配給各個硬件來執行這樣如果我們想提高應用程序的性能的話加一些硬件就可以達到目的了按理說這種方法能提高應用程序的性能但是我們應該避免使用這種方法所以只要有可能我們都應該把aspnet頁面和它用到的組件放到一個應用程序中運行

  因為分布式的布署要用到web services或者Remoting它將使應用程序的性能下降%或者更多

  對於數據層有點不同最好還是把它獨立出來布署用一個單獨的硬件來運行它雖然這樣但是數據庫仍然是應用程序性能的瓶頸因此當你想優化你的程序的時候首先想到的地方就應該是優化數據層了

  在修改應用程序的出現性能問題的地方之前你要先確認出問題的地方的程序看起來很嚴密性能分析器對於查找應用程序哪些地方花費了多長時間非常有用這些地方是我們用直覺感覺不到的

  本文討論兩種類型的性能優化一種是大的性能優化(big optimizations)如用aspnet的Cache另一種是小的性能優化(tiny optimizations)小幅的性能優化有時候非常有用你只對你的代碼作一個小的改到然後一次調用它一千或一萬次作一次大的性能優化你會發生你的應用程序的速度會有一個很大的提升作一次小的性能優化也許每次請求只能提高一微秒但是如果每天的請求量很大的話那麼應用程序就有很顯著的性能提升

  數據層的性能

  當你要優化一個應用程序的性能的時候你可以按下面的順序工作你的代碼要訪問數據庫?如果要訪問數據庫頻率怎麼樣?同樣這種測試方法也可以用在用web services或Remoting 的程序代碼中本文將不討論用Web services和Remoting的程序優化的問題

  如果在你的代碼中有一段必須訪問數據庫的請求而你在其它的地方又看到實現同樣的功能 的代碼那麼你首先要優化它修改和完善繼續測試除非你有一個非常大的性能問題你的時間最好花在優化查詢連接數據庫返回數據集的大小以及一次查詢往返回的時間上

  根據經驗的總結讓我們來看看十個能幫助你提升你的應用程序性能的經驗我將按將它們提升效率的多少從大到小小依次說明

  返回多個數據集

  檢查你的訪問數據庫的代碼看是否存在著要返回多次的請求每次往返降低了你的應用程序的每秒能夠響應請求的次數通過在單個數據庫請求中返回多個結果集可以減少與數據庫通信的時間使你的系統具有擴展性也可以減少數據庫服務器響應請求的工作量
如果你是用動態的SQL語句來返回多個數據集那我建議你用存儲過程來替代動態的SQL語句是否把業務邏輯寫到存儲過程中這個有點爭議但是我認為把業務邏輯寫到存儲過程裡面可以限制返回結果集的大小減小網絡數據的流量在邏輯層也不用在過濾數據這是一個好事情
用SqlCommand對象的ExecuteReader方法返回一個強類型的業務對象再調用NextResult方法來移動數據集指針來定位數據集示例一演示了一個返回多個ArrayList強類型對象的例子只從數據庫中返回你需要的數據可以大大的減小你的服務器所耗用的內存

  對數據進行分頁

  ASPNET的DataGrid有一個非常有用的功能分頁如果DataGrid允許分頁在某一時刻它只下載某一頁的數據另外它有一個數據分頁的濟覽導航欄它讓你可以選擇浏覽某一頁而且每次只下載一頁的數據

  但是它有一個小小的缺點就是你必須把所有的數據都綁定到DataGrid中也就是說你的數據層必須返回所有的數據然後DataGrid再根據當前頁過濾出當前頁所需要的數據顯示出來如果有一個一萬條記錄的結果集要用DataGrid進行分頁假設DataGrid每頁只顯示條數據那就意味著每次請求都有條數據都是要丟棄的每次請求都要返回這麼大的數據集對應用程序的性能影響是非常大的

  一個好的解決方案是寫一個分頁的存儲過程例子是一個用於對Northwind數據庫orders表的分頁存儲過程你只需要傳當前頁碼每頁顯示的條數兩個參數進來存儲過程會返回相應的結果

  在服務器端我專門寫了一個分頁的控件來處理數據的分頁在這裡我用了第一個方法在一個存儲過程裡面返回了兩個結果集數據記錄總數和要求的結果集

  返回的記錄總數取決於要執行查詢例如一個where條件可以限制返回的結果集的大小因為在分頁界面中必須要根據數據集記錄的大小來計算總的頁數所以必須要返回結果集的記錄數例如如果一共有條記錄如果用where條件就可以過濾成只返回條記錄存儲過程的分頁邏輯應該知道返回那些需要顯示的數據

  連接池

  用TCP來連接你的應用程序與數據庫是一件昂貴的事情(很費時的事情)微軟的開發者可以通過用連接池來反復的使用數據庫的連接比起每次請求都用TCP來連一次數據庫連接池只有在不存在有效的連接時才新建一個TCP連接當關閉一個連接的時候它會被放到池中它仍然會保持與數據庫的連接這樣就可以減少與數據庫的TCP連接次數

  當然你要注意那些忘記關的連接你應在每次用完連接後馬上關閉它我要強調的是無論什麼人說net framework中的GC(垃圾收集器)總會在你用完連接對象後調用連接對象的Close或者Dispose方法顯式的關閉你的連接不要期望CLR會在你想象的時間內關掉連接雖然CLR最終都要銷毀對象和關閉邊接但是我們並不能確定它到底會在什麼時候做這些事情

  要用連接池優化有兩條規則第一打開連接處理數據然後關閉連接如果你必須在每次請求中多次打開或關閉連接這好過一直打開一個邊接然後把它傳到各個方法中第二用相同的連接字符串(或者用相同的用戶標識當你用集成認證的時候)如果你沒有用相同的連接字符串如你用基於登錄用戶的連接字符串這將不能利用連接池的優化功能如果你用的是集成的論證因為用戶很多所以你也不能充分利用連接池的優化功能NET CLR提供了一個數據性能計數器它在我們需要跟蹤程序性能特性的時候非常有用當然也包括連接池的跟蹤了

  無論你的應用程序什麼時候要連在另一台機子的資源如數據庫你都應該重點優化你連資源所花的時間接收和發送數據的時間以及往返回之間的次數優化你的應用程序中的每一個處理點(process hop)它是提高你的應用的性能的出發點
應用程序層包含與數據層連接傳送數據到相應的類的實例以及業務處理的邏輯例如在Community Server中要組裝一個Forums或者Threads集合然後應用業務邏輯如授權更重要的這裡要完成緩存邏輯

   ASPNET緩存API

  在寫應用程序之前你要做的第一件事是讓應用程序最大化的利用ASPNET的緩存功能

  如果你的組件是要在Aspnet應用程序中運行你只要把SystemWebdll引用到你的項目中就可以了然後用HttpRuntimeCache屬性就可訪問Cache了(也可以通過PageCache或HttpContextCache訪問)

  有以下幾條緩存數據的規則

  第一數據可能會被頻繁的被使用這種數據可以緩存

  第二數據的訪問頻率非常高或者一個數據的訪問頻率不高但是它的生存周期很長這樣的數據最好也緩存起來

  第三是一個常常被忽略的問題有時候我們緩存了太多數據通常在一台X的機子上如果你要緩存的數據超過M的話就會出現內存溢出的錯誤所以說緩存是有限的換句話說你應該估計緩存集的大小把緩存集的大小限制在以內否則它可能會出問題在Aspnet中如果緩存過大的話也會報內存溢出錯誤特別是如果緩存大的DataSet對象的時候

  這裡有幾個你必須了解的重要的緩存機制首先是緩存實現了最近使用原則( a leastrecentlyused algorithm)當緩存少的時候它會自動的強制清除那些無用的緩存其次 條件依賴強制清除原則(expiration dependencies)條件可以是時間關鍵字和文件以時間作為條件是最常用的在aspnet中增加一更強的條件就是數據庫條件當數據庫中的數據發生變化時就會強制清除緩存要更深入的了解數據庫條件依賴請看Dino Esposito 在MSDN雜志年七月刊的Cutting Edge專欄文章Aspnet的緩存架構如下圖所示

   預請求緩存

  在前面我提到過即使我們只對某些地方作了一個小小的性能改進也可以獲得大的性能提升我非常喜歡用預請求緩存來提升程序的性能

  雖然Cache API設計成用來保存某段時間的數據而預請求緩存只是保存某個時期的某個請求的內容如果某個請求的訪問頻率高而且這個請求只需要提取應用修改或者更新數據一次那麼就可以預緩存該請求我們舉個例子來說明

  在CS的論壇應用程序中每一個頁面的服務器控件都要求得到用於決定它的皮膚(skin)的自定義的數據以決定用哪個樣式表及其它的一些個性化的東西這裡面的某些數據可能要長時間的保存有些時間則不然如控件的skin數據它只需要應用一次而後就可以一直使用

  要實現預請求緩存用Aspnet 的HttpContext類HttpContext類的實例在每一個請求中創建在請求期間的任何地方都可以通過HttpContextCurrent屬性訪問HttpContext類有一個Items集合屬性在請求期間所有的對象和數據都被添加到這個集合中緩存起來和你用Cache緩存訪問頻率高數據一樣你可以用HttpContextItems緩存那些每個請求都要用到的基礎數據它背後的邏輯很簡單我們向HttpContextItems中添加一個數據然後再從它裡面讀出數據


From:http://tw.wingwit.com/Article/program/net/201311/15792.html
    推薦文章
    Copyright © 2005-2022 電腦知識網 Computer Knowledge   All rights reserved.