1. 程式人生 > >tomcat 調優

tomcat 調優

github sys asn git 設置 cronolog 左右 服務 ready

https://github.com/judasn/Linux-Tutorial/blob/master/Tomcat-Install-And-Settings.md

Tomcat 8 安裝和配置、優化

Tomcat 8 安裝

  • Tomcat 8 安裝
    • 官網:http://tomcat.apache.org/
    • Tomcat 8 官網下載:http://tomcat.apache.org/download-80.cgi
    • 此時(20160207) Tomcat 8 最新版本為:apache-tomcat-8.0.32.tar.gz
    • 我個人習慣 /opt 目錄下創建一個目錄 setups 用來存放各種軟件安裝包;在 /usr 目錄下創建一個 program
      用來存放各種解壓後的軟件包,下面的講解也都是基於此習慣
    • 我個人已經使用了第三方源:EPEL、RepoForge,如果你出現 yum install XXXXX 安裝不成功的話,很有可能就是你沒有相關源,請查看我對源設置的文章 - Tomcat 8 下載(201706 更新:舊版本失效):wget http://apache.fayea.com/tomcat/tomcat-8/v8.0.44/bin/apache-tomcat-8.0.44.tar.gz
    • 壓縮包解壓:tar -zxvf apache-tomcat-8.0.32.tar.gz
    • 移到解壓出來文件夾到 /usr 下:mv apache-tomcat-8.0.32/ /usr/program/
    • 為了方便,修改解壓目錄的名字:mv /usr/program/apache-tomcat-8.0.32/ /usr/program/tomcat8/
  • 設置 Iptables 規則(這一步是必須設置的):
    • 一種方式:先關閉 iptables,防止出現攔截問題而測試不了:service iptables stop
    • 一種方式:在 iptables 中添加允許規則(Tomcat 默認端口是 8080):
      • 添加規則:iptables -I INPUT -p tcp -m tcp --dport 8080 -j ACCEPT
      • 保存規則:service iptables save
      • 重啟 iptables:service iptables restart
  • 測試安裝好後的 Tomcat:
    • 啟動 Tomcat:sh /usr/program/tomcat8/bin/startup.sh ; tail -200f /usr/program/tomcat8/logs/catalina.out
    • 訪問:http://服務器 IP 地址:8080/
    • 停止 Tomcat:sh /usr/program/tomcat8/bin/shutdown.sh
  • 如果啟動報:java.net.UnknownHostException 或 localhost. This prevents creation of a GUID
    • 解決辦法:
      • 修改配置文件:vim /etc/sysconfig/network,把裏面的 HOSTNAME 改為你自己設置的一個名字,比如我這邊改為:youmeek
      • 修改配置文件:vim /etc/hosts,把第一行的 127.0.0.1 這一行刪掉,然後再最後一行增加這句:127.0.0.1 localhost youmeek,這裏最後的 youmeek 就是主機名
      • 然後重啟計算機:reboot
  • 如果啟動報:java.net.BindException: 地址已在使用 / java.net.BindException: Address already in use
    • 解決辦法:這表示端口被占用,修改 Tomcat 的 server.xml 配置文件,把端口改了即可。

Tomcat 8 配置

  • 設置 Tomcat 相關變量:
    • vim /usr/program/tomcat8/bin/catalina.sh
    • 在配置文件的可編輯內容最上面(98 行開始),加上如下內容(具體參數根據你服務器情況自行修改):
     JAVA_HOME=/usr/program/jdk1.8.0_72
     CATALINA_HOME=/usr/program/tomcat8
     CATALINA_OPTS="-Dfile.encoding=UTF-8 -server -Xms2048m -Xmx2048m -Xmn1024m -XX:PermSize=256m -XX:MaxPermSize=512m -XX:SurvivorRatio=10 -XX:MaxTenuringThreshold=15 -XX:NewRatio=2 -XX:+DisableExplicitGC"
     CATALINA_PID=$CATALINA_HOME/catalina.pid
  • 如果使用 shutdown.sh 還無法停止 tomcat,可以修改其配置:vim /usr/program/tomcat8/bin/shutdown.sh
    • 把最尾巴這一行:exec "$PRGDIR"/"$EXECUTABLE" stop "[email protected]"
    • 改為:exec "$PRGDIR"/"$EXECUTABLE" stop 10 -force

