歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> Linux教程 >> Linux生產環境下tomcat宕掉解決辦法

Linux生產環境下tomcat宕掉解決辦法

日期:2017/2/27 15:54:53   编辑:Linux教程
對於中小公司使用tomcat作為java容器,沒有經過系統的調優很容易出現tomcat在運行過程中出現服務宕掉,並且在tomcat的日志中一般無法看出有用的信息,而此次實例中對tomcat宕機後調優,是由公司的構架進行調整,他是對JVM調優有著非常深的理解,而作者對JVM調優的理解比較淺薄,所以本實例不會過多講解調優的原理,只記錄分析和調優的過程,希望能給各位遇到tomcat宕機的運維朋友們帶來一點思路。

一、tomcat宕掉初步分析
生產環境的tomcat會在隔幾天的情況下服務宕掉,這其中沒有規律,有規律的是tomcat宕掉每次都是在版本升級後重啟10分鐘~60分鐘內,並不是每次重啟tomcat都會宕掉,如果tomcat啟動超過一天,運行過程中是不會宕掉的,而且再次重啟tomcat後,就不會再出現tomcat宕掉的情況,這可以初步排除上線代碼導致的主因(新代碼上線其實也是有一部分原因,後面會講)。

查看tomcat的catalina.out日志:
2015-1-5 13:35:41 org.apache.coyote.http11.Http11NioProtocol pause
信息: Pausing Coyote HTTP/1.1 on http-8890
2015-1-5 13:35:42 org.apache.catalina.core.StandardService stop
信息: Stopping service Catalina
 
2015-1-5 13:35:42 org.apache.coyote.http11.Http11NioProtocol destroy
信息: Stopping Coyote HTTP/1.1 on http-8890
Exception in thread "Timer-1" java.lang.NullPointerException
        at com.qhfax.invest.balanceAccount.common.util.TaskBalanceAccount.run(TaskBalanceAccount.java:75)
        at java.util.TimerThread.mainLoop(Timer.java:512)
        at java.util.TimerThread.run(Timer.java:462)
通過日志可以看到,tomcat先暫停了http服務的8890端口,然後停止了核心服務。

很明顯,從上面的日志,我們無法看到任何的有用信息,那該如何辦呢?

二、tomcat內存分析調優-開啟GC日志
既然從日志無法看出tomcat是如何宕掉的,那麼我們就從分析tomcat內存開始,可以開啟gc日志,記錄日常JVM在清理內存時的情況,具體步驟如下:

先展示下,未做過調優前生產tomcat的配置情況(tomcat調優的核心就是JVM參數設置):
原配置:
編輯{tomcat_home}/bin/catalina.sh,可以直接在頂部#注釋說完後,就添加以下參數
export JRE_HOME=/usr/java/jdk1.6.0_38
export CATALINA_HOME=/home/resin/tomcat
JAVA_OPTS="-Xms1024m -Xmx1024m -XX:PermSize=512m -XX:MaxPermSize=512m"
JVM啟動參數說明:
-Xms1024m 設置JVM最小可用內存為1024M
-Xmx1024m 設置JVM最大可用內存為1024M
-XX:PermSize=512m JVM初始分配的非堆內存
-XX:MaxPermSize=512m 設置持久代大小為512M
修改後配置:
export JRE_HOME=/usr/java/jdk1.6.0_38
export CATALINA_HOME=/home/resin/tomcat
JAVA_OPTS="-server -Xms2048m -Xmx2048m -Xmn512m -XX:+UseParallelOldGC -XX:+PrintGCDateStamps -XX:+PrintGCDetails -Xloggc:/home/resin/tomcat/logs/gc.log"
調優後JVM啟動參數說明:
-server server模式啟動速度較慢,但是一旦運行起來後,性能將會有很大的提升
-Xmn512m 設置年輕代大小為2G。整個堆大小=年輕代大小 + 年老代大小 + 持久代大小。持久代一般固定大小為64m,所以增大年輕代後,將會減小年老代大小。此值對系統性能影響較大,Sun官方推薦配置為整個堆的3/8。
-XX:+UseParallelOldGC 執行垃圾回收器,一般在多線程多處理器機器上使用
-XX:+PrintGCDateStamps 記錄GC日志並不會特別地影響Java程序性能
-XX:+PrintGCDetails 打印收集的其他信息
-Xloggc:/****/****/tomcat/logs/gc.log GC日志路徑地址
2.tomcat配置文件server.xml
原配置:
<Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
    <Connector port="8890" protocol="HTTP/1.1" 
            URIEncoding="UTF-8"   connectionUploadTimeout="36000000" disableUploadTimeout="false" connectionTimeout="60000"    
               redirectPort="8443" />
