對於一個信息系統的後端服務(如一個web服務),其性能優化應該如何着手?這裏試圖從通常性方法論的角度,給出一些思路。java
1、性能優化流程
性能優化通常流程以下圖所示:linux
2、性能指標
用來衡量一個系統的性能指標一般有:web
- TPS/QPS:Transaction Per Second,每秒處理事務數量;Query Per Second,每秒請求次數。這兩個指標反應的是系統吞吐量,每每用於描述系統在必定的併發壓力下的性能表現。
- RT:Response Time,響應時間,執行一個請求從開始到最後收到響應數據所花費的整體時間,即從客戶端發起請求到收到服務器響應結果的時間。它反應的是系統的響應速度。
一個描述系統的指望性能指標的例子:redis
- 無併發環境下,單次請求的響應時間小於1秒;
- 在【100用戶同時操做,QPS達到500,並持續30分鐘】的併發壓力下,系統的TPS達到300以上,平均響應時間小於5秒,90%響應時間小於3秒。(90%響應時間意思是指90%的請求的響應時間,依據不一樣的性能需求,也能夠指定80%RT,95%RT等等。)
3、尋找性能瓶頸及其優化對策的指導方針
按照性能優化通常流程,你須要先衡量系統目前的性能表現。因此首先你須要耗時統計與資源監控。算法
而後你能夠從三個層面去考慮如何尋找性能瓶頸及其優化策略:數據庫
3.1 耗時統計
響應時間是一個系統最重要的性能指標之一。對於系統的用戶而言,響應時間是最直接影響使用用戶體驗的性能參數。後端
咱們須要首先經過日誌分析等手段,肯定一個請求的各階段耗時。緩存
例如對於典型的分層部署的後臺系統,你須要首先定位耗時較長的處理分別位於哪些服務器。
web服務器?業務邏輯層服務器?DB層服務器?性能優化
3.2 分析硬件資源監控的統計數據,肯定資源有無瓶頸
當咱們已經明確耗時較長的處理位於哪一個服務器以後,咱們首先須要確認該服務器在性能測試期間的資源消耗。服務器
- CPU負載/利用率:若是CPU負荷太高說明目前CPU資源是不足的。那麼在後續的[分析程序的數據結構與算法]階段,你須要優化運算邏輯如設計更合理的並行線程數量(一般是cpu核數×2);或者你能夠直接增長CPU資源(scale up);
- 內存佔用:若是內存佔用太高,可能會致使交換到swarp區,進而致使性能降低。那麼在後續的[分析程序的數據結構與算法]階段,你須要優化程序設計,好比減小緩存使用,及時釋放內存等;或者你能夠直接增長內存(scale up)。
- 磁盤IO:磁盤IO過多會致使性能表現降低,嚴重時會致使相關線程阻塞。那麼在後續的[分析程序的數據結構與算法]階段,你能夠考慮優化程序設計,減小IO量,減小小文件讀寫頻率,增長緩存等等;或者你能夠直接置換磁盤爲SSD(scale up)。
- 網絡IO:網絡IO過多可能會被網絡帶寬限制,致使傳輸速度受限。那麼在後續的[分析程序的數據結構與算法]階段,你能夠優化程序設計好比減少通訊量;或你能夠直接增長帶寬(scale up)。
3.3 應用層面的優化
從應用層面考慮,咱們應該對邏輯處理的數據結構與算法進行優化:
- 若是資源有瓶頸,參考[3.2 分析硬件資源監控的統計數據,肯定資源有無瓶頸]中的相關記述對程序自己邏輯進行優化分析;
- 若是資源無瓶頸,則須要分析程序自己的數據結構與算法有無優化空間。
例如:
- 優化算法,採用在時間複雜度方面更具備優點的算法,例如,使用更合理的數據結構,減小循環的深度與次數,減小遞歸深度等;
- 有沒有臨界資源的競爭,例若有沒有使用排它鎖致使其餘線程阻塞等現象;
- 對於SQL語句,要考慮SQL語句有沒有優化空間,表可否優化結構好比添加索引,甚至考慮explain解析執行計劃分析SQL語句;
- 其餘...
3.4 架構層面的優化
從架構層面分析性能問題時,涉及到的技術較多。
這裏以通常的Web站點架構(大體以下圖所示)爲例,說明一下咱們能夠考慮的切入點:
- 反向代理層性能優化(如經過參數優化增長併發能力)。
- Web站點層性能優化。參數優化增長QPS指標;是否須要使用支持異步非阻塞模式的web容器來增長單機併發能力(如webflux);是否須要水平擴展多個web站點並負載均衡來增長集羣併發能力(scale out)。
- 是否須要內存數據庫實現緩存層設計(如redis)。
- DB是否須要讀寫分離,是否須要分庫分表(如sharding-jdbc)。
- 各層通訊效率可否優化,有沒有更高效的序列化協議(如protobuf)。
- 是否須要引入搜索引擎爲數據庫或非結構化數據創建反向索引實現快速檢索(如elasticSearch)。
- 是否須要對業務層進行水平擴展來增長併發能力(scale out)。
- 是否須要採用分佈式並行運算框架,解決特殊場景的單機性能上限問題。
- DB層是否須要使用其餘的NOSql數據庫從而提高非OLTP場景的性能表現。
3.5 運維層面的優化
運維層面的優化主要是各類組件服務器的性能相關參數優化。
這裏列舉了常見的組件服務以及linux內核等參數優化的例子:
- DB參數優化 : 對於DB服務器,有無性能相關參數能夠優化。好比存儲引擎,緩衝池大小等等。
- JVM參數優化 : 對於java應用,JVM參數是否能夠優化。如GC算法,堆棧分配等等。同時,能夠增長GC日誌分析是否發生了過多的full GC。
- linux內核參數優化 : 對於linux服務器的內核參數,應當根據業務環境特性及服務器硬件配置來設置合理的值。