1. 程式人生 > >對ASP.NET網站高效能和多併發的設計的討論

對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#,在目前的業務中對集合/陣列的操作肯定是最頻繁的,考慮用一些細節上的優化,也可以提高效能

  1. int[] arr = { 1, 3, 6, 7, 3, 6, 7, 3, 5 };  
  2. for (int i = 0, max = arr.Length; i < max; i++)  
  3. {  
  4.     System.Console.WriteLine(arr[i]);  
  5. }  


類似很多技巧都是減少對集合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,恩,是的,不過我還沒有好好用呢,不能講出什麼來