一次效能調優的實戰

2021-06-05 18:34:40 字數 2316 閱讀 1479

專案情況:是乙個大型公司的內部辦公系統,該系統有兩個和一般企業應用不太一樣的特點:一是使用者量非常多,人員數達到2w左右,另乙個是採用分級管理的形式,各個分公司資料分開管理。

我們的定位:我們是作為業務平台的提供商參與這個專案的,我們提供底層的開發平台,系統整合商在此基礎上進行二次開發。

在專案從開發到部署的過程中遇到了很多的問題,也反映出很多問題。

一、怎麼回事,跑得比貓還慢

專案開發完畢後部署在ibm aix 小型機上,32g記憶體,16個cpu。應用伺服器採用的是weblogic9.2,資料庫是oracle10.0.2。上線後發現系統執行的非常緩慢,甚至比開發環境下的tomcat還要慢。於是開始排查原因,最開始是對sql進行監控,優先考慮是資料庫訪問效能產生瓶頸。通過監控,發現很多業務需要執行大量的sql語句,檢視客戶編寫的相關**,發現在查詢資料時迴圈執行了大量sql。主要原因在於他們在**中迴圈呼叫了我們相關api,乙個最典型的例子是通過使用者id查詢使用者name,他們在業務**裡沒有儲存使用者name,而是在查詢的時候通過使用者id查詢使用者name填充到頁面,幾乎每乙個查詢都是n+1。

另外由於平台使用了hibernate,使得oo程式設計得非常爽快,導致開發人員完全忽略了相應的資料庫操作所帶來的壓力。很多業務邏輯直接通過po疊加完成,把一些可以通過很少sql完成的邏輯全部分散放置到po裡,導致了大量po的互動和sql語句。

開始優化sql,優化的同時增加大量業務快取。但優化完畢後執行緩慢的現象依舊存在,效能有了一定的提公升但是不是非常明顯。繼續優化,其中考慮過多頻繁訪問的資料使用記憶體資料庫的方式。但是優化過後在tomcat上效果明顯,部署到生產環境就問題依舊。於是考慮weblogic的配置問題,作為開發平台提供商,我們只是提供系統開發相關方面的支援,對於應用伺服器和資料庫伺服器只是做基本的配置系統可執行即可。但是在這個問題上系統整合商咬定是我們平台的問題不放,並且存在乙個很嚴重的問題:他們使用的是盜版的weblogic,這樣根本就沒有相應的技術支援。

問題的解決:最後是找了乙個bea曾經的開發人員,問題實際非常的簡單,現場部署的weblogic預設是執行在32位機器上,與64位機器存在一定的不相容。通過替換相應的jar包,問題得到了解決,主要是io方面。替換完畢後,速度提公升了進30% 。該開發人員說,如果沒有lisence,根本就不會得到這些替換的jar包。

二、記憶體耗盡了

訪問速度的問題解決了,系統的使用量很快上來,馬上遇到新的問題:記憶體耗盡了。嚴重到幾乎每天都要out of memory一次。這種問題在客戶現場頻繁出現。

本地測試,tomcat,sun jdk 通過jprofiler監測記憶體使用情況。在併發訪問門戶的情況下,記憶體確實存在暴漲的情況,100併發,記憶體使用立刻上公升了150m左右,繼續併發100,再增長150m。但是很快在抵達高峰時會有一次gc發生,記憶體使用穩定在200m,記憶體裡大量char陣列物件。疲勞測試,記憶體使用曲線並沒有出現逐漸上公升洩露的情況。換weblogic和jrocket測試,gc發生的更加頻繁,記憶體使用穩定。

但是現場依舊頻繁當機,記憶體根本釋放不了,一直逐漸增長,典型的記憶體洩露。對系統快取、單態物件包括spring管理的物件、io流進行了統一排查,依舊沒有找到記憶體洩露的原因。使用ibm 工具分析heapdump檔案,結果還是大量的char陣列物件佔據記憶體,查詢應用,找不到相關業務物件引用。

問題解決:問題解決是一篇偶爾搜到的oracle論壇的帖子,這裡 。原因在於oracle10的資料庫驅動對statement最後執行的結果集有著引用,並且不會釋放,目的在於通過記憶體而換取更好的效能。資料庫連線採用的是weblogic的連線池,關於connection有個相關的statement cache設定,設定乙個connection能夠被快取的statement個數,最大是1024,而現場就被設定為了1024!connection pool的connection個數被設定為了500 。真是個恐怖的設定。在將1024改為10後,記憶體使用量轟然倒地,穩定在1g左右。這個設定是在前面系統訪問速度存在問題時由系統整合商的開發人員設定上去的,他們將所有和優化相關的引數全部開到了最大。這個問題要是使用者購買的是正版的weblogic和oracle的話,相信也會很快得到解決。

三、執行緒阻塞

記憶體洩露的問題解決後,執行緒阻塞的問題浮出水面。系統整合商報告是執行緒死鎖,通過分析工具其實是執行緒阻塞,主要問題在於系統用到了synchronized關鍵字,對工作流相關api全部使用了synchronized,原因在這裡: 。分析發現乙個工作項提交的操作在連線資料庫時被掛起了20分鐘!造成了大量執行緒的排隊阻塞。被掛起的原因有很多種。我們採用的方法是將介面拆分和設定事務timeout時間。但是這顯然不是乙個好方法。最後是去掉所有的synchronized關鍵字,將同步的問題交由資料庫解決,問題解決。

四、反思

一次效能調優的實戰

專案情況 是乙個大型公司的內部辦公系統,該系統有兩個和一般企業應用不太一樣的特點 一是使用者量非常多,人員數達到2w左右,另乙個是採用分級管理的形式,各個分公司資料分開管理。我們的定位 我們是作為業務平台的提供商參與這個專案的,我們提供底層的開發平台,系統整合商在此基礎上進行二次開發。在專案從開發到...

一次Java垃圾收集調優實戰

cms收集器 暫停時間優先 配置引數 xx useconcmarksweepgc 已預設無需配置的引數 xx useparnewgc parallel收集新生代 xx cmspermgensweepingenabled cms收集持久代 xx usecmscompactatfullcollectio...

一次Java垃圾收集調優實戰

cms收集器 暫停時間優先 配置引數 xx useconcmarksweepgc 已預設無需配置的引數 xx useparnewgc parallel收集新生代 xx cmspermgensweepingenabled cms收集持久代 xx usecmscompactatfullcollectio...