2012-12-18日
下午開會探討北京項目出現的一些問題,當時記錄的問題是由可能因為有一定數量的客戶上來后,就造成了Web服務器宕機,而且沒有任何時間上的規律性,讓我準備出差到北京,限定三天時間,以及準備測試壓力的工具軟件等等。
2012-12-19日
上午飛抵北京后,進行了安頓安排,以及開會聽王經理講了一下情況。由于服務器已經在生產網上,客戶在使用,北京大概有100多個將近200個收費網點,每天都有很多客戶在排隊繳費,所以不能進行相關的壓力測試,只能在晚上進行。下午針對簡單的操作編寫了壓力測試用的操作邏輯。
晚上和大家一起進行做對系統的初步壓力檢測。
檢測結果:
本機搭建的Web服務器和一臺數據庫Oracle服務器并發1000人的登陸的結果是,雖然內存有逐步的上漲,但沒有宕機。
真對運行生產網進行了壓力測試檢驗后,和白天也出現的宕機狀態一樣,初步分析應該不是因為程序的架構缺陷,以及程序的編寫缺陷造成的原因。
2012-12-20日
針對系統現象表明,如果在集群內,一臺服務器宕機,另外一臺服務器不在集群入口進入的話,還可以使用。但如果有新登陸的客戶,如果被分載到了宕機節點后,就會登陸不進去。晚上測試的現象表明,如果宕機了,Tomcat還沒有掛掉,而在登陸的時候連接不上數據庫,并且根本沒有連接數據庫失敗的報錯。但如果把數據庫服務器網線拔掉后,就會在頁面進行報錯,當時分析有可能是數據庫連接池的原因,但把數據庫連接池設置很小后,也會在頁面上提示連接失敗,并不會宕機。此時分析的結果,有可能是在連接發送到Oracle數據庫后,沒有返回造成的。隨即又做了個壓力測試,把Oracle服務器進行全面的性能壓力堵塞,在用Web服務器進行連接,這個時候很慢,頁面反應效果很像,點連不進去。不過Oracle的CPU和內存利用幾乎是百分之百,局域網內部人去連接Oracle服務器幾乎沒反應了。和白天的癥狀不一樣,白天一臺web服務器宕機后,另外一臺服務器還可以很順利的進行與Oracle服務器進行交互,而且其他用戶還可以利用PL/SQP查看系統有沒有死鎖等癥狀。由此判斷不是數據庫的原因。
2012-12-21日
由于針對前段癥狀的分析,程序上沒問題的話,懷疑可能是Tomcat服務器造成的原因。Tomcat導致宕機的最大可能性就是內存及緩存的溢出造成的。于是把JVM的內存和最大最小內存連接池以及線程池都設置到最低,然后Web服務器運行后開始進行壓力測試。雖然效果和昨天的頁面反應情況很像,從測試機器的Logs里可以查出(嚴重: Caught exception (java.lang.OutOfMemoryError: Java heap space)即內存溢出),但是,我又查看了一下服務器的相關記錄,并未找到任何一條關于內存溢出的錯誤日志。通過核對客戶群里對系統反應錯誤的時間,以及核對集群Apache和兩個Tomcat出錯日志的比對,看看是否能夠和集群的相關配置有關。
從日志的結果分析來看,apache在宕機時間內,有兩次顯示” [Thu Nov 15 14:13:05 2012] [warn] Server ran out of threads to serve requests. Consider raising the ThreadsPerChild setting”,這個意思是表明apache作為控制器來講,他的允許線程數已經不夠用了,后來看了一下Apache配置” conf/httpd.conf”文件,發現ThreadsPerChild默認為250。后來查詢了相關資料,這個線程一般為最大可以為1920,然后我就把它調節到了1000。由此分析,本系統的應用負載,是現在的架構節點遠遠不夠的。但從數據庫的日志,以及tomcat相關日志,并沒有對數據庫出現異常的相關信息,比如連接速度慢,查看了linux下oracle的日志,也并沒有線程以及內存相關的溢出信息,由此分析,瓶頸并不在oracle。于是為了驗證想法,又增加了兩個負載節點,觀察服務器的動向。
2012-12-22日
由于工作已經超出原定的三天,也就既來之則安之。而且經理說了,周六周日的人,并不多,每天上來繳費的網點差不多50,到60人左右,想最好是先觀察一下。不過今天是周六,一整天都平安無事。
2012-12-23日
為了安全起見,我對各種引起宕機可能的情況作了總結。一、內存溢出,二、表死鎖,三、數據庫連接池死鏈接,四、數據庫瓶頸壓力過大,五、負載均衡器入口瓶頸壓力過大。當日查看了tomcat的系統日志,發現session會話復制失敗率很高。因為兩個或多個web服務器做負載的時候,為了保證高可用,要在一臺服務器宕機后,自動切換到另外一臺服務器。但我們的系統有個問題,因為是采用extjs作為前端,ajax與后臺操作量非常大,從而導致服務器session復制兩就很大。
由Tomcat的系統管理頁面可以看出,http協議與外面交互,這一上午的吞吐量也不過52MB,而用于session復制的ajp協議,卻達到了133MB。為了認證這一說法,我把其中一臺節點服務器的session復制關掉,為了迎接明天壓力的到來。
2012-12-24日
今天上午的時候,反應還良好,只不過其中有一臺服務器稍微有些慢。不過到下午15:24的時候,從負載機,帶集群節點,統一宕機。當然其中也包括我那臺被關閉session復制的服務器,當時我就蒙圈了。我覺得不可能,沒有任何理由啊。因為從負載機進去,就一個IP地址,但各個集群機都有各自的IP或端口,即使是一兩個節點宕機,乃至三個節點宕機,但其中那臺沒session復制的機器也不應該啊。難道是Oracle有防火墻,同一時間出現網絡閃斷,但那也不用非得重啟web服務器才好用啊,因為重啟一個節點時,那個節點就好用了,不過另外的節點還是不好用。晚上的時候,開始在Linux查找各種問題。連接,以及日志,結果還是沒問題。
2012-12-25日
沒辦法了,只能出最后絕招了。因為系統宕機原因跑不出那五個原因,我決心全面監視起來,每一個信息參數都記錄日志,然后進行分析。于是,我就做了個程序,監視內存,JVM內存,JVM的CPU,死鎖的表,用戶操作登陸及日志,連接池,以及web服務器和數據庫服務器的TCPIP流的吞吐量。剩下就是漫長的等待了,果然在下午兩點多,Tomcat的JVM空閑內存值,一個節點在一小時內急速下降到0,然后JVM內存溢出,緊接著表開始死鎖,然系統頁面開始反應緩慢。
通過以上的現象來看。一天的操作都很正常,空閑內存突然的下降。引起了我很大的懷疑,同時我查看了那個時刻的Http頁面的吞吐量。也是50多兆。不過JVM內存我可設置了1.5G,完全不是一個數量級別。就并發干整它一個星期,也宕機不了。一定是程序邏輯有問題,造成了內存超大的累加。
沒辦法,只能看是什么操作了,于是我劃定了宕機時間段兒,通過群里的聊天記錄,找出宕機的時間范圍,然后把這幾天的宕機時間內所有的操作日志調了出來,然后找出它們共同的操作。這個時候,“稅控機導入”,這個日志這個詞,緊排在“登陸/退出”的后面,立刻引起了我的注意。緊接著我就詢問了開發人員,然后再我機器上搭了一套模擬環境,開始對這個操作日志進行了壓力測試。結果表明,連續上傳了三次,系統就JVM內存不夠了,而且表被鎖住。因為如果傳一個比較大的excel,會出現上傳時間很長的狀態,如果沒有耐心煩,就會把頁面關閉,雖然關閉,數據庫連接池并沒有釋放。緊接著使用者就會再次登陸,在去實驗上傳,然后屢試不爽。當他在實驗的過程中,線程池,連接池一個個的被占滿,內存逐漸溢出。其他人使用,不但反應緩慢,而且登陸都登陸不上去(因為連接池被占有沒有釋放)。
就此為止,罪魁禍首就浮出了水面。
就此處問題,我提出了解決方案。因為系統硬件為16個G的內存,不過32位電腦JVM最大只支持到2G,而且excel上傳并不耗費很大資源,只不過系統在讀excel往數據庫里插的時候,會耗費很大的內存空間。本來tomcat就最大1.5G的支持,幾下就死掉。所以,只能把處理excel插數據庫的任務,交給另外的進程和線程去做。做個服務,或應用啥的。實時改造的方法,可以利用消息隊列進行業務接受。當上傳成功后,就在消息隊列內進行排序。然后服務讀取到消息后,進行處理,等成功后在回執。
?
2012-12-26日
準備收工,改造方案的落實。
?