tomcat8調優


a. tomcat的運行原理:

  1. Tomcat是運行在JVM中的一個進程。它定義為【中間件】,顧名思義,是一個在Java項目與JVM之間的中間容器。
  2. Web項目的本質,是一大堆的資源文件和方法。Web項目沒有入口方法(main方法),,意味着Web項目中的方法不會自動運行起來。
  3. Web項目部署進Tomcat的webapp中的目的是很明確的,那就是希望Tomcat去調用寫好的方法去為客戶端返回需要的資源和數據。
  4. Tomcat可以運行起來,並調用寫好的方法。那么,Tomcat一定有一個main方法。
  5. 對於Tomcat而言,它並不知道我們會有什么樣的方法,這些都只是在項目被部署進webapp下后才確定的,由此分析,必然用到了Java的反射
      來實現類的動態加載、實例化、獲取方法、調用方法。但是我們部署到Tomcat的中的Web項目必須是按照規定好的接口來進行編寫,以便進行調用
  6. Tomcat如何確定調用什么方法呢。這取卻於客戶端的請求,http://127.0.0.1:8080/wsota/wsota_index.jsp?show這樣的一個請求,
   通過http協議, 在瀏覽器發往本機的8080端口,攜帶的參數show方法,包含此方法的路徑為wsota,文件名為:wsota_index.jsp。


b. Tomcat運行機制:

    假設來自客戶的請求為:http://localhost:8080/wsota/wsota_index.jsp
  1. 請求端口8080,等待http請求。
  2. Connector把該請求交給它所在的Service的Engine來處理,並等待來自Engine的回應
  3. Engine獲得請求localhost/wsota/wsota_index.jsp,匹配到名為localhost的Host
  4. localhost Host獲得請求/wsota/wsota_index.jsp,匹配它所擁有的所有Context
  5. Host匹配到路徑為/wsota的Context(如果匹配不到就把該請求交給路徑名為""的Context去處理)
  6. path="/wsota"的Context獲得請求/wsota_index.jsp,在它的mappingtable中尋找對應的servlet
  7. Context匹配到URLPATTERN為*.jsp的servlet,對應於JspServlet類
  8. 構造HttpServletRequest對象和HttpServletResponse對象,作為參數調用JspServlet的doGet或doPost方法
  9. Context把執行完了之后的HttpServletResponse對象返回給Host
  10. Host把HttpServletResponse對象返回給Engine
  11. Engine把HttpServletResponse對象返回給Connector
  12. Connector把HttpServletResponse對象返回給客戶browser

 

c. tomcat調優:

  Tomcat配置文件server.xml 優化

<?xml version='1.0' encoding='utf-8'?>

<Server port="8005" shutdown="SHUTDOWN">
  <Listener className="org.apache.catalina.startup.VersionLoggerListener" />
  <!-- Security listener. Documentation at /docs/config/listeners.html
  <Listener className="org.apache.catalina.security.SecurityListener" />
  -->
  <!--APR library loader. Documentation at /docs/apr.html -->
  <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
  <!-- Prevent memory leaks due to use of particular java/javax APIs-->
  <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
  <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
  <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />

 
  <GlobalNamingResources>
    <Resource name="UserDatabase" auth="Container"
              type="org.apache.catalina.UserDatabase"
              description="User database that can be updated and saved"
              factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
              pathname="conf/tomcat-users.xml" />
  </GlobalNamingResources>

  
  <Service name="Catalina">

    <!-- 使用線程池 -->
    <!--
        name: 共享線程池的名字。這是Connector為了共享線程池要引用的名字,該名字必須唯一。
        namePrefix: 在JVM上,每個運行線程都可以有一個name字符串。這一屬性為線程池中每個線程的name字符串設置了一個前綴,Tomcat將把線程號追加到這一前綴的后面。默認值:tomcat-exec-;
        prestartminSpareThreads: 在 Tomcat 初始化的時候就初始化
        maxThreads:最大並發數,默認200,建議在 500 ~ 800,根據硬件設施和業務來判斷
        maxQueueSize: 最大的等待隊列數,超過則拒絕請求
        minSpareThreads:Tomcat初始化時創建的線程數,默認設置25
        maxIdleTime: 最大備用(空閑)線程數,如果空閑線程超過這個值,Tomcat就會關閉不活動線程,默認值:60000(一分鍾)。
    -->
    <Executor 
        name="tomcatThreadPool"         
        namePrefix="HTTP-8080-exec-"   
        prestartminSpareThreads="true" 
        maxThreads="800"  
        maxQueueSize="100" 
        minSpareThreads="50" 
        maxIdleTime="60000" />
              

    <!-- tomcat容器性能參數設置 -->
    <!--
        executor: 線程池
        port: 端口號
        redirectPort: 重定向端口號,https方式訪問資源時,此時Tomcat會自動重定向到這個redirectPort設置的https端口。
        proxyPort: 這個屬性指定了調用request.getServerPort()返回的端口值
        protocol: https://www.jianshu.com/p/e4d2d7aac14f
        acceptCount: 處理隊列中的請求數,默認值10。超過這個數值的請求將不予處理。一般大於或者等於maxThreads
        connectionTimeout: 網絡連接超時,默認值20000,單位:毫秒。設置為0表示永不超時,通常可設置為30000毫秒
        maxHttpHeaderSize: http請求頭信息的最大程度,超過此長度的部分不予處理。一般8K。
        enableLookups: 是否反查域名,默認值為true。為了提高處理能力,應設置為false 
        compression: 打開壓縮功能
        compressionMinSize: 啟用壓縮的輸出內容大小,默認為2KB
        compressableMimeType: 哪些資源類型需要壓縮 
        URIEncoding: 指定Tomcat容器的URL編碼格式
    -->
    <Connector
        executor="tomcatThreadPool" 
        port="8080" 
        redirectPort="8443" 
        proxyPort="8443" 
        protocol="org.apache.coyote.http11.Http11Nio2Protocol"
        acceptCount="1000"
        connectionTimeout="30000" 
        maxHttpHeaderSize="8192"
        enableLookups="false"
        compression="on"
        compressionMinSize="10240"
        compressableMimeType="text/html,text/xml,text/javascript,text/css,text/plain"
        URIEncoding="UTF-8"/>
   

    <!-- 
        AJP是為 Tomcat 與 HTTP 服務器之間通信而定制的協議,能提供較高的通信速度和效率。
        如果tomcat前端放的是apache的時候,會使用到AJP這個連接器。
        我們用nginx做的反向代理,不使用此連接器,因此需要注銷掉該連接器。 
    -->
    <!-- <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" /> -->

    <Engine name="Catalina" defaultHost="localhost">

        <Realm className="org.apache.catalina.realm.LockOutRealm">
            <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
               resourceName="UserDatabase"/>
        </Realm>

        <Host name="localhost"  appBase="webapps" unpackWARs="true" autoDeploy="true">
        <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
               prefix="localhost_access_log" suffix=".txt"
               pattern="%h %l %u %t &quot;%r&quot; %s %b" />

        </Host>
     
    </Engine>
  </Service>
