系統架構效能優化思路

youmen發表於2020-11-29

這篇文章重點還是談已經上線的業務系統後續出現效能問題後的問題診斷和優化重點。

系統效能問題分析流程

我們首先來分析下如果一個業務系統上線前沒有效能問題,而在上線後出現了比較嚴重的效能問題,那麼實際上潛在的場景主要來自於以下幾個方面。

/*
		1.業務出現大併發的訪問,導致出現效能瓶頸

    2.上線後的系統資料庫資料日積月累,資料量增加後出現效能瓶頸
    3.其它關鍵環境改變,比如我們常說的網路頻寬影響
*/

正是由於這個原因,當我們發現效能問題的時候,首先就需要判斷是單使用者非併發狀態下本身就有效能問題,還是說在併發狀態才存在效能問題。對於單使用者效能問題往往比較容易測試和驗證,對於併發效能問題我們可以在測試環境進行加壓測試和驗證,以判斷併發下的效能。

如果是單使用者本身就存在效能問題,那麼大部分問題都出在程式程式碼和SQL需要進一步優化上面。如果是併發效能問題,我們就需要進一步分析資料庫和中介軟體本身的狀態,看是否需要對中介軟體進行效能調優。

在加壓測試過程中,我們還需要對CPU,記憶體和JVM進行監控,觀察是否存在類似記憶體洩漏無法釋放等情況,即併發下效能問題本身也可能是程式碼本身原因導致效能異常。

效能問題影響因素分析

對於效能問題影響因素,簡單來說包括了硬體環境,軟體執行環境和軟體程式三個方面的主要內容。下面分別再展開說明下。

硬體環境

硬體環境就是我們常說的計算,儲存和網路資源。

對於伺服器的計算能力,一般來說廠家都會提供TPMC引數作為一個參考資料,但是我們實際看到相同TPMC能力下的X86伺服器能力仍然低於小型機的能力。

除了伺服器的計算能力引數,另外一個重點就是我們說的儲存裝置,影響到儲存的重點又是IO讀寫效能問題。有時候我們監控發現CPU和記憶體居高不下,而真正的瓶頸通過分析反而發現是由於IO瓶頸導致,由於讀寫效能跟不上,導致大量資料無法快速持久化並釋放記憶體資源。

比如在Linux環境下,本身也提供了效能監控工具方便進行效能分析。比如常用的iostat,ps,sar,top,vmstat等,這些工具可以對CPU,記憶體,JVM,磁碟IO等進行效能監控和分析,以發現真正的效能問題在哪裡。

比如我們常說的記憶體使用率持續告警,你就必須發現是高併發呼叫導致,還是JVM記憶體洩漏導致,還是本身由於磁碟IO瓶頸導致。

對於CPU,記憶體,磁碟IO效能監控和分析的一個思路可以參考:

執行環境-資料庫和應用中介軟體

資料庫和應用中介軟體效能調優是另外一個經常出現效能問題的地方。

資料庫效能調優

拿Oracle資料庫來說,影響資料庫效能的因素包括:系統、資料庫、網路。資料庫的優化包括:優化資料庫磁碟I/O、優化回滾段、優化Rrdo日誌、優化系統全域性區、優化資料庫物件。

要調整首先就需要對資料庫效能進行監控

我們可以在init.ora引數檔案中設定TIMED_STATISTICS=TRUE 和在你的會話層設定ALTER SESSION SET STATISTICS=TRUE 。執行svrmgrl 用 connect internal 註冊,在你的應用系統正常活動期間,執行utlbstat.sql 開始統計系統活動,達到一定的時間後,執行utlestat.sql 停止統計。統計結果將產生在report.txt 檔案中。

資料庫效能優化應該是一個持續性的工作,一個方面是本身的效能和引數巡檢,另外一個方面就是DBA也會經常提取最佔用記憶體的低效SQL語句給開發人員進一步分析,同時也會從資料庫本身的以下告警KPI指標中發現問題。

比如我們可能會發現Oracle資料庫出現記憶體使用率高的告警,而通過檢查會發現是產生了大量的Redo日誌導致,那麼我們就需要從程式上進一步分析為何會產生如此多的回滾。

應用中介軟體效能分析和調優

應用中介軟體容器即我們常說的Weblogic, Tomcat等應用中介軟體容器或Web容器。應用中介軟體調優一個方面是本身的配置引數優化設定,一個方面就是JVM記憶體啟動引數調優。

