這篇文章重點仍是談已經上線的業務系統後續出現性能問題後的問題診斷和優化重點。前端
咱們首先來分析下若是一個業務系統上線前沒有性能問題,而在上線後出現了比較嚴重的性能問題,那麼實際上潛在的場景主要來自於如下幾個方面。ios
/* 1.業務出現大併發的訪問,致使出現性能瓶頸 2.上線後的系統數據庫數據日積月累,數據量增長後出現性能瓶頸 3.其它關鍵環境改變,好比咱們常說的網絡帶寬影響 */
正是因爲這個緣由,當咱們發現性能問題的時候,首先就須要判斷是單用戶非併發狀態下自己就有性能問題,仍是說在併發狀態才存在性能問題。對於單用戶性能問題每每比較容易測試和驗證,對於併發性能問題咱們能夠在測試環境進行加壓測試和驗證,以判斷併發下的性能。算法
若是是單用戶自己就存在性能問題,那麼大部分問題都出在程序代碼和SQL須要進一步優化上面。若是是併發性能問題,咱們就須要進一步分析數據庫和中間件自己的狀態,看是否須要對中間件進行性能調優。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語句慢。這樣能夠極大的提高咱們性能問題分析診斷的效率。