本文通過一個特別的案例:終端使用者使用瀏覽器向伺服器請求包含100條最新新聞紀錄的頁面,慢慢的展開。
本文集中在ASP.NET Web伺服器(特指用於接收使用者請求,處理商務邏輯和響應HTML的伺服器; 分布式,用戶端,IIS,資料庫和應用伺服器配置和最佳化部分,稍後介紹)
應用程式層級
1.生產環境使用Release版本,而不是Debug版本
2.移除不必要的HTTP Module
- 通過運行時訪問HttpContext.Current.ApplicationInstance.Modules確定使用到的Module
- 通過web.config移除不必要的HTTP Module
- 例如如果你不想使用Session那麼就移除SessionModule
- 本案例中,由於新聞資料和使用者無關,也許我們可以移除很多Module
3.移除不必要的檔案
4.啟用伺服器配置
5.檢查Global等全域性代碼和功能
頁面層級
1.考慮使用比Aspx輕量級的處理模式,例如ashx(httphandler)
- 例如需要一個頁面作為介面提供或者接收資料,(而不是返回一堆HTML)
- aspx頁面生命週期過於笨重,速度緩慢
- aspx內部經常使用伺服器控制項,這也是重量級的主
- aspx內部伺服器控制項產生的ViewState等。。。。
- 個人比較喜歡MVC做頁面和WCF做服務
2.避免使用重量級解決方案
- Asp.net UpdatePanel (這東西搞搞管理員模組也就算了,就不要拿到終端使用者介面來嚇人了)
- EXT,ComponentArt等重量級第三方解決方案
3.避免太深的頁面或者類繼承(例如APage:BPage....)
- 不要設計超級父類,集中了一大堆功能
- 繼承層級過深是較為消耗效能的
4.最佳化邏輯
5.小心使用重量級資源,包括但不僅限於以下內容
- Thread
- Sesssion
- Application
- 核心鎖
- 記憶體
- 大量小對象 (GC壓力,例如大量的使用小字串),可以使用WinDbg+SOS調查
6.設計往往對與效能有至關重要的影響
- 例如長時間的操作,非同步比同步效能要好很多
- 例如大批量同類的操作,大量操作比一次操作一條要好的多
- CPU未滿,而且希望縮短回應時間,考慮多線程
- CPU滿了 考慮空間換時間
- CPU沒滿 考慮時間換空間 (注意 IO壓力大也會導致CPU100% 這個時候還是考慮空間換時間)
- 例如設計時候考慮資料和樣式分離,每次只要重新拉資料就行了例如每次拉取資料的時候,伺服器只返回已經更新了的資料
- 例如按照更新時間排列,如果更新了早一些的資料;那麼每次讀取的時候按照更新時間排列就是一個問題,不如在記憶體中儲存最新的100條資料,有更新的話直接把該集合中最舊的一條移除,最新的一條插入 (可以多留幾條備用)
- 這個例子一般是讀多寫少,讀寫比例可能達到1000:1,是很好的使用緩衝的例子
緩衝
1.頁面緩衝和頁面片段快取
<%@ OutputCache Duration="60" VaryByParam="none"%>
<html>
<script language="C#" runat="server">
void Page_Load(Object sender, EventArgs e)
{
TimeMsg.Text = DateTime.Now.ToString("G");
}
</script>
<body>
<h3>Using the Output Cache</h3>
<p>Last generated on: <asp:label id="TimeMsg" runat="server"/>
</body>
</html>
2.適當的使用使用304緩衝,或者瀏覽器端緩衝
3.使用HttpRuntimeCache快取資料,或使用靜態對象快取資料
- 如果不需要控制到期時間,或者永不到期,建議用靜態對象快取資料,Cache其實還是很重量的
4.就這個方案而言
- 可以把這100條資料放在記憶體中,如果有更新的時候直接更新記憶體,需要讀取的時候直接從記憶體中讀取
- 緩衝的同步和更新永遠都是一個大問題,選擇不同的緩衝取決於你所想要的效能和能承受的缺陷 (例如如果能接受1分鐘的的資料延遲,緩衝)
- 良好的線程同步知識,可以減少很多的BUG
代碼層級
1.將可能的類設計為封閉的(不可繼承)
2.使用更為有效率的方法
- 例如使用Request.QueryString[Key] 而不是Request[Key]
- 例如Int.TryParse,而不是Int.Parse
- 謹慎使用異常
慢慢補充,未完待續。。。。。。
使用工具測量是很重要的一個方面,例如DotTrace,Visual Studio 2010效能測試工具,LoadRunner等壓力測試工具
但是此類工具無法彌補基本概念上的缺失,例如封閉類的效能會比非封閉類的效能好 (在這個方面FxCop之類的工具可以稍微幫你一下) ,
但是工具可以幫你較為準確的測量修改後的效能,最終跑出來的效能才是決定一個最佳化的價值的關鍵
此外高效能一般和可維護性是衝突的,需要找一個平衡點
本人水平有限,希望大家一起討論