性能(performance)設計很是重要,對於服務器端實時交易系統來講系統性能的重要性不言而喻,對客戶端軟件來講性能好的軟件也會得到良好的用戶體驗,從而給用戶留下高質量軟件的良好印象。所以在進行架構設計中性能設計很是重要。html
但架構設計實際是一個平衡設計,在可用性、可擴展性、可維護性、可靠性、高性能等之間作個妥協選擇。這些非功能性的需求再加上覆雜的功能性需求,同時還要考慮到項目管理上tight schedule, low cost, perfect effect的三角難題約束,有時需求還不是很明確,vision不是很清楚,這種狀況下系統架構設計真是一門藝術。(可參考筆者另一篇文章《也談系統設計的一些原則》)
單就性能設計來講,在架構設計初期就必定要把系統性能考慮在內,不然等開發完成之後測試發現性能很差就比較難辦,一般要花費較長的時間來診斷性能瓶頸,找到提高的辦法,甚至要改變架構,傷筋動骨,每每形成項目延期。因此性能設計首先要有明確的性能目標,根據用戶和軟件自己的性能要求來設計,合適的就是最好的。其次,要有適當的度量標準和量化的性能指標。最後,要有相應的設計策略,具體的測試方法。
根據個人經驗,影響系統性能主要瓶頸在I/O,包括數據庫,socket,網絡通訊,文件等,例如頻繁查詢數據庫並返回大量結果集,頻繁操做大文件等,這些昂貴的操做會佔用大量的CPU時間。拿系統響應和服務一個事務來講,有幾個Round trip,要經過哪幾層I/O,如何合理的分配這些I/O的調用,下降沒必要要的I/O,都是進行系統性能設計要考慮的。而有些性能問題在初期並不會表現出來,但當拿到實際上線環境下,存在多用戶併發、大數據量的狀況下就會暴露出嚴重的問題。因此性能設計時必定要考慮到I/O,同步,併發,資源爭用,以及大數據量等因素。一般,I/O操做、網絡響應、差的算法、數據庫、以及其餘的低效的資源使用都會致使低劣的性能。
正則表達式
具體可用的設計策略有:
算法
l 緩存以及緩存層(caching layer)
數據庫
在數據層和應用層之間增長數據緩存層,提供全局數據服務。能夠大大減小數據庫往返次數。與讀取數據庫和讀取大文件(如XML文件)比,讀取內存的速度無疑要快的多。因此對常常要訪問的數據進行緩存是很是好的實踐方法。由於如今系統每每內存很大,能夠充分利用大內存,而共享內存更能實現數據併發訪問。
編程
l 多線程(multi-threading)
數組
如今基本上大部分軟件實現多線程或多進程,多線程對單CPU系統還只是順序利用CPU時間和改善用戶體驗,多CPU系統纔是真正的並行。要注意的是多線程不要爭搶訪問同一資源而致使部分串行操做,要作到真正的並行操做多線程並不容易。另外,在多線程間同步一個龐大的資源,過多建立線程又沒有實現線程池也會致使系統性能降低。
緩存
l 負載平衡(load balancing)
性能優化
物理上增長地位對等的集羣服務器(Cluster),經過負載分配算法 分配相應服務器來響應客戶端請求。不少系統支持負載均衡,Windows server2003 IIS就支持負載均衡服務,其餘如WebLogic, WebSphere也有集羣版本支持負載均衡。固然你也能夠本身實現負載分配算法。
服務器
l 數據庫優化(database optimization)
網絡
若是應用程序使用了數據庫,能夠採起許多步驟來消除訪問和寫入數據時的瓶頸:
Ø 標識潛在的索引,但不要建立過多的索引。
Ø 若是使用 SQL Server,則使用 SQL Server 的事件探查器和索引優化嚮導。
Ø 監視處理器的使用;理想範圍是:75-80% 處理器時間。
Ø 使用查詢分析器分析查詢計劃以優化查詢。
Ø 使用存儲過程優化性能。
Ø 標準化寫入的大量數據 —寫入較少的數據。
Ø 取消標準化讀取的大量數據 —讀取較少的數據。
l 文件系統優化
有時候系統性能很差,但當你關閉寫log的功能,性能一會兒提升不少。由於頻繁的打開關閉大log文件時I/O開銷很是大,一樣記錄log到數據庫也同樣。因此,release版儘可能減小寫log,或乾脆移到裸設備上。
頻繁打開關閉文件對系統性能降低程度是驚人的,能夠經過一些變通辦法來減小文件的頻繁操做。
例如,原來的緩存持久化實現是保存在XML文件,每次要得到一個配置項,都打開XML文件,經過XPath拿到這個配置項的值,這樣效率不高,並且容易把這個XML文件lock住;改進的方法是:經過比較XML文件的修改時間(System.IO.File.GetLastWriteTime)判斷是否要再次打開文件,大大提升了效率;另外一個能夠改進的方法是:啓動時讀取全部配置到一個靜態的HashTable,每次要得到一個配置項都從內存HashTable獲取,在最後或適當的時候持久化到XML。
l 代碼性能設計
在編程實現上,代碼性能設計也很重要,一些昂貴的操做會佔用大量的資源和CPU時間。例如,字符串相加沒用StringBuilder, 頻繁建立對象,差勁的排序或遞歸算法,過多的裝箱拆箱,過多的使用反射(Reflection),頻繁new HashTable或大的數組,用異常(Catch Exception)用作正常的邏輯,使用複雜的正則表達式,等等。具體能夠參考《Effective C++》《Effective C#》等書籍。
l 語言的選擇
另外,語言選擇也很重要。好比相對於Java, C#, C++, 大多數OLTP系統用C語言效率高的多,由於在全部的高級程序設計語言中,C程序設計語言的運行效率是公認的。再好比咱們熟悉的一些框架,框架自己是C#或是Java的,但其核心獨立模塊是C++封裝的,這樣能夠達到最佳的性能。因此對於一些特定的業務需求目標和數據的具體狀況,對於核心的模塊或算法,能夠用特定的語言來實現以得到更好的效率。
l 應用層
好比應用層和數據庫的API,在.Net中就有就有DataReader、DataSet和IList等的選擇以及轉換等,這個根據具體狀況而定;還有就是你們常採用的數據的格式化和壓縮,以及採用分頁,減小傳輸的數據量;是否能夠把一部分處理邏輯放在客戶端呢,減小服務端的工做量。界面端也是有不少針對性能優化的考慮,例如繪圖,控件重繪都是很是耗資源的,各控件的數據加載和數據綁定性能也各不相同,儘可能採用惰性加載,異步加載;初始化和啓動速度等都是須要考慮和優化的。