Tomcat 8 優化

  • Tomcat 6/7/8 的優化參數有點不一樣,最好按下面的方式看一下官網這個文檔是否還保留著這個參數
  • 啟動tomcat,訪問該地址,下面要講解的一些配置信息,在該文檔下都有說明的:
    • 文檔:http://127.0.0.1:8080/docs/config
    • 你也可以直接看網絡版本:
      • Tomcat 6 文檔:https://tomcat.apache.org/tomcat-6.0-doc/config
      • Tomcat 7 文檔:https://tomcat.apache.org/tomcat-7.0-doc/config/
      • Tomcat 8 文檔:https://tomcat.apache.org/tomcat-8.0-doc/config/
  • 如果你需要查看 Tomcat 的運行狀態可以配置tomcat管理員賬戶,然後登陸 Tomcat 後臺進行查看
  • 編輯 /opt/tomcat7/bin/conf/tomcat-users.xml 文件,在裏面添加下面信息:
<role rolename="manager"/>
<role rolename="manager-gui"/>
<role rolename="admin"/>
<role rolename="admin-gui"/>
<user username="tomcat" password="tomcat" roles="admin-gui,admin,manager-gui,manager"/>
  • 編輯配置文件:vim /usr/program/tomcat7/conf/server.xml
    • 打開默認被註釋的連接池配置:
      • 默認值:
       <!--
       <Executor name="tomcatThreadPool" namePrefix="catalina-exec-"
           maxThreads="150" minSpareThreads="4"/>
       -->
      • 修改為:
      <Executor
              name="tomcatThreadPool"
              namePrefix="catalina-exec-"
              maxThreads="500"
              minSpareThreads="30"
              maxIdleTime="60000"
              prestartminSpareThreads = "true"
              maxQueueSize = "100"
      />
      • 重點參數解釋:
        • maxThreads,最大並發數,默認設置 200,一般建議在 500 ~ 800,根據硬件設施和業務來判斷
        • minSpareThreads,Tomcat 初始化時創建的線程數,默認設置 25
        • prestartminSpareThreads,在 Tomcat 初始化的時候就初始化 minSpareThreads 的參數值,如果不等於 true,minSpareThreads 的值就沒啥效果了
        • maxQueueSize,最大的等待隊列數,超過則拒絕請求
        • maxIdleTime,如果當前線程大於初始化線程,那空閑線程存活的時間,單位毫秒,默認60000=60秒=1分鐘。
    • 修改默認的鏈接參數配置:
      • 默認值:
      <Connector 
          port="8080" 
          protocol="HTTP/1.1" 
          connectionTimeout="20000" 
          redirectPort="8443" 
      />
      • 修改為:
      <Connector 
         executor="tomcatThreadPool"
         port="8080" 
         protocol="org.apache.coyote.http11.Http11Nio2Protocol" 
         connectionTimeout="20000" 
         maxConnections="10000" 
         redirectPort="8443" 
         enableLookups="false" 
         acceptCount="100" 
         maxPostSize="10485760" 
         maxHttpHeaderSize="8192" 
         compression="on" 
         disableUploadTimeout="true" 
         compressionMinSize="2048" 
         acceptorThreadCount="2" 
         compressableMimeType="text/html,text/xml,text/plain,text/css,text/javascript,application/javascript" 
         URIEncoding="utf-8"
      />
      • 重點參數解釋:
        • protocol,Tomcat 8 設置 nio2 更好:org.apache.coyote.http11.Http11Nio2Protocol(如果這個用不了,就用下面那個)
        • protocol,Tomcat 6、7 設置 nio 更好:org.apache.coyote.http11.Http11NioProtocol
        • enableLookups,禁用DNS查詢
        • acceptCount,指定當所有可以使用的處理請求的線程數都被使用時,可以放到處理隊列中的請求數,超過這個數的請求將不予處理,默認設置 100
        • maxPostSize,以 FORM URL 參數方式的 POST 提交方式,限制提交最大的大小,默認是 2097152(2兆),它使用的單位是字節。10485760 為 10M。如果要禁用限制,則可以設置為 -1。
        • acceptorThreadCount,用於接收連接的線程的數量,默認值是1。一般這個指需要改動的時候是因為該服務器是一個多核CPU,如果是多核 CPU 一般配置為 2.
        • maxHttpHeaderSize,http請求頭信息的最大程度,超過此長度的部分不予處理。一般8K。
    • 禁用 AJP(如果你服務器沒有使用 Apache)
      • 把下面這一行註釋掉,默認 Tomcat 是開啟的。
       <!-- <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" /> -->