修改後配置:
 <!-- Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" gcDaemonProtection="false"/ -->   #此語句注釋掉
    <Connector executor="tomcatThreadPool"
               port="8890" protocol="org.apache.coyote.http11.Http11NioProtocol" 
   connectionUploadTimeout="36000000" 
               disableUploadTimeout="false" 
               connectionTimeout="60000" 
               redirectPort="8443" />
說明:注釋掉的語句是為了減少JVM的周期性的Full GC頻繁問題。

在初步調優後,之後又出現了一次tomcat宕掉,看來tomcat調優沒有還需要繼續,通過查看gc.log:
2015-01-07T14:29:45.658+0800: 169496.327: [GC [PSYoungGen: 5069K->4064K(514304K)] 40126K->39121K(2087168K), 0.0034770 secs] [Times: user=0.04 sys=0.00, real=0.01 secs] 
2015-01-07T14:29:45.661+0800: 169496.331: [Full GC (System) [PSYoungGen: 4064K->0K(514304K)] [ParOldGen: 35057K->38587K(1572864K)] 39121K->38587K(2087168K) [PSPermGen: 51269K->51269K(72128K)], 0.3473340 secs] [Times: user=1.42 sys=0.00, real=0.35 secs] 
2015-01-07T14:55:31.114+0800: 171041.784: [GC [PSYoungGen: 212923K->9959K(514048K)] 251510K->54259K(2086912K), 0.0073020 secs] [Times: user=0.06 sys=0.00, real=0.00 secs] 
2015-01-07T14:55:31.122+0800: 171041.791: [Full GC (System) [PSYoungGen: 9959K->0K(514048K)] [ParOldGen: 44299K->34703K(1572864K)] 54259K->34703K(2086912K) [PSPermGen: 51276K->51274K(69440K)], 0.2653740 secs] [Times: user=0.79 sys=0.01, real=0.27 secs] 
2015-01-07T14:55:31.531+0800: 171042.200: [GC [PSYoungGen: 5345K->2304K(507776K)] 40048K->37007K(2080640K), 0.0024170 secs] [Times: user=0.02 sys=0.00, real=0.00 secs] 
2015-01-07T14:55:31.533+0800: 171042.203: [Full GC (System) [PSYoungGen: 2304K->0K(507776K)] [ParOldGen: 34703K->36747K(1572864K)] 37007K->36747K(2080640K) [PSPermGen: 51364K->51363K(67264K)], 0.2703940 secs] [Times: user=0.83 sys=0.00, real=0.28 secs] 
2015-01-07T14:55:37.374+0800: 171048.044: [GC [PSYoungGen: 10021K->10878K(508416K)] 46768K->47625K(2081280K), 0.0026770 secs] [Times: user=0.02 sys=0.00, real=0.01 secs] 
2015-01-07T14:55:37.377+0800: 171048.046: [Full GC (System) [PSYoungGen: 10878K->0K(508416K)] [ParOldGen: 36747K->34645K(1572864K)] 47625K->34645K(2081280K) [PSPermGen: 51364K->51363K(65216K)], 0.2716380 secs] [Times: user=0.86 sys=0.00, real=0.27 secs] 
2015-01-07T14:55:37.670+0800: 171048.339: [GC [PSYoungGen: 3948K->2880K(510016K)] 38594K->37525K(2082880K), 0.0025790 secs] [Times: user=0.03 sys=0.00, real=0.00 secs] 
2015-01-07T14:55:37.672+0800: 171048.342: [Full GC (System) [PSYoungGen: 2880K->0K(510016K)] [ParOldGen: 34645K->37317K(1572864K)] 37525K->37317K(2082880K) [PSPermGen: 51363K->51363K(63104K)], 0.2714200 secs] [Times: user=0.84 sys=0.00, real=0.27 secs] 
2015-01-07T15:33:44.205+0800: 173334.875: [GC [PSYoungGen: 153420K->14231K(505728K)] 190738K->51548K(2078592K), 0.0048450 secs] [Times: user=0.04 sys=0.00, real=0.00 secs] 
2015-01-07T15:33:44.210+0800: 173334.880: [Full GC (System) [PSYoungGen: 14231K->0K(505728K)] [ParOldGen: 37317K->34594K(1572864K)] 51548K->34594K(2078592K) [PSPermGen: 51364K->51359K(61440K)], 0.2908710 secs] [Times: user=0.89 sys=0.00, real=0.29 secs] 
2015-01-07T15:33:44.514+0800: 173335.183: [GC [PSYoungGen: 3254K->2560K(506816K)] 37849K->37154K(2079680K), 0.0024490 secs] [Times: user=0.03 sys=0.00, real=0.00 secs] 
2015-01-07T15:33:44.516+0800: 173335.186: [Full GC (System) [PSYoungGen: 2560K->0K(506816K)] [ParOldGen: 34594K->36883K(1572864K)] 37154K->36883K(2079680K) [PSPermGen: 51360K->51360K(60224K)], 0.2721010 secs] [Times: user=0.82 sys=0.00, real=0.27 secs]
發現,tomcat會周期在一段時間頻繁的進行full gc,說明從JVM內存出發對tomcat調優方向是對的。