</Server>

 

  JVM調優

  Tomcat並不建議直接在catalina.sh里配置變量,而是寫在與catalina同級目錄(bin目錄)下的setenv.sh里, 如果不存在, 則創建一個.

#!/bin/shexport
# 優化參考 https://blog.csdn.net/adrian_dai/article/details/80538059


# 設置JAVA_HOME
export JAVA_HOME=/usr/local/jdk1.8.0_201
export PATH=$PATH:$JAVA_HOME/bin
export CLASSPATH=$JAVA_HOME/lib


# 設置CATALINA_HOME
CATALINA_HOME=/data/tomcat/tomcat8080-console


# 參考地址: https://blog.csdn.net/y_blueblack/article/details/81066141
# -Xms:虛擬機初始化時的最小堆內存。
# -Xmx:虛擬機可使用的最大堆內存. -Xms與-Xmx設成一樣的值,避免JVM因為頻繁的GC導致性能大起大落
# 設定每個線程的堆棧大小。一般不宜設置超過1M,要不然容易出現out ofmemory
# AggressiveOpts: 啟用這個參數,則每當JDK版本升級時,你的JVM都會使用最新加入的優化技術(如果有的話)
# UseBiasedLocking: 啟用一個優化了的線程鎖。對於應用服務器來說每個http請求就是一個線程,由於請求需要的時長不一,在並發較大的時候會有請求排隊、甚至還會出現線程阻塞的現象,這個配置可以改善這個問題。
# PermSize: 設置非堆內存初始值,默認是物理內存的1/64;
# MaxPermSize: 設置最大非堆內存的大小,默認是物理內存的1/4。
# DisableExplicitGC: 在程序代碼中不允許有顯示的調用”System.gc()”。
# UseParNewGC: 對年輕代采用多線程並行回收,這樣收得快。
# MaxTenuringThreshold: 設置垃圾最大年齡。如果設置為0的話,則年輕代對象不經過Survivor區,直接進入年老代,根據本地的jprofiler監控后得到的一個理想的值,不能一概而論原搬照抄。
# UseConcMarkSweepGC: 即CMS gc,這一特性只有jdk1.5即后續版本才具有的功能,它使用的是gc估算觸發和heap占用觸發。
# CMSParallelRemarkEnabled: 在使用 UseParNewGC 的情況下,盡量減少 mark 的時間。
# UseCMSCompactAtFullCollection: 在使用 concurrent gc 的情況下,防止 memoryfragmention,對 live object 進行整理,使 memory 碎片減少。
# LargePageSizeInBytes: 指定 Java heap 的分頁頁面大小,內存頁的大小不可設置過大, 會影響 Perm 的大小。
# UseFastAccessorMethods: 使用 get,set 方法轉成本地代碼,原始類型的快速優化。
# UseCMSInitiatingOccupancyOnly: 只有在 oldgeneration 在使用了初始化的比例后 concurrent collector 啟動收集。
# UseBiasedLocking: -Djava.awt.headless=true這個參數一般我們都是放在最后使用的, 解決window下可以顯示的圖片在linux不能顯示
export JAVA_OPTS="-server     
    -Xms1024M     
    -Xmx1024M     
    -Xss512k 
    -XX:+AggressiveOpts 
    -XX:+UseBiasedLocking 
    -XX:PermSize=128M 
    -XX:MaxPermSize=512M
    -XX:+DisableExplicitGC     
    -XX:+UseParNewGC
    -XX:MaxTenuringThreshold=15 
    -XX:+UseConcMarkSweepGC 
    -XX:+CMSParallelRemarkEnabled     
    -XX:+UseCMSCompactAtFullCollection 
    -XX:LargePageSizeInBytes=128m 
    -XX:+UseFastAccessorMethods 
    -XX:+UseCMSInitiatingOccupancyOnly 
    -Djava.awt.headless=true " 

 

 

參考:

  tomcat 運行機制和調優: https://blog.csdn.net/y_blueblack/article/details/81066141

  tomcat 工作原理詳解: https://blog.csdn.net/res_cue/article/details/21756357

  tomcat bio nio apr模式性能測試: https://blog.csdn.net/wanglei_storage/article/details/50225779

  tomcat 開始apr模式: https://blog.csdn.net/xyang81/article/details/51502766

   java虛擬機性能監控調優及原則: https://www.cnblogs.com/thingk/p/6840585.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM