對ASP.NET網站高性能和多併發的設計的討論

對以下文章內容我要說明下,在財大氣粗的互聯網公司或爲財大氣粗的客戶服務的不缺錢的主,請立即繞行,以下內容不適合您。

以下內容爲客戶計算資源緊缺,預算緊缺,無法通過增大帶寬,增多服務器,購買各種高級服務的程序員們進行討論。

謝謝



對於如何提高應用程序的性能(無論是互聯網應用還是企業級應用)我的觀點一直是考慮一個核心:IO處理。因爲我認爲目前的CPU的處理能力已經是非常高了,正常編寫的在內存中處理的代碼沒有太嚴重的問題都不會對CPU造成很大的影響,性能往往是被IO所限制。由於我和我的團隊溝通時間比較長,所以我們之間的一個簡單的IO說明往往覆蓋了很多的含義,這些IO包括了磁盤IO、網絡IO、內存IO以及各種設備的IO處理。我們的團隊經驗是儘可能的在各種IO處理中尋找出可以提升的效率。



以下,我將從後向前說明我們團隊在提升IO處理的經驗和認識


1 數據庫
數據庫是最明顯的消耗磁盤IO的組件,提高數據的性能有多種,SQL語句寫的好,也是減少了表的掃描(明顯是IO動作),設計合理的索引又是提高了IO處理能力,將不在變化的歷史數據獨立的存儲也減少了複雜IO的處理,爲表設計冗餘的字段也是爲了減少IO讀寫提高性能,將數據表分佈在不同的磁盤上也是提升IO效率。還有其他的各種方式,比如查詢緩存、連接池神馬的,原則同樣如此。

總之,減少數據庫和磁盤之間過度的活動,能儘可能的提升數據庫效率。




2 數據緩存
內存IO的處理效能自然要遠高於磁盤IO,數據的緩存就是減少磁盤操作,或至少減少性能更低的數據庫操作。對於頁面的結果數據緩存我們的通常簡單方案是準備兩個緩存區:一個內存,一個文件
內存的緩存區,我們直接用HttpRuntime.Cache,在這個緩存區中我們放置特徵碼和數據(數據往往是頁面需要的數據,一般我們放置JSON格式),過期策略上我們自然選擇NoAbsoluteExpiration。
當數據需要從內存緩存區中被撤掉時,我們會將這個過期數據再次處理,我們在Cache中有一個集合,這個集合放置了被撤掉的緩存數據的特徵碼,而對應的數據寫入磁盤上的一個文件中。
用戶請求數據時,先檢查特徵碼是否在正常的緩存中,如果不在,則檢查是否在過期區,如果是過期區,則去讀取磁盤文件(至少減少了數據庫開銷),都沒有,那去查數據庫吧。


3 對集合的代碼處理
無論是頁面的javaScript,還是後臺的java,C#,在目前的業務中對集合/數組的操作肯定是最頻繁的,考慮用一些細節上的優化,也可以提高性能
int[] arr = { 1, 3, 6, 7, 3, 6, 7, 3, 5 };

for (int i = 0, max = arr.Length; i < max; i++)
{
    System.Console.WriteLine(arr[i]);
}


類似很多技巧都是減少對集合Length/Count的反覆確認對高頻的集合操作是有益的。當然集合中不能動態的加減數據。數組優先、泛型其次,arrayList最後考慮,這些選取的原因都是減少IO開銷。
還有很多代碼的細節都是可以提高效率,比如對string的認知什麼的。
(林永堅MVP 提示我沒有表達清楚以上意思,我的想法是:集合我的測試是,如果反覆的判斷count會比較慢,不如for的時候吧count先求出來,還有就是儘可能的用數組,因爲數組初始化的時候已經賦值完畢了,且又是強類型,不知道我表達的對不





4 網絡傳輸
後臺數據最終要傳遞給瀏覽器,減少網絡傳輸的字節也是提高吞吐的重點,簡單的說,就是對網絡IO處理優化。減少webform中的ViewState信息,或者乾脆不用webform,改用MVC,或者直接httpcontext自己來控制所有狀態信息。我們採用ashx並且爲不同的服務開闢不同的ashx通道提高性能。由於ashx不必做一系列動作、不用經過一連串的事件處理、一大堆的控件狀態管理(加載並解析ViewState,還原、更新控件的值、保存ViewState等),直接返回操作結果,也就不用耗費更多的服務器資源,返回的格式也非常好靈活,所有用ashx在基於文檔型的網站中我們運用的很好。
另外一點ashx對開發成員的工作隔離也是非常好。
除了編程影響傳輸,頁面需要的圖片和css文件,js文件合理的處理減少HTTP請求也能提高網絡IO效率:比如將圖片合併,js、css壓縮等簡單的方式雖然改變不多,但併發的時候降低服務器的壓力總是好的。




5 頁面渲染和體驗
優化頁面的html結構,有時候爲了加快渲染,不必完全符合W3C的規範,減少div嵌套,使用固定寬度,主要javaScript的細節可以提高很好的體驗。我在chrome中的測試結果可以發現,很多情況下網絡的速度遠遠高於渲染的速度,所以能提高頁面的處理,對個體用戶的體驗是很有效的。




4 數據提交
在可靠的情況下,多考慮異步模式或多線程。對數據庫的提交,web服務的訪問都可以使用異步模型,當然是在可靠的情況下。
頁面的ajax自然也是異步的一種方式,另外js文件的加載也可以異步的方式。


5 鎖

太累了,先不寫了


林永堅MVP還提出了用noSQL,恩,是的,不過我還沒有好好用呢,不能講出什麼來



最後微博小廣告:http://weibo.com/shyleoking


發佈了199 篇原創文章 · 獲贊 8 · 訪問量 59萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章