二、tomcat內存分析調優-開啟HeapDump
僅僅開啟gc.log還是無法分析出tomcat宕掉的具體原因,到底是由什麼導致的,這時候就要針對tomcat的OutOfMemory時的內存情況進行分析,於是構架師又進行了第二次調優:

調整JVM啟動參數
原:JAVA_OPTS="-server -Xms2048m -Xmx2048m -Xmn512m -XX:+UseParallelOldGC -XX:+PrintGCDateStamps -XX:+PrintGCDetails -Xloggc:/home/resin/tomcat/logs/gc.log"
修改後: 
JAVA_OPTS="-server -Xms2048m -Xmx2048m -Xmn768m -XX:PermSize=128m -XX:MaxPermSize=256m -XX:+UseParallelOldGC -XX:+PrintGCDateStamps -XX:+PrintGCDetails -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/home/resin/tomcat/dumpfile/heap.bin  -Xloggc:/home/resin/tomcat/logs/gc.log"
調優後JVM啟動參數說明:
-XX:PermSize=128m 方法區內存從默認20M,提高到128M
-XX:MaxPermSize=256m 限定方法區內存最大256M
-XX:+UseParallelOldGC 相當於” Parallel Scavenge” + “ParallelOld”,都是多線程並行處理
-XX:+HeapDumpOnOutOfMemoryError 開啟HeapDump
-XX:HeapDumpPath=/*****/****/tomcat/dumpfile/heap.bin HeapDump輸出路徑

三、如何對HeapDump文件分析
在上次調優後,tomcat很穩定的跑了2個月,但年後又出現了一次服務宕掉,並且聲稱了HeapDump文件,那麼我們就要對HeapDump文件進行分析了。

先將HeapDump文件從服務器傳輸到你的本地電腦。

使用MemoryAnalyzer-1.4.0.20140604-win32.win32.x86這個軟件,使用過程我會在下面截圖,軟件是構架給我的,51cto下載地址:點這裡

或者打開這個鏈接:http://down.51cto.com/data/2006879

打開MemoryAnalyzer.exe,導入HeapDump文件







至此,我們就大致找到了導致此次tomcat宕掉的原因,剩下的就是將此次分析報告交給上司,後面的工作就是開發的了,可以看到因代碼或應用無限循環導致內存洩露,再對JVM調優已無意義。
原文:http://vekergu.blog.51cto.com/9966832/1619640

Copyright © Linux教程網 All Rights Reserved