JVM 優化

  • 模型資料來源:http://xmuzyq.iteye.com/blog/599750
  • 配比資料:http://www.jianshu.com/p/d45e12241af4
  • Java 的內存模型分為:
    • Young,年輕代(易被 GC)。Young 區被劃分為三部分,Eden 區和兩個大小嚴格相同的 Survivor 區,其中 Survivor 區間中,某一時刻只有其中一個是被使用的,另外一個留做垃圾收集時復制對象用,在 Young 區間變滿的時候,minor GC 就會將存活的對象移到空閑的Survivor 區間中,根據 JVM 的策略,在經過幾次垃圾收集後,任然存活於 Survivor 的對象將被移動到 Tenured 區間。
    • Tenured,終身代。Tenured 區主要保存生命周期長的對象,一般是一些老的對象,當一些對象在 Young 復制轉移一定的次數以後,對象就會被轉移到 Tenured 區,一般如果系統中用了 application 級別的緩存,緩存中的對象往往會被轉移到這一區間。
    • Perm,永久代。主要保存 class,method,filed 對象,這部門的空間一般不會溢出,除非一次性加載了很多的類,不過在涉及到熱部署的應用服務器的時候,有時候會遇到 java.lang.OutOfMemoryError : PermGen space 的錯誤,造成這個錯誤的很大原因就有可能是每次都重新部署,但是重新部署後,類的 class 沒有被卸載掉,這樣就造成了大量的 class 對象保存在了 perm 中,這種情況下,一般重新啟動應用服務器可以解決問題。
  • Linux 修改 /usr/program/tomcat7/bin/catalina.sh 文件,把下面信息添加到文件第一行。
    • 如果服務器只運行一個 Tomcat
      • 機子內存如果是 4G:
        • CATALINA_OPTS="-Dfile.encoding=UTF-8 -server -Xms2048m -Xmx2048m -Xmn1024m -XX:PermSize=256m -XX:MaxPermSize=512m -XX:SurvivorRatio=10 -XX:MaxTenuringThreshold=15 -XX:NewRatio=2 -XX:+DisableExplicitGC"
      • 機子內存如果是 8G:
        • CATALINA_OPTS="-Dfile.encoding=UTF-8 -server -Xms4096m -Xmx4096m -Xmn2048m -XX:PermSize=256m -XX:MaxPermSize=512m -XX:SurvivorRatio=10 -XX:MaxTenuringThreshold=15 -XX:NewRatio=2 -XX:+DisableExplicitGC"
      • 機子內存如果是 16G:
        • CATALINA_OPTS="-Dfile.encoding=UTF-8 -server -Xms8192m -Xmx8192m -Xmn4096m -XX:PermSize=256m -XX:MaxPermSize=512m -XX:SurvivorRatio=10 -XX:MaxTenuringThreshold=15 -XX:NewRatio=2 -XX:+DisableExplicitGC"
      • 機子內存如果是 32G:
        • CATALINA_OPTS="-Dfile.encoding=UTF-8 -server -Xms16384m -Xmx16384m -Xmn8192m -XX:PermSize=256m -XX:MaxPermSize=512m -XX:SurvivorRatio=10 -XX:MaxTenuringThreshold=15 -XX:NewRatio=2 -XX:+DisableExplicitGC"
    • 如果是 8G 開發機
      • -Xms2048m -Xmx2048m -XX:NewSize=512m -XX:MaxNewSize=1024m -XX:PermSize=256m -XX:MaxPermSize=512m
    • 如果是 16G 開發機
      • -Xms4096m -Xmx4096m -XX:NewSize=1024m -XX:MaxNewSize=2048m -XX:PermSize=256m -XX:MaxPermSize=512m
    • 參數說明:
     -Dfile.encoding:默認文件編碼
     -server:表示這是應用於服務器的配置,JVM 內部會有特殊處理的
     -Xmx1024m:設置JVM最大可用內存為1024MB
     -Xms1024m:設置JVM最小內存為1024m。此值可以設置與-Xmx相同,以避免每次垃圾回收完成後JVM重新分配內存。
     -Xmn1024m:設置JVM新生代大小(JDK1.4之後版本)。一般-Xmn的大小是-Xms的1/2左右,不要設置的過大或過小,過大導致老年代變小,頻繁Full GC,過小導致minor GC頻繁。如果不設置-Xmn,可以采用-XX:NewRatio=2來設置,也是一樣的效果
     -XX:NewSize:設置新生代大小
     -XX:MaxNewSize:設置最大的新生代大小
     -XX:PermSize:設置永久代大小
     -XX:MaxPermSize:設置最大永久代大小
     -XX:NewRatio=4:設置年輕代(包括 Eden 和兩個 Survivor 區)與終身代的比值(除去永久代)。設置為 4,則年輕代與終身代所占比值為 1:4,年輕代占整個堆棧的 1/5
     -XX:MaxTenuringThreshold=10:設置垃圾最大年齡,默認為:15。如果設置為 0 的話,則年輕代對象不經過 Survivor 區,直接進入年老代。對於年老代比較多的應用,可以提高效率。如果將此值設置為一個較大值,則年輕代對象會在 Survivor 區進行多次復制,這樣可以增加對象再年輕代的存活時間,增加在年輕代即被回收的概論。需要註意的是,設置了 -XX:MaxTenuringThreshold,並不代表著,對象一定在年輕代存活15次才被晉升進入老年代,它只是一個最大值,事實上,存在一個動態計算機制,計算每次晉入老年代的閾值,取閾值和MaxTenuringThreshold中較小的一個為準。
     -XX:+DisableExplicitGC:這個將會忽略手動調用 GC 的代碼使得 System.gc() 的調用就會變成一個空調用,完全不會觸發任何 GC
  • Windows 修改 /tomcat7/bin/catalina.bat 文件,找到這一行:echo Using CATALINA_BASE: "%CATALINA_BASE%",然後在其上面添加如下內容,此方法只對解壓版的 Tomcat 有效果,對於安裝版本的需要點擊安裝後任務欄上的那個 Tomcat 圖標,打開配置中有一個 Java Tab 的進行編輯。
