IBM WAS 宕機情況的分析

這是上篇文章的續篇,也是07年初發表於JavaEye,被評爲精華帖,瀏覽近四萬次,也被各大IT媒體轉載(google可查)。基於同樣的原因,被刪除了)。 

對WebSphere一線開發人員,這麼珍貴的文章,特別是會員的評論,就被這個商業社會給和諧。 
因爲,尋找和閱讀WebSphere診斷和調優的資料,非常困難,否則,它那高額的服務費哪裏來?(IBM的WebSphere服務費:人民幣10000元/天)。 



-------------------------------------------------------------------- 

續寫這篇文章,已經過去一個半月了。直到現在,系統一直運行平穩。 
先說說我接手這項工作的經歷吧:該項目大部分是06年10月就部署在客戶那邊了,到07年3月份,WAS宕機問題實在無法忍受,我才加入進來,前半年有另外一位同事斷斷續續處理,但對問題一直都無可奈何,而且項目負責人也沒有引起足夠的重視。可想而知,最後付出的代價是非常慘重的。在這近半年的時間內,服務器宕機63次。每次宕機時,WAS的JVM會dump出一個heapdump.phd文件(heap快照),然後JVM就死掉了,當然,此時WAS也停止了響應。一般我們的做法是重啓,最後是乾脆AIX每天晚上定時重啓。有時候一天還死多次。大家見附件的截圖(all- GC.png)。這是我接手後,用IBM的分析工具得到的截圖。對截圖的分析,留給後面對應的部分吧。 
服務器不穩定、宕機問題,拖延到最後,客戶憤怒了,公司高層也害怕了,部門還專門成立了八人攻關組。當然了,我當時的壓力也非常大,因爲我是技術負責人,也就是實實在在幹活、想主意的。 
服務器診斷那段時間,從前到後,我們也是沿着一條線走下來,雖然最後發現很多路都走不通。現在就按這個思路,也就是時間先後一步步敘述吧。我想,大家如果也碰到類似應用服務器診斷,應該思路差不多。 

術語說明: 
IBM Websphere Application Server:WAS,WebSphere本身是一個平臺,產品家族 
OutOfMemoryError:OOM,內存泄漏,內存溢出 
Gabage Collection:GC,自動垃圾回收 
Content Management System:CMS,就是給新聞類門戶網站編輯們用的系統 

我們診斷大體上經歷了以下幾個階段: 
1、按Job調度線程池引起內存泄漏診斷:因爲很多次OOM是發生在某個特定時候,譬如14:30、22:40左右。 
2、按應用程序引起內存泄漏診斷:用JProfiler等工具探測:因爲總是發生OOM。 
3、分離WAS懷疑有OOM的應用:因爲每個WAS應用太多,20來個,混一起沒法定位。 
4、用IBM官方heap、GC分析工具。以及和IBM技術支持聯繫。WAS、AIX參數優化。 
5、隔離出WAS超級惡魔程序:一個CMS產品。 
6、WAS、AIX參數優化、設置。 

我們走到第5步時,纔出現效果。計算一下,那時已經過去一個月了。服務器宕機、系統不穩定,在這個驗收的時候,客戶已經忍無可忍,以致後來的每一次行動都得膽戰心驚得去做。 


一、按Job調度線程池導致內存泄漏診斷
因爲從我們WAS的日誌(默認是native_stderr.log)來看,最近半年的宕機時間都有一個明顯時間規律。見附件截圖Job1-1.png。 
我想,做過Java服務器性能調優的朋友,都知道在Web容器裏面啓線程池是個不太好的做法,因爲Web容器本身有一個線程池,譬如Servlet線程池(Tomcat默認起25個),而自啓的線程池很容易導致Servlet線程管理混亂,最終導致GC問題。我們的現象似乎和那很符合。如果我們沿着這個思路做下去,具體怎樣實施呢? 

我們的WAS上部署了20個左右的Web應用,譬如Lucene全文檢索、B2B行業數據同步等,都是通過Quartz的Job調度做的,當然還有很多其它調度。當時,由我負責,通知相關負責人,將定時調度暫時去掉。觀察了幾天,後來發現問題依然存在,不過時間有點隨機了。 
不過,最後還是發現OOM不是由Job調度引起的。 
也就是說,我們這個方案是失敗的。而且,我們的很多想法都是臆測的,沒有可靠的根據,也沒有方向,再加上我是第一次處理這種問題,這導致後來查找問題的艱難。但是,仔細想想,我們又能拿什麼做依據呢?出現OOM錯誤,我想大多數人想到的,除了JVM參數設置,就是內存泄漏。其實,OOM發生有很多種情況,在IBM、Sun、BEA等不同虛擬機上,因爲GC機制不一樣,所以原因一般都不同,容易定位難度也不一樣。下文會談到。 
於是,我們乾脆釜底抽薪分析問題吧:用JProfiler檢測。 


