現在寫一個的web應用程序變得非常的簡單
許多的程序員都不願花時間去構建一個性能良好的應用程序
本文將要討論提高web應用程序性能的十大方法
我將不限於只討論應用程序的內容
因為它們只是web應用程序的一個子集
本文也不能提供一個完整提高web應用程序性能的指南
因為這需要一本書的篇幅
本文只提供一個提高web應用程序性能的良好的開端
(剩下的只有我們自己慢慢研究了)
在工作這外
我經常去攀巖
在每次攀巖之前
我都會重溫一下攀巖線路圖及看一下前面的成功的攀巖者的建議
因為我們需要它們的成功經驗
同樣的
當你需要修改某個有性能問題的程序或者是要開發一個高性能的站點時
你也需要學習怎麼樣寫一個高性能的web應用程序
我個人的經驗主要來源於在微軟的組擔任程序經理
運行和管理網站
和協助開發Community Server(它是 Forums
Text
and nGallery的集成升級版本軟件)
我想這些經驗能我讓來幫助大家
你也許會想到把你的應用程序劃分成不同的邏輯層
你也可能聽過三層物理架構或N層架構
這是最常用的架構模式
它把不同的程序功能物理的分配給各個硬件來執行
這樣
如果我們想提高應用程序的性能的話
加一些硬件就可以達到目的了
按理說這種方法能提高應用程序的性能
但是我們應該避免使用這種方法
所以
只要有可能
我們都應該把頁面和它用到的組件放到一個應用程序中運行
因為分布式的布署
要用到web services或者Remoting
它將使應用程序的性能下降
%或者更多
對於數據層有點不同
最好還是把它獨立出來布署
用一個單獨的硬件來運行它
雖然這樣
但是數據庫仍然是應用程序性能的瓶頸
因此
當你想優化你的程序的時候
首先想到的地方就應該是優化數據層了
在修改應用程序的出現性能問題的地方之前
你要先確認出問題的地方的程序看起來很嚴密
性能分析器對於查找應用程序哪些地方花費了多長時間非常有用
這些地方是我們用直覺感覺不到的
本文討論兩種類型的性能優化
一種是大的性能優化(big optimizations)
如用的Cache
另一種是小的性能優化(tiny optimizations)
小幅的性能優化有時候非常有用
你只對你的代碼作一個小的改到
然後一次調用它一千或一萬次
作一次大的性能優化
你會發生你的應用程序的速度會有一個很大的提升
作一次小的性能優化
也許每次請求只能提高一微秒
但是如果每天的請求量很大的話
那麼應用程序就有很顯著的性能提升
數據層的性能 當你要優化一個應用程序的性能的時候
你可以按下面的順序工作
你的代碼要訪問數據庫?如果要
訪問數據庫頻率怎麼樣?同樣
這種測試方法也可以用在用web services或Remoting的程序代碼中
本文將不討論用Web services和Remoting的程序優化的問題
如果在你的代碼中有一段必須訪問數據庫的請求
而你在其它的地方又看到實現同樣的功能 的代碼
那麼你首先要優化它
修改和完善繼續測試
除非你有一個非常大的性能問題
你的時間最好花在優化查詢
連接數據庫
返回數據集的大小
以及一次查詢往返回的時間上
根據經驗的總結
讓我們來看看十個能幫助你提升你的應用程序性能的經驗
我將按將它們提升效率的多少從大到小小依次說明
一返回多個數據集 檢查你的訪問數據庫的代碼
看是否存在著要返回多次的請求
每次往返降低了你的應用程序的每秒能夠響應請求的次數
通過在單個數據庫請求中返回多個結果集
可以減少與數據庫通信的時間
使你的系統具有擴展性
也可以減少數據庫服務器響應請求的工作量
如果你是用動態的SQL語句來返回多個數據集
那我建議你用存儲過程來替代動態的SQL語句
是否把業務邏輯寫到存儲過程中
這個有點爭議
但是我認為
把業務邏輯寫到存儲過程裡面可以限制返回結果集的大小
減小網絡數據的流量
在邏輯層也不用在過濾數據
這是一個好事情
用SqlCommand對象的ExecuteReader方法返回一個強類型的業務對象
再調用NextResult方法來移動數據集指針來定位數據集
示例一演示了一個返回多個ArrayList強類型對象的例子
只從數據庫中返回你需要的數據可以大大的減小你的服務器所耗用的內存
二對數據進行分頁 ASP
NET的DataGrid有一個非常有用的功能
分頁
如果DataGrid允許分頁
在某一時刻它只下載某一頁的數據
另外
它有一個數據分頁的濟覽導航欄
它讓你可以選擇浏覽某一頁
而且每次只下載一頁的數據
但是它有一個小小的缺點
就是你必須把所有的數據都綁定到DataGrid中
也就是說
你的數據層必須返回所有的數據
然後DataGrid再根據當前頁過濾出當前頁所需要的數據顯示出來
如果有一個一萬條記錄的結果集要用DataGrid進行分頁
假設DataGrid每頁只顯示
條數據
那就意味著每次請求都有
條數據都是要丟棄的
每次請求都要返回這麼大的數據集
對應用程序的性能影響是非常大的
一個好的解決方案是寫一個分頁的存儲過程
例子
是一個用於對Northwind數據庫orders表的分頁存儲過程
你只需要傳當前頁碼
每頁顯示的條數兩個參數進來
存儲過程會返回相應的結果
在服務器端
我專門寫了一個分頁的控件來處理數據的分頁
在這裡
我用了第一個方法
在一個存儲過程裡面返回了兩個結果集
數據記錄總數和要求的結果集
返回的記錄總數取決於要執行查詢
例如
一個where條件可以限制返回的結果集的大小
因為在分頁界面中必須要根據數據集記錄的大小來計算總的頁數
所以必須要返回結果集的記錄數
例如
如果一共有
條記錄
如果用where條件就可以過濾成只返回
條記錄
存儲過程的分頁邏輯應該知道返回那些需要顯示的數據
三連接池 用TCP來連接你的應用程序與數據庫是一件昂貴的事情(很費時的事情)
微軟的開發者可以通過用連接池來反復的使用數據庫的連接
比起每次請求都用TCP來連一次數據庫
連接池只有在不存在有效的連接時才新建一個TCP連接
當關閉一個連接的時候
它會被放到池中
它仍然會保持與數據庫的連接
這樣就可以減少與數據庫的TCP連接次數
當然
你要注意那些忘記關的連接
你應在每次用完連接後馬上關閉它
我要強調的是
無論什麼人 framework中的GC(垃圾收集器)總會在你用完連接對象後調用連接對象的Close或者Dispose方法顯式的關閉你的連接
不要期望CLR會在你想象的時間內關掉連接
雖然CLR最終都要銷毀對象和關閉邊接
但是我們並不能確定它到底會在什麼時候做這些事情
要用連接池優化
有兩條規則
第一
打開連接
處理數據
然後關閉連接
如果你必須在每次請求中多次打開或關閉連接
這好過一直打開一個邊接
然後把它傳到各個方法中
第二
用相同的連接字符串(或者用相同的用戶標識
當你用集成認證的時候)
如果你沒有用相同的連接字符串
如你用基於登錄用戶的連接字符串
這將不能利用連接池的優化功能
如果你用的是集成的論證
因為用戶很多
所以你也不能充分利用連接池的優化功能
NET CLR提供了一個數據性能計數器
它在我們需要跟蹤程序性能特性的時候非常有用
當然也包括連接池的跟蹤了
無論你的應用程序什麼時候要連在另一台機子的資源
如數據庫
你都應該重點優化你連資源所花的時間
接收和發送數據的時間
以及往返回之間的次數
優化你的應用程序中的每一個處理點(process hop)
它是提高你的應用的性能的出發點
應用程序層包含與數據層連接
傳送數據到相應的類的實例以及業務處理的邏輯
例如
在Community Server中
要組裝一個Forums或者Threads集合
然後應用業務邏輯
如授權
更重要的
這裡要完成緩存邏輯
四 ASPNET緩存API 在寫應用程序之前
你要做的第一件事是讓應用程序最大化的利用ASP
NET的緩存功能
如果你的組件是要在應用程序中運行
你只要把System
Web
dll引用到你的項目中就可以了
然後用HttpRuntime
Cache屬性就可訪問Cache了(也可以通過Page
Cache或HttpContext
Cache訪問)
有以下幾條緩存數據的規則
第一
數據可能會被頻繁的被使用
這種數據可以緩存
第二
數據的訪問頻率非常高
或者一個數據的訪問頻率不高
但是它的生存周期很長
這樣的數據最好也緩存起來
第三是一個常常被忽略的問題
有時候我們緩存了太多數據
通常在一台X
的機子上
如果你要緩存的數據超過
M的話
就會出現內存溢出的錯誤
所以說緩存是有限的
換名話說
你應該估計緩存集的大小
把緩存集的大小限制在
以內
否則它可能會出問題
在中
如果緩存過大的話也會報內存溢出錯誤
特別是如果緩存大的DataSet對象的時候
這裡有幾個你必須了解的重要的緩存機制
首先是緩存實現了
最近使用
原則( a least
recently
used algorithm)
當緩存少的時候
它會自動的強制清除那些無用的緩存
其次
條件依賴
強制清除原則(expiration dependencies)
條件可以是時間
關鍵字和文件
以時間作為條件是最常用的
在
中增加一更強的條件
就是數據庫條件
當數據庫中的數據發生變化時
就會強制清除緩存
要更深入的了解數據庫條件依賴請看Dino Esposito 在MSDN雜志
年七月刊的Cutting Edge專欄文章
的緩存架構如下圖所示
五 預請求緩存 在前面
我提到過即使我們只對某些地方作了一個小小的性能改進也可以獲得大的性能提升
我非常喜歡用預請求緩存來提
From:http://tw.wingwit.com/Article/program/net/201311/13761.html