set JAVA_OPTS=%JAVA_OPTS% -Dfile.encoding="UTF-8" -Dsun.jnu.encoding="UTF8" -Ddefault.client.encoding="UTF-8" -Duser.language=Zh
set JAVA_OPTS=%JAVA_OPTS% -server -Xms4096m -Xmx4096m -Xmn2048m -XX:PermSize=256m -XX:MaxPermSize=512m -XX:SurvivorRatio=10 -XX:MaxTenuringThreshold=15 -XX:NewRatio=2 -XX:+DisableExplicitGC

Tomcat 8 的 Log 分割

  • 修改前提:本人為 Tomcat8.5,安裝目錄為:/usr/program/tomcat8
  • 網絡上的官網地址現在打不開:http://cronolog.org/download/index.html
  • 阿裏雲的 CentOS 有 epel 源所以可以直接下載:yum install cronolog,此時:2017-02,最新版本為:1.6.2-10.el6
  • 安裝完後,查看下安裝後的目錄位置:which cronolog,我這邊得到的結果是:/usr/sbin/cronolog,記下這個結果,後面有用到。
  • 修改 catalina.sh 中的內容:vim /usr/program/tomcat8/bin/catalina.sh
  • 找到這段代碼(預計在 416 行前後):
shift
touch "$CATALINA_OUT"
if [ "$1" = "-security" ] ; then
if [ $have_tty -eq 1 ]; then
  echo "Using Security Manager"