對於應用中介軟體本身的引數設定,主要包括了JVM啟動引數設定,執行緒池設定,連線數的最小最大值設定等。如果是叢集環境,還涉及到叢集相關的配置調優。

對於JVM啟動引數調優,往往也是應用中介軟體調優的一個關鍵點,但是一般JVM引數調優會結合應用程式一起進行分析。

比如我們常見的JVM堆記憶體溢位,如果程式程式碼沒有記憶體洩漏問題的話,我就需要考慮調整JVM啟動時候堆記憶體設定。在32位作業系統下只能夠設定到4G,但是在64位作業系統下已經可以設定到8G甚至更大的值。

其中JVM啟動的主要控制引數說明如下:

/*
		-Xmx設定最大堆空間
    -Xms設定最小堆空間
    -XX:MaxNewSize設定最大新生代空間
    -XX:NewSize設定最小新生代空間
    -XX:MaxPermSize設定最大永久代空間(注:新記憶體模型已經替換為Metaspace)
    -XX:PermSize設定最小永久代空間(注:新記憶體模型已經替換為Metaspace)
    -Xss設定每個執行緒的堆疊大小
*/

那麼這些值究竟設定多大合適,具體來講:

Java整個堆大小設定,Xmx 和 Xms設定為老年代存活物件的3-4倍,即FullGC之後的老年代記憶體佔用的3-4倍。永久代 PermSize和MaxPermSize設定為老年代存活物件的1.2-1.5倍。

年輕代Xmn的設定為老年代存活物件的1-1.5倍。

老年代的記憶體大小設定為老年代存活物件的2-3倍。

/*
		注意在新的JVM記憶體模型下已經沒有PermSize而是變化為Metaspace,
		因此需要考慮Heap記憶體和Metaspace大小的配比,同時還需要考慮相關的垃圾回收機制是採用哪種型別等。
*/

對於JVM記憶體溢位問題,我前面寫過一篇專門的分析文章可以參考。

從表象到根源-一個軟體系統JVM記憶體溢位問題分析解決全過程

軟體程式效能問題分析

在這裡首先要強調的一點就是,當我們發現效能問題後首先想到的就是擴充套件資源,但是大部分的效能問題本身並不是資源能力不夠導致,而是我們程式實現上出現明顯缺陷。

比如我們經常看到的大量迴圈建立連線,資源使用了不釋放,SQL語句低效執行等。

為了解決這些效能問題,最好的方法仍然是在事前控制。其中包括了事前的程式碼靜態檢查工具的使用,也包括了開發團隊對程式碼進行的Code Review來發現效能問題。

所有已知的問題都必須形成開發團隊的開發規範要求,避免重複再犯。

業務系統效能問題擴充套件思考

對於業務系統的效能優化,除了上面談到的標準分析流程和分析要素外,再談下其它一些效能問題引發的關鍵思考。

上線前的效能測試是否有用

有時候大家可能覺得奇怪,為何我們系統上線前都做了效能測試,為何上線後還是會出現系統效能問題。那麼我們可以考慮下實際上我們上線前效能測試可能存在的一些無法真實模擬生產環境的地方,具體為:

/*
		硬體能否完全模擬真實環境?最好的效能測試往往是直接在搭建完成的生產環境進行。

    資料量能否模擬實際場景?真實場景往往是多個業務表都已經存在大資料量的積累而非空表。

    併發能否模擬真實場景?一個是需要錄製複合業務場景,一個是需要多臺壓測機。
*/

而實際上我們在做效能測試的時候以上幾個點都很難真正做到,因此要想完全模擬出生產真實環境是相當困難的,這也導致了很多效能問題是在真正上線後才發現。

系統本身水平彈性擴充套件是否完全解決效能問題

第二個點也是我們經常談的比較多的點,就是我們的業務系統在進行架構設計的時候,特別是面對非功能性需求,我們都會談到系統本身的資料庫,中介軟體都採用了叢集技術,能夠做到彈性水平擴充套件。那麼這種彈性水平擴充套件能力是否又真正解決了效能問題?

實際上我們看到對於資料庫往往很難真正做到無限的彈性水平擴充套件,即使對於Oracle RAC叢集往往也是最多擴充套件到單點的2到3倍效能。對於應用叢集往往可以做到彈性水平擴充套件,當前技術也比較成熟。