二、按應用程序導致內存泄漏診斷,JProfiler檢測
如果遇到OOM問題,我想大家都會想到內存檢測工具,現在最可靠的還是下面三種分析工具:Borland 的Optimizeit Suite,Quest的JProbe,ej-technologies的JProfiler。但面臨三個問題: 
1、三個都是商業產品,公司暫時沒有買,必須自己下載,而且要找序列號。 
2、工具必須支持AIX5.3+JDK1.42+WAS6.0,不是Windows平臺。 
3、工具必須在客戶真實環境下部署,對客戶的業務不能有衝擊,也就是說部署測試工具前,必須做個大量測試,對工具非常熟練,遇到意外可以立即恢復現場。 
Note:項目上線後,而不是測試或試運行階段遇到此類問題,非常考驗人;另外一個,就是性能和可伸縮性問題,很可能把整個項目給毀了。 

當我決定要這麼做後,就立即動手查閱這些工具的官方文檔,用emule下載,最終都下載到了。試用後,最終選擇了JProfiler4.03,比起其它工具,它界面美觀、清晰、功能強大、集成度高(Heap,Memory,CPU,Thread都統一了)。另外,JProbe沒有AIX版本,這也是放棄它的一個原因。 

JVM的Profiler原理,都是通過JVM內置的的標準C語言Profiler 接口收集數據,然後通過Profiler工具的客戶端展現。也就是說各廠商的Profiler工具,都有兩個部分,一個部分是Profiler Agent,和JVM綁定,負責收集JVM內部數據,譬如方法調用次數、耗費時間等;另外一個部分就是Profiler front-end。通過Profiler工具的自定義local或remote協議傳輸到front-end,其實,我們最常用的JavaIDE的debug功能就是在此基礎上的(JPDA)。(JProfiler的截圖http://www.ej-technologies.com/products/jprofiler/screenshots.html )。 
下面是Sun官方文檔: 
JDK1.42及以前是JVM PI:http://java.sun.com/j2se/1.4.2/docs/guide/jvmpi/jvmpi.html 
JDK1.5是JVM TI:http://java.sun.com/j2se/1.5.0/docs/guide/jvmti/jvmti.html 
具體到JProfiler的配置上,專門針對JDK1.4和1.5的JVM配置差別很大。 

我用的JProfiler是4.31版本,透露給大家一個萬能序列號吧(這東西不太好找),對各版本應該都支持。深入瞭解Java,這類工具是不可少的: 
Name: License for You 
Lincese Code: A-G667#42616F-10kg1r134fq9m#2217 

爲了保證真實環境的檢測成功,我做了大量的試驗,譬如: 
1、Windows系列的本地、遠程測試。 
2、AIX的遠程測試。 
3、Tomcat5.0、WebLogic8.14、WebSphere6.02,以及上述兩種方式的組合測試,排列組合,場景不下10個。 
當時也參閱了大量JVM文檔,JProfiler官方几百頁英文文檔,輔助的JProbe對照。而且也製造過內存泄漏造成的OOM場景。 
當然,要是在幾個月前,在客戶那邊部署的測試環境時,就進行測試該多好啊。 

在公司內部,我用 JProfiler測試了我們當時部署的幾個應用,沒有發現內存泄漏,所以,我們最懷疑的是就是CMS系統。因爲出問題的那個WAS上它佔去了90%的負荷(我們有多臺AIX、WAS服務器)。該CMS超級龐大,感覺著名的賽迪網就用它,當時該CMS廠商給我們部署都花了快一個月。所以再重新部署一套測試環境也挺困難。另外,CMS提供商不給lisence。現在測試,客戶早就對我們惱火了,當然不怎麼配合,這對我們工作的開展就有很大的挑戰。 

在大致可以確定萬無一失的情況下,我們最終決定在客戶的真實環境下測試。也就是讓JProfiler的agent端直接在WAS的JVM裏面啓動(北京IDC),然後遠程(大連)監控。 
本來該模式在另外幾個應用的測試都通過了(因爲北京IDC那邊好幾臺AIX服務器)。但一部署上,客戶的一些編輯用CMS時就感覺超級慢,儘管我們用了JProfiler的最小負載模式。半個小時後,客戶實在無法忍受,打電話過來,又把我們部長和經理訓了一頓,還要寫書面報告。我們被迫馬山中止測試,恢復現場。 

雖然JProfiler也支持客戶那邊的環境,但還是有bug,至少負載一高就有嚴重的性能問題,幾乎導致系統掛起,這是我當時沒有料到的。JProfiler一啓動,WAS的啓動時間就由原來的3分鐘降到10分鐘,而且系統響應明顯變慢,我們具體的環境如下(排列組合恐怕不下20種): 
1、AIX5.3,Power PC64位(不是32位) 
2、WebSphere6.0 
3、IBM JVM1.42 
4、Remote 模式 

我後來仔細讀了一下JProfiler的changeLog,發現對上面的環境支持不夠也很正常,因爲官方在最近的4.3.x版本下陸續有對IBM JVM和Websphere6.0的features和bug fix:http://www.ej-technologies.com/download/jprofiler/changelog.html 

進行到這一步,我忽然覺得無計可施了 ,此時已經過了三週。 
上面的策略,我認爲是很正統的處理方法。誰怪我們當初項目上線時沒有進行充分的測試呢?其實,這類測試沒做也正常,OOM這類問題誰都無法預測。 

到這個時候,我想肯定有人會問我?你知道導致JVM的OOM有幾種情況嗎?在當時,我想到了以下五種: 
1、JVM的heap最小、最大值沒有設,或不合理。 
2、JVM的maxPermSize沒有設置(這個IBM的JVM沒有,一設置JVM就起不來)。 
對於Sun和BEA的JVM,以上兩種參數設置,可以排除90%以上的非程序內存溢出導致的OOM。 
3、程序內存泄漏 
4、有的JVM,當在80%的CPU時間內,不能GC出2%的heap時,也發生OOM(IBM的JVM就是,但我沒有驗證) 
5、JVM本身內存泄漏(JVM有bug不是不可能) 

現在的難題是,如果是那個可怕的CMS程序本身有內存溢出,在產品環境下,我們怎麼去驗證?我們自己開發的10來個web應用,測試並不是很難,在公司測試都可以。但是,我現在最想解決的,就是CMS測試的問題。而且,在我們那種環境下,該CMS產品供應商並沒有透露成功案例。 

其實,最後發現,並不是內存泄漏造成的,因爲我們的heap走勢都很平穩。納悶的是,有1000M的heap,每次在heap只被佔用400來M時就發生OOM,沒有任何預兆。大家猜猜,會是什麼原因 ?這個問題我到後面相關章節再說吧。 

既然我們所有的矛頭都指向那個可怕的CMS系統,現在就是考慮隔離的問題。如果我們驗證這個問題是CMS造成的,那麼大部分責任就應該由CMS廠商承擔 。 
既然CMS我們不敢移(費勁,而且客戶在正式用),那我就移我們開發的10來個web系統吧。 


三、移出除CMS系統以外的所有應用 
說起來容易啊,做呢? 隔離(移動)工作由我負責,具體涉及到10來個相關負責人。 
轉移工作,必須處理好很多問題,就說幾個印象最深的吧: 
1、某些應用,如Blog和BBS,都涉及到文件、圖片上傳目錄和產品本身的環境,如 JDBC連接池、Cache位置。 
2、目標服務器本身的環境,WAS安裝環境、網絡等。 
3、移植時的先後順序、調度,各應用內部本身的約束關係。 
4、移植後的測試。 
當然,還有一個最嚴峻的問題,客戶允許我們這麼做嗎?對它們目前運行的系統有多大影響?風險如何評估? 

這個工作持續了一天,已經完成了80%的工作,到第二天,客戶又惱火了:WAS又宕機了。 
爲什麼?這確實是WAS的一個bug:WAS的後臺隨便一操作,heap就會突然上升幾百M,導致JVM內存不夠。不過WAS撐住的話,過半小時後就會降下來,我估計是WAS後臺對用戶操作狀態、文件都緩存到Session裏面。你們可以檢查類似這樣的一個文件夾:d:\IBM\WebSphere\AppServer\profiles\AppSrv01\wstemp,我不知道爲什麼WAS不主動去清除它,它偷偷的就上升到幾個G,系統硬盤可能不久就後就會空間不足,WAS莫名遲緩、最後死掉。聽過WAS6.0以前這個目錄更誇張。大家見我附件的截圖WAS_Console.png那個尖峯。 

咋辦?經理也已經不敢讓我們繼續鋌而走險了。這個方案最終又以失敗告終 。 

不過,最後我們還是發現問題出在CMS上。我們以前把這個問題向CMS技術支持反映,有大量依據和現象,並且把相關日誌都給它們。過了兩天,他們最後竟然只回了一句話“從給我的兩個日誌來看,沒有找到任何與XXX有關的東西….”。TMD!我真的很生氣 ,它們的產品都折磨我們半年之久了。不過,看他們對IBM的WAS和JVM也不懂,我也就不想再說什麼了。下面是我的郵件,公司機密部分都隱去了: 

引用 
附件是我們這段時間服務器宕機的日誌。我們用IBM Pattern Modeling and Analysis Tool for Java Garbage Collector Version 1.3.2分析了一下虛擬機日誌,沒有發現是內存泄漏導致;用IBM HeapAnalyzer Version 1.4.4 分析heap文件,也沒有發現很可疑的內存泄漏。 
我想以前你們也這樣做過,現在我們分析錯誤日誌,發現有一個現象,在宕機時,總是找不到文件,我看就是Websphere或是AIX IO資源不夠,不知道是什麼導致的。但是,我們自己的應用,基本上沒有什麼IO,除了一次load幾個配置文件。不過,我覺得你們WCM的IO操作挺多的,不知道你對日誌有什麼新的發現。 
客觀的說,這幾個月來,宕機那臺服務器,除了你們的XXX,就以論壇和blog爲主,而且他們都是開源的。在頻繁宕機的06年11月份,我們的論壇和blog還沒有上線。現在我們不得不每天晚上11點定時重啓,但這也不是長久之計。 
現在,我們進行分離遇到很大阻力,原來想把你們的XXX單獨分離出來,在當前的環境下,不是很現實,如安裝、測試(負載、定時服務),所以現在分離我們自己的應用,但當前在產品環境下,客戶方阻力也很大。 
希望儘快能夠得到你們的問題建議和方案。 
文中說到了IBM的兩個分析工具,這也是我們後來的救星:我們就是需要這種離線分析工具,因爲實時檢測已經證明不現實。但我始終對該分析出來的結果抱懷疑態度,直到我去深入IBM的JVM以及和IBM的技術支持交流…… 

柳暗花明啊 ,至少看到了一點希望,不過最後我們還是失望而返。 


四、用IBM的HeapAnalyzer和GarbageCollector檢測

找到這兩個工具,已經是夠費勁了,因爲以前找的IBM HeapRoot工具,讓我對這類工具很失望。而且,這兩個工具,只有在IBM的Techinical Support網站能夠搜索到,但很不容易,因爲那兩個工具,並不是象IBM的Websphere產品那樣宣傳,它只在IBM Techinical Support文章的某些角落裏出現。要知道,Techinical Support是IBM很重要的收入來源,這類文檔,他們並不會讓你很輕易就拿到,比起BEA WLS的支持網站dev2dev差遠了。 
具體診斷細節我就不詳述了。我認爲,IBM的WAS或JVM出了性能和OOM問題,這兩個工具是最有效的,而且是離線分析工具,比起那些實時Profiler工具,某些場合有絕對的優勢:譬如我們目前的產品環境,你只能分析宕機後的日誌,實時分析前面已經驗證是不可行的。 
從日誌分析,我們最終得出結論,我們購買的CMS系統有嚴重的碎片(大對象)問題,而該問題是OOM的罪魁禍首,而且IBM工程師也得出了同一結論。不過,在起先我們得出這一結論一週後,我還始終不相信heap碎片會導致OOM,直到IBM工程師總是向我強調。 

我想很多人也是不太相信,因爲大多數人用的都是Sun的JVM,譬如Windows、Solaris上的hotspot。而且,Sun JVM出問題,如果是配置的問題,一般通過配置heap最大最小值,以及maxPermSize都可以解決。Heap碎片導致的OOM,只有BEA的 JRockit和IBM JVM上發生,不過JRockit有專門文檔說明,而且很容易找到(就在jdk的文檔裏面)。 

配置heap最小最大值,我想大多數人都有經驗。對於Sun的JVM來說,一般可以設置heap最大最小值一致,也是推薦的做法。因爲它的GC策略默認是複製、分代算法。也就是說,它會將heap分成不同的幾個區,譬如Solaris JVM中最上面有兩個大小相等的區。GC時刻,將一個區的存活對象複製到另外一個對等區,垃圾對象就算遺棄了。這樣在heap裏面,就不存在碎片問題。另外,根據Java對象的存活期不同,將之轉移到不同的區(Tenured區),存活最長的在最底部(火車算法),這也就是分代模型。具體請參考官方文檔:http://java.sun.com/docs/hotspot/gc1.4.2/ 

對於maxPermSize(Permanent Generation),主要和那些加載到JVM裏面的Java Class對象相關,它的空間不是在Java Heap裏面分配。如果你當前的heap有1000M,permSize是200M,那麼JVM至少佔用1200M。 
在這個空間內的對象的生存期和JVM是一樣的,譬如JDK的核心類庫,它們被System Classloader加載到JVM的Method Area(方法區)後,就不會被GC掉的,這些對象一般是Class對象,而不是普通的實例對象,也就是JVM的元數據。我們在用反射時經常用到它們。所以,對於現在象Spring、Hibernate這些框架經常通過反射創建實例,可能對maxPermSize要求就大了,缺省的64M很多時候是不夠的,特別是對於應用服務器裏的應用,象JSP就會產生和加載很多classes。不過,如果是它導致的OOM,一般會有類似 perm size提示。 

但是,對於IBM的JVM,情況就完全不一樣。它的默認GC策略並沒有採取複製、分代。這個可以從GC日誌分析出來。它不像Sun的JVM那樣,有個單獨的方法區,它的方法區就放在Java Heap裏面。JVM規範裏面並沒有要求方法區的必須存放的位置,因爲它只是一個JVM實現問題。 

在IBM的JVM裏面,這些對象一般分配在稱爲k-cluster和p-cluster裏(cluster又是屬於Heap),而後者一般是臨時在heap裏面申請。並且,這些cluster是不能GC,或是被移動重排的(Compact過程)。這就導致Java Heap裏面就如同馬蜂窩,但不同的蜂孔又不能合併,於是,當我們程序裏面產生一個大對象,譬如2M的數組(數組必須分配在連續的內存區)時,就沒有可分配空間了,於是就報告OOM。這些不能被移動的cluster就稱爲所謂的碎片。此時,JVM的Heap利用率可能不到50%。 
當然,通過一定時期的GC日誌,可以計算出cluster的合理大小(專門在Java Heap的底部),另外,還可以爲這些大對象專門分配大對象區的(超過64k的對象)。 

通過上面的理論介紹,我想大家一定知道了爲什麼IBM的JVM裏面不推薦heap的最大最小值相同,因爲這樣碎片問題會非常嚴重:如果我們每次大對象申請內存時,heap都擴展5%,譬如50M,碎片問題很大程度上可以避開,程序性能也高些(尋找可用空隙和分配耗時,以及每次GC時間拉長)。 
以上的具體闡述,請參考我在上文推薦的幾個URL,另外再推薦三個寶貴的鏈接: 
http://www-1.ibm.com/support/docview.wss?rs=180&context=SSEQTP&q1=fragmentation&uid=swg21176363&loc=en_US&cs=utf-8&lang=en 
http://www-900.ibm.com/cn/support/viewdoc/detail?DocId=2447476A10000 (IBM 技術支持告訴我的,太重要了!) 
http://www-900.ibm.com/cn/support/viewdoc/detail?DocId=2847476B08000 

我想大家應該會問:我怎麼能夠肯定我的OOM問題是heap碎片造成的呢?下面的方法可以驗證。 
在OOM發生時,JVM會產生一個heapdump文件。然後用GarbageCollector分析出該OOM發生時刻,JVM去申請的空間,譬如約235k。此時,你再用HeapAnalyzer去分析此時的heap快照裏面的gap size大小(空隙大小)和各自的可用數目。你會發現,大於235k的空隙個數爲0。這就是碎片導致OOM的證據。 

另外,有人會問:我懷疑我的OOM是因爲程序內存泄漏造成的,怎麼去驗證? 

你可以用HeapAnalyzer分析發生OOM時刻的heap快照,工具會羅列出哪些對象懷疑有內存泄漏,譬如Cache對象都非常大(但你可以確定它不是內存泄漏)。另外,分析這次宕機(從這次虛擬機啓動到宕機這段時間)的heap走勢,如果曲線明顯是向上傾斜,也就是那種典型的內存泄漏圖,就有可能是內存泄漏。當然,還必須結合heap快照。 
內存持續上升在JVM開始一段時間很正常,因爲JVM對第一次訪問到的Class 對象,譬如一個典型的Web應用,就有jdk的class、Spring或Hibernate的class對象,它們都會被緩存下來 (ClassLoader原理),一般均不會被GC。當大多數class對象緩存差不多(當然還可能有一些Singleton對象,不過不怎麼佔分量),JVM的Heap就平穩了,呈一水平波浪或鋸齒線。 
如果可以用JProfiler這類工具實時監控,就更容易確診了。 

經過一番周折,我們終於看到了一線希望了 。 

在一定的準備後,我們決定對WAS進行性能調優了。WAS的調優參數,可以分爲兩個部分:JVM級別和WAS級別: 
JVM:主要是GC和Heap。 
WAS:Thread Pool,JDBC DataSource。 
當然要調節,你需要明白你的目標是什麼,調節依據是什麼,怎麼計算,絕對不是憑空想象的,譬如heap最小值1024M,日誌證明,該參數非常不適合我們的環境。具體細節,留給後文吧。 

戰戰兢兢地,中午12:00,我們給產品環境下的WAS調節參數、重啓,同時優化了AIX的IO相關參數。 

我試着設置了一下JVM的k-cluster和p-cluster。下午15:00左右,WAS掛了,AIX也掛了。這下麻煩可大了。我們都慌了,馬山客戶的老總就來電話了,一陣嘩嘩啦啦。實在無奈,讓客戶那邊工作人員通知機房(服務器託管處)工作人員重啓AIX。我也不得不強行更改剛纔的參數,立即設爲另外一個值。 
其實,我把那個兩個cluster值確實設置太大了,我把它們設置爲推薦值的5倍,譬如p-cluster是65k×110%×5。另外一個愚蠢的設置就是把最小heap設置爲2048M(AIX有4G內存)。 
後來我恢復到約正常的值,也就是去掉那個cluster的5,另外分配了一個30%的大對象區(如果1000M的heap,就是700M+300M)。 

就這樣,系統持續正常運行了三天,以前可是一天一down。當在三天後再次宕機時,我們都沒有自信了 。不得不通過AIX的cron,繼續每天深夜11點的WAS定時重啓。 
不過,那次宕機,包括以後的幾次宕機,再也沒有出現OOM錯誤了,但系統依然不穩定。雖然我可以說OOM問題解決了,但領導和客戶需要的並不是這種結果。 

其實,在這個時候,我們已經發現我們系統的四大問題: 
1、WAS和JVM參數:OOM問題 
2、AIX的IO和Paging Spacing不足:AIX日誌後來顯示錯誤 
3、AIX的WAS分區空間不夠:WAS的日誌膨脹一週就把那個opt分區塞滿了。 
4、應用程序的JDBC連接池:我們20來個應用,一個20 connections,DB2數據庫有時被撐死。 

也就是說,我們最初在客戶那兒部署時,用的默認值根本不行。而且,部署涉及多人,人員之間出現斷層。如果我們只是按OOM,無疑是走入死衚衕,必須全局考慮! 
但是,項目組實力薄弱,公司範圍內就沒有對AIX精通的。不過項目組原來有一個搞銀行系統,在AIX下開發,就他熟悉些。我當時對AIX也比較陌生,你們從Linux轉到AIX,你就知道它有多彆扭了。命令都自定一套(也許因爲是Unix元老吧),那個shell也超級別扭,而且參考書特少。不是自詡,我兩年前負責一個高負載的Linux服務器管理一年多,也是玩得很轉的。 

就這樣,他負責AIX的相關問題,我負責WAS相關的。 
但是,現實環境,已經不允許我們再試驗下去了 。我們必須找到一條絕對可靠的對策! 
這就是下文的CMS系統大遷移,服務器再次優化。 


五、隔離CMS系統,服務器優化
從前面的介紹,大家應該記得,我們開始是固定CMS,分離其它應用,但遭遇失敗。現在是反過來,乾脆把CMS系統趕出WAS平臺 。 

說實話,項目經理做這個決定,我認爲已經是鼓出很大勇氣了 。 

當時我們想在一個備用AIX機上安裝CMS產品測試,但最後還是沒有做成: 
CMS這類文章發佈系統很難安裝,也不好測試,又沒有liscence,而且還有一堆準備工作。絕對沒有著名的openCMS安裝那麼簡單,當然功能遠遠比它複雜。而且,我們當時也低估了後來的工作,總覺得問題好解決。 

在很遙遠的06年中期,CMS廠商在客戶那邊一臺AIX的Tomcat上部署了一套CMS產品。但當時客戶執意要求將其跑在WAS上,也就是現在的情況。最開始,客戶還要求我們必須用WAS的集羣(我們買的就是WAS的ND版),無奈該CMS不支持。要是集羣,又是死傷一遍。其實,現在想想,我們當時太被動,CMS這種東西,就供公司的幾十個編輯用,一個普通Tomcat就完全夠用。而且,把它和麪向公網的Internet應用混在一起,完全沒有必要。也許,被動是因爲我的實力造成的。 

我們決定背水一戰時,已經做過周密的計劃:某年某月某日晚上8:00…… 
CMS產品負責人現場切換 
xx(我)負責WAS相關參數調整 
yy負責AIX參數。 
zz負責應用的測試 
….. 

總之,該行動涉及到客戶方、產品提供商、公司高層、項目組。每個人都密切關注,不下20人。每個人都守在電腦前,隨時聽候調遣,當天晚上,我們都沒有準備回家睡覺,大家齊心協力。 

真沒想到,整個式切換工作,一個小時就順利完成 !第二天,客戶編輯打開瀏覽器,她們一定想不到昨晚大家準備經歷一場廝殺…. 

系統持續平穩地運行了一週,然後是漫長的五一,我回湖北黃岡老家休息了八天。回來時,一切依舊。 

當天晚上,我們這邊主要做了兩項工作: 
1、JVM的Heap參數,共五個。 
2、AIX的IO、Paging Space等共六個。 
當然還有其他人的工作,譬如測試、監控。 

還有一個非常重要的方面:JDBC連接池。我們原來是在每個Web應用裏面獨立設置,這樣20來個應用就有幾百個DB連接,一不小心DB就給撐死。現在統一交由WAS內置DataSource處理,總共連接不到30個。其實,我們項目開始部署時,就是這樣做的,但當時WAS內置的DataSource對JTA(XA)支持有bug (這個和IBM技術支持確認過,但他們沒有給予很好的解決方案),不過Datasource還是配好的。 

但是這個工作已經屬於WAS性能優化的主題了,而且優化值必須持續觀察一段時間,通過專門的分析工具來計算。 
優化本身,是一項很考驗人的工作,我就簡單說一下最實用方法吧,也許是專門針對IBM的產品。 
1、清理歸零WAS日誌。然後啓動WAS,生成日誌(-verbose:gc默認是開的) 
2、讓WAS持續運行約兩週,讓JVM Heap佔用曲線平穩一段時間即可(用IBM的Garbage Collector分析觀察)。 
3、在AIX的shell裏,產生heapdump.phd文件,也就是heap快照。命令:kill -3 pid (pid是WAS的PID,通過ps –ef查看),觀察heap當時的碎片情況,是否需要單獨分大對象區(一般不需要設置),特別是那個方法區Class對象大小(p-cluster參數)。 
4、通過GC工具,觀察GC平均時間、Heap實際佔用情況。Note: GC是一個Stop The World過程,也就是說GC時系統對外不響應,多CPU也不例外。看你的應用實際需求了,GC持續時間和頻率是矛盾的,另外還有性能考慮。一般Web應用,我想讓GC持續時間(Pause time)調節到合理值就ok了,譬如0.2到0.4s。 
5、根據3可以算出k-cluster值,它是工具推薦值的110%。 
6、Heap的最小值是程序剛啓動不久的佔用值,譬如320M。切記:IBM JVM初始值太大非常不好。 
7、Heap的最大值是系統平穩後的100/70。也就是說如果最大值是1000M,那麼應該平穩時是700M,還有30%的空餘。IBM的JVM默認情下的碎片問題,WAS控制檯下操作Heap猛增這種bug,你不得不堤防。Heap最大值不設,AIX下的WAS肯定OOM。 

當然啦,我沒有考慮到大對象區的計算(雖然我們的應用設置了專門的大對象區),包括IBM JVM支持的分代GC、並行GC,Heap每次expand百分比等。那些情況我們一般不常用,譬如,你的AIX平臺一般不是16CPU吧? 

一口氣寫到現在,我忽然覺得該收尾了。下面就說說我對這類工作的整體看法吧。 
1、儘量在項目測試和試運行的時候就進行壓力、性能測試,當正式投入使用後,如果發現類似問題,代價非常大。躲過算你運氣好,一般來說,可能你們系統沒多少人用,也不是核心業務系統,譬如一般的電子政務。 
2、千萬不要低估了技術風險,用IBM的系列產品尤其要慎重,出問題一定不要忘了技術支持。而且,查資料時,建議用google English,因爲象WebSphere這類問題,很少有中文資料。 
3、程序部署環境建立時,就要考慮到日後的正式環境,譬如AIX的Paging Space、IO、分區大小,默認值往往是不行的,而且在產品環境下改這些值,往往非常難。 
4、在項目開發初期,就考慮到日誌的問題,因爲它分散到每個方法內,必須慎重定義好debug、info、warn、error級別,不要隨便忽視異常(catch裏面不記錄),到真正程序出問題時,它就是我們的最重要的依據之一。當然這主要是功能性問題診斷。另外對於高負載網站,日誌文件往往非常大,各級別日誌千萬不要混在一起,否則找問題就很困難了。 
5、怎麼說呢,別死扣技術,以爲什麼都可以通過技術解決。你看我們最大的問題就是把CMS給移到Tomcat下。你要是問我,爲什麼CMS產品會導致系統這麼多的問題,我也不知道,到那時候,我確實也不想深入。我只要知道,趕出你這個應用,我的系統就好控制多了。而且,那個CMS系統,在Tomcat下,就是跑得服服帖帖的,非常穩定。難度是可惡的WAS?不過那CMS,據IBM工程師,包括我們二次開發,都覺得夠爛了,每個jsp頁面都打開、關閉DB connection(7年前的jsp開發模式),還有那麼嚴重的大對象問題。 

好了,以上總結的幾點可能也不充分、深入,但如果你仔細讀我這篇文章,應該有自己的想法。畢竟,只有經過思考的東西,纔會屬於自己。 


————————————————- 
原文僅存的一點回復(google快照)

也許有人會說,我看完全文,發現你們遇到的問題還是很基礎啊。現在想想,也確實如此。不過,當時確實沒有方向。另外,一個人不太可能有這麼全面的知識。其實,最難的,還是那個IBM JVM的heap碎片問題,關鍵是你想不到,網上又很難搜到資料。大家要是用它後,出現OOM問題,一定要前車之鑑啊! 

newold 寫道 
我感覺WAS調優沒那麼難吧,你們應該在測試系統上做下壓力測試,不應該在生產系統上這麼折騰.解決這種問題,首先考慮把WAS升級到最新版,然後再考慮是不是程序問題.如果WAS是正版的,IBM應該會幫你們分析日誌的,我覺得你解決問題的方式不大對,把事情搞複雜了 
1、我接手這個活的時候,系統已經在生產環境幾個月了,這是我無法選擇的。當初準備切換到正式環境時,沒有人對這個問題引起重視,特別是領導,而且我當時也不在該小組。再說,誰會懷疑那個大名鼎鼎的CMS產品,中國恐怕是top 1。 

2、把WAS升級到最新版是我在接手這個活的時候已經做了(6.0.0.0到6.0.2.0),所以文中我沒有提及。另外,在診斷過程中也準備升級一次(從6.0.2.0到6.0.2.17),但考慮生產環境,風險太大。不過,我當時確實也總懷疑是否是這個原因,仔細讀了讀官方的bugfix(估計有幾千個)。 

3、“IBM應該會幫你們分析日誌的”,當然了。當我去向IBM技術支持諮詢時,他們向我要日誌。不過,他們和我對日誌的分析結果是一樣的,只是他們讓我更肯定了某些東西。主要就是文中那幾個截圖中的工具。另外,就是SystemOut.log日誌(看是否有線程掛起)。 
不過,對於IBM的技術支持,有點讓人失望的是,我們解決了OOM後,但我們的系統還是不穩定,再向他們諮詢時,那個WAS技術支持告訴我,他只提供IBM的WAS相關技術支持,如果你們告訴我WebLogic AS下很正常,我無法給你提供幫助,我們對其它公司的類似產品不瞭解。另外,如果你們懷疑是我們的AIX產品有問題,請諮詢我們的AIX技術支持(當前前提是我們的AIX還在服務期,對於那個WAS的售後服務,我們是用公司另外一個項目組的license,因爲我們的已經過期了)。 
也就是說,IBM無法給你提供全局的技術支持! 

4、一開始,我們根本就沒有方向,應用系統又多(兩個WAS上共30多個應用)。你仔細讀文章也會知道,我們的現象和推測往往都是矛盾的。 

什麼東西,都是解決了,經歷過了,再回轉頭來說,好簡單啊,當初我怎麼沒想到?就像中國股市,要是兩年前我都能夠預測了現在,我早就暴發了。 

而且,直到現在,我都可以坦率得說,不把那個CMS移出WAS,無論我們怎麼優化AIX、WAS和JVM,都很難解決問題! 
分享到: sina.jpgtec.jpg
評論
5 樓 txyly998 2011-08-05   
呵呵 謝謝你,我google下吧。 
我們的系統就是數據量太大才導致性能問題頻發的,最大的局點有一千幾百萬用戶、一千幾百萬訂購關係等等。
4 樓 zwchen 2011-08-05   
txyly998 寫道

現在就想問你一下,你說的按通用的JVM設置方式調整參數,這個有沒有具體點的步驟呢?

google Tomcat的一般參數設置方法,或是選擇WAS一般的調優參數。
像你們這種政務系統,一般是因爲加個WAS,項目合同可以翻倍,和WAS無關。而且,你們的負載應該是超低的(員工用)。

對於非分佈式應用(無RMI、EJB),WAS就是垃圾。

我隱約記得(好幾年沒關注了),IBM的JVM的GC和sun的不一樣,所以最大和最小的heap可能是設置不同的。
3 樓 txyly998 2011-08-04   
首先非常感謝你的回覆!謝謝! 

我們的這個系統在全國有13個局點在用,有些局點基本沒怎麼出現(在我接觸這個1年多的時間內),有些局點則1個月出現一兩次,項目組都沒多少人懂這類的問題,可能也沒有引起足夠的重視,最近出現的局點越來越多,而我是在公司支持現網的,現網有問題直接聯繫我這邊,所以想自己試着解決,目前感覺有點無從下手。 
對於你說的兩週重啓一次,這個不行的,現場沒事不能隨便重啓環境的,有特殊情況要重啓環境必須要向客戶申請。另外,出現問題後,watchdog會自動重啓系統或者切換雙機的。出現重啓或者切換,現場的人就要我們分析原因的。 
現在就想問你一下,你說的按通用的JVM設置方式調整參數,這個有沒有具體點的步驟呢?
2 樓 zwchen 2011-08-04   
txyly998 寫道
我們一個系統down掉了,生成了javacore和heapdump文件,有IBM Thread and Monitor Dump Analyzer for Java和IBM HeapAnalyzer工具,但是不知道怎麼分析這倆文件,能否指教下呢?多謝!

操作系統AIX5.3
JDK 1.5
華爲的uniportal平臺(Tomcat和Jboss結合到一起的)

如果只是down一次,沒有出現規律性的宕機,比如一週一次,暫時不用太考慮,因爲你的數據積累不夠。

你可以:
1、如果系統一個月宕一兩次,你可以兩週重啓一下服務
2、按通用的JVM設置方式,調整參數

我不太建議直接去分析headdump等問題,它必須對各種JVM的GC有很深入的瞭解,我當時也是自學過一兩個月,摸索着調成功的概率非常低。

如果你們的WAS還在技術支持範圍內,諮詢IBM北京。
自己去解決這種極其有難度的問題,從公司的角度是很不值的。

1 樓 txyly998 2011-08-02   
我們一個系統down掉了,生成了javacore和heapdump文件,有IBM Thread and Monitor Dump Analyzer for Java和IBM HeapAnalyzer工具,但是不知道怎麼分析這倆文件,能否指教下呢?多謝! 

操作系統AIX5.3 
JDK 1.5 
華爲的uniportal平臺(Tomcat和Jboss結合到一起的)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章