fi
shift
eval $_NOHUP "\"$_RUNJAVA\"" "\"$LOGGING_CONFIG\"" $LOGGING_MANAGER $JAVA_OPTS $CATALINA_OPTS   -classpath "\"$CLASSPATH\""   -Djava.security.manager   -Djava.security.policy=="\"$CATALINA_BASE/conf/catalina.policy\""   -Dcatalina.base="\"$CATALINA_BASE\""   -Dcatalina.home="\"$CATALINA_HOME\""   -Djava.io.tmpdir="\"$CATALINA_TMPDIR\""   org.apache.catalina.startup.Bootstrap "[email protected]" start   >> "$CATALINA_OUT" 2>&1 "&"

else
eval $_NOHUP "\"$_RUNJAVA\"" "\"$LOGGING_CONFIG\"" $LOGGING_MANAGER $JAVA_OPTS $CATALINA_OPTS   -classpath "\"$CLASSPATH\""   -Dcatalina.base="\"$CATALINA_BASE\""   -Dcatalina.home="\"$CATALINA_HOME\""   -Djava.io.tmpdir="\"$CATALINA_TMPDIR\""   org.apache.catalina.startup.Bootstrap "[email protected]" start   >> "$CATALINA_OUT" 2>&1 "&"

fi
  • 將上面代碼改為如下,其中請註意這個關鍵字:/usr/sbin/cronolog,這個是我上面提到的安裝路徑,你如果跟我不一樣,需要自己修改該相關。
shift
# touch "$CATALINA_OUT"
if [ "$1" = "-security" ] ; then
if [ $have_tty -eq 1 ]; then
  echo "Using Security Manager"
fi
shift
eval $_NOHUP "\"$_RUNJAVA\"" "\"$LOGGING_CONFIG\"" $LOGGING_MANAGER $JAVA_OPTS $CATALINA_OPTS   -classpath "\"$CLASSPATH\""   -Djava.security.manager   -Djava.security.policy=="\"$CATALINA_BASE/conf/catalina.policy\""   -Dcatalina.base="\"$CATALINA_BASE\""   -Dcatalina.home="\"$CATALINA_HOME\""   -Djava.io.tmpdir="\"$CATALINA_TMPDIR\""   org.apache.catalina.startup.Bootstrap "[email protected]" start 2>&1 | /usr/sbin/cronolog "$CATALINA_BASE"/logs/catalina.%Y-%m-%d.out >> /dev/null &

else
eval $_NOHUP "\"$_RUNJAVA\"" "\"$LOGGING_CONFIG\"" $LOGGING_MANAGER $JAVA_OPTS $CATALINA_OPTS   -classpath "\"$CLASSPATH\""   -Dcatalina.base="\"$CATALINA_BASE\""   -Dcatalina.home="\"$CATALINA_HOME\""   -Djava.io.tmpdir="\"$CATALINA_TMPDIR\""   org.apache.catalina.startup.Bootstrap "[email protected]" start 2>&1 | /usr/sbin/cronolog "$CATALINA_BASE"/logs/catalina.%Y-%m-%d.out >> /dev/null &

fi

靜止外網通過 8080 端口訪問 Tomcat

  • 添加 iptables 規則:
    • iptables -t filter -A INPUT -p tcp -m tcp --dport 8080 -s localhost -j ACCEPT
    • iptables -t filter -A INPUT -p tcp -m tcp --dport 8080 -j REJECT
    • service iptables save
    • service iptables restart

tomcat 調優