當中介軟體能夠做到完全彈性擴充套件的時候,實際上仍然可能存在效能問題,即隨著我們系統的執行和業務資料量的不斷積累增值。實際上你可以看到往往非併發狀態下的單使用者訪問本身就很慢,而不是說併發上來後慢。因此也是我們常說的要給點,即:

/*
		單點訪問效能正常的時候可以擴充套件叢集來應對大併發狀態下的同時訪問

		單點訪問本身效能就有問題的時候,要優先優化單節點訪問效能
*/
業務系統效能診斷的分類

對於業務系統效能診斷,如果從靜態角度我們可以考慮從以下三個方面進行分類:

/*
		作業系統和儲存層面
		中介軟體層面(包括了資料庫,應用伺服器中介軟體)
		軟體層面(包括了資料庫SQL和儲存過程,邏輯層,前端展現層等)
*/

那麼一個業務系統應用功能出現問題了,我們當然也可以從動態層面來看實際一個應用請求從呼叫開始究竟經過了哪些程式碼和硬體基礎設施,通過分段方法來定位和查詢問題。

比如我們常見的就是一個查詢功能如果出現問題了,首先就是找到這個查詢功能對應的SQL語句在後臺查詢是否很慢,如果這個SQL本身就慢,那麼就要優化優化SQL語句。如果SQL本身快但是查詢慢,那就要看下是否是前端效能問題或者叢集問題等。

軟體程式碼的問題往往是最不能忽視的一個效能問題點

對於業務系統效能問題,我們經常想到的就是要擴充套件資料庫的硬體效能,比如擴充套件CPU和記憶體,擴充套件叢集,但是實際上可以看到很多應用的效能問題並不是硬體效能導致的,而是由於軟體程式碼效能引起的。對於軟體程式碼常見的效能問題我在以往的部落格文章裡面也談過到,比較典型的包括了。

/*
		迴圈中初始化大的結構物件,資料庫連線等
    資源不釋放導致的記憶體洩露等
    沒有基於場景需求來適度通過快取等方式提升效能
    長週期事務處理耗費資源
    處理某一個業務場景或問題的時候,沒有選擇最優的資料結構或演算法
*/

以上都是常見的一些軟體程式碼效能問題點,而這些往往需要通過我們進行Code Review或程式碼評審的方式才能夠發現出來。因此如果要做全面的效能優化,對於軟體程式碼的效能問題排查是必須的。

通過IT資源監控或APM應用工具來發現效能問題

對於效能問題的發現一般有兩條路徑,一個就是通過我們IT資源的監控,APM的效能監控和預警來提前發現效能問題,一個是通過業務使用者在使用過程中的反饋來發現效能問題。

APM應用效能管理主要指對企業的關鍵業務應用進行監測、優化,提高企業應用的可靠性和質量,保證使用者得到良好的服務,降低IT總擁有成本(TCO)。

資源池-》應用層-》業務層

這個可以理解為APM的一個關鍵點,原有的網管類監控軟體更多的是資源和作業系統層面,包括計算和儲存資源的使用和利用率情況,網路本身的效能情況等。但是當要分析所有的資源層問題如何對應到具體的應用,對應到具體的業務功能的時候很難。

傳統模式下,當出現CPU或記憶體滿負荷的時候,如果要查詢到具體是哪個應用,哪個程式或者具體哪個業務功能,哪個sql語句導致的往往並不是容易的事情。在實際的效能問題優化中往往也需要做大量的日誌分析和問題定位,最終才可能找到問題點。

/*
		比如在我們最近的專案實施中,結合APM和服務鏈監控,我們可以快速的發現究竟是哪個服務呼叫出現了效能問題,
		或者快速的定位出哪個SQL語句有驗證的效能問題。這個都可以幫助我們快速的進行效能問題分析和診斷。
*/

資源上承載的是應用,應用本身又包括了資料庫和應用中介軟體容器,同時也包括了前端;在應用之上則是對應到具體的業務功能。因此APM一個核心就是要將資源-》應用-》功能之間進行整合分析和銜接。

而隨著DevOps和自動化運維的思路推進,我們更加希望是通過APM等工具主動監控來發現效能問題,對於APM工具最大的好處就是可以進行服務全鏈路的效能分析,方便我們發現效能問題究竟發生在哪裡。比如我們提交一個表單很慢,通過APM分析我們很容易發現究竟是呼叫哪個業務服務慢,或者是處理哪個SQL語句慢。這樣可以極大的提升我們效能問題分析診斷的效率。

來源 https://4m.cn/rN8IB

相關文章