生產環境Tomcat的優化

    生產環境Tomcat的優化

    估計不少公司的生產環境都使用Tomcat使用爲Web容器,估計也有不少同窗已經對生產環境的Tomcat的進行各類各樣優化,努力找出Tomcat的性能瓶頸,在生產環境提供一個穩定的、高效的Tomcat。讓在咱們在生產環境進行優化以前,先對Tomcat進行壓力測試,找出Tomcat性能瓶頸,而後修改優化配置,再觀察Tomcat是否知足咱們的性能要求。html

測試環境

測試系統圖示:算法

測試系統環境說明:數據庫

  1. 部署Tomcat的服務器程序是一個WAR包,WAR只有一個index.jsp頁面,jsp頁面的body只有一行」 <p>hello world!</p>」,除此之外War中再沒有任何額外的Jar類和Lib包。
  2. Agent客戶端向服務器發送Http請求。
  3. Agent會把請求結果反饋至nGrinder管理機,包括TPS峯值、MTT、TPS圖表等一系列數據。
  4. Tomcat服務器已接入Pinpoint,Pinpoint能夠查詢Tomcat服務器的heap、jvm cpu的使用狀況。
  5. Tomcat的Webapps除測試包test.war外,仍是host-manager、manager、ROOT均有Tomcat自帶,方便偶爾觀察Tomcat的線程池狀況。
  6. Pinpoint、Tomcat監控嚴格意義來講會影響測試結果,但本次咱們測試中忽略不計。

測試結果

heap.size=2G&G1

    大約在Agent啓動17分鐘後,Tomcat的JVM開始出現Full GC(紅色框是本次GC圖),而且出現長時間STW事件。從第一個Full GC開始後,並且Full GC越來密集,大部分的停頓時間都在10000ms以上,對一個Web服務器來講停頓10秒鐘是不可接受的。apache

    從吞吐量的角度來看,系統啓動17分鐘之後吞吐量也下來了,致使Agent以出錯的方式結束。緩存

heap.size=4G&G1

    從GC圖來看,能夠看到存在比較頻繁的Full GC,並且Full GC的持續時間較長爲10741ms,即系統有10.7S停頓,系統的響應延遲現象是很明顯的。tomcat

    從測試結果來看,能夠看到TPS的圖在前面20多分鐘屬於相對穩定,可是以後就頻繁出現爲TPS爲0或接近0的狀況,結合上圖能夠知道此時系統正在進行Full GC。從整個測試結果的數值上看,TPS的平均值爲4,065.2,TPS峯值爲5,251.5,測試的後期TPS波動較大。服務器

heap.size=4G&G1(6客戶端)

    從GC圖上看本次的測試沒有發生Full GC事件,系統延遲也比較小,可是不能簡單認爲此次的測試的GC活動對系統沒有影響。網絡

    從測試結果圖來看,TPS的趨勢整體平衡,波動較小,沒有出現特別低的點,整體屬於優秀。其中,TPS的平均值爲2,771.7,峯值爲3,284,數據屬於比較理想的狀況。session

heap.size=6G&G1

    從GC圖上看本次的測試沒有發生Full GC事件,能夠簡單認爲由於GC事件對系統延遲比較小,可是不能簡單認爲此次的測試的GC活動對系統沒有影響。併發

    從測試結果圖來看,TPS的趨勢整體平衡,但也存在波動的狀況,特別是有二次比較低的點,分別是300TPS和700TPS,整體屬於良好。其中,TPS的平均值爲4,095.7,峯值爲5,412.5,數據屬於比較理想的狀況。

heap.size=6G&ParallelOld

    從GC圖能夠看到堆的大小几乎是沿着45度的角度增加,而且在系統測試的34分鐘後,出現第一次Full GC,並且此次的Full GC是持續時間爲86569ms,即86.6S。也便是由於Full GC,系統中止響應長達86.6S,直接致使Agent認爲服務器沒有響應從而中止發送請求,從而結束了測試。

    從Agent的統計圖表來看,大約在開啓壓力測試22分鐘後,TPS的波動很是大,TPS有時甚至爲零。另外此處的TPS的平均值爲3,836.1,TPS峯值爲4,554.5,能夠對比下」 heap.size=6G&G1」的對應數值(TPS 4,095.7和TPS峯值爲5,412.5)均有降低。能夠看出來,ParallelOld算法在停頓方面的缺點仍是很明顯的,特別是大HeapSize的狀況下。

heap.size=4G&ParallelOld(6客戶端)

    GC圖上面來看,已經出現密集的Full GC,時間比較長的爲26971ms,即27秒。

    測試結果來看,29以後的TPS很不穩定,存在比較密集的觸零點,屬於比較差的測試結果。

heap.size=4G&CMS

    從上面的GC圖能夠看到Full GC的事件很頻繁,其中有一個持續46651ms,並且底部的短期Full GC很頻繁,停頓時間較長。

    從測試結果來看,大概在開始測試的29分鐘時後TPS波動很大,甚至有的接近底部。從TPS的走勢圖來看,表現爲是不穩定。測試過程當中平均TPS爲4060.2,峯值爲4855。

heap.size=4G&CMS(6客戶端)

    從GC圖上看本次的測試發生6次Full GC事件,其中一次最長時間的一次Full GC事件爲174ms,即0.1s,系統沒有由於Full GC 而產生時間的停頓和延遲。

    從測試結果圖來看,TPS的趨勢整體平衡,波動較小,沒有出現特別低的點,整體屬於優秀。其中,TPS的平均值爲2,841.7,峯值爲3,658.5,數據屬於比較理想的狀況。

heap.size=6G&CMS

    從上面的GC圖能夠看到發生好幾回的Full GC事件,但每次的Full持續的時間不長,其中一次是67ms,這是咱們能夠接受的停頓時間,時間間隔比較是大概7分鐘發生一次Full GC,但時間均小於100ms。

    從上面的測試結果圖表來看,TPS的量一直比較穩定,沒有浮動很大的狀況。TPS的平均值爲4,238.8,峯值爲5,346,其中峯值屬於以上測試狀況較好的,比」 heap.size=6G&G1」的峯值5,412.5略小一點,但TPS」 heap.size=6G&G1」的平均值4,095.7比更大。

測試結果分析與總結:

  1. Tomcat8默認使用NIO做爲鏈接處理器,NIO相對的阻塞式BIO模式來講,NIO處理鏈接更高效、更節省線程,但NIO還不是Tomcat的鏈接器的最佳選擇,APR纔是。由於APR是從操做系統級別解決IO問題,Tomcat經過JNI的方式調用系統資源,提升服務器的併發處理性能,可是APR須要額外安裝和配置。具體能夠參考:https://tomcat.apache.org/tomcat-8.5-doc/apr.html
  2. 關閉Tomcat的」 AccessLog」的輸出(即註釋:conf/server.xml的Valve className="org.apache.catalina.valves.AccessLogValve」節點),由於AccessLog平時使用很少,關閉後能夠減小Tomcat的IO操做。這個操做須要自身業務系統的狀況判斷,確實不須要才關掉此日誌輸出。
  3. Tomcat sessionid生成器致使的延遲,這個問題不是每次測試都會出現,可是一旦出現會致使Tomcat出現相似假死的現象。具體表現爲」org.apache.catalina.util.SessionIdGeneratorBase.createSecureRandom Creation of SecureRandom instance for session ID generation using [SHA1PRNG] took [3,533] milliseconds」。能夠參考:https://stackoverflow.com/questions/28201794/slow-startup-on-Tomcat-7-0-57-because-of-securerandom
  4. 「too many open files」現象,當Tomcat併發的鏈接數太多時,即Tomcat進程的句柄數超出系統限制,就會出現」 too many open files」,這個時候須要修改操做系統的默認參數。具體能夠參考:https://stackoverflow.com/questions/36863451/apache-tomcat-exception-too-many-open-files?rq=1
  5. Tomcat 線程池配置,在conf/server.xml文件中,」 Connector」配置節點能夠修改Tomcat的線程池大小和鏈接等參數。
  • 網上不少帖子說一個Tomcat進程最多隻能配置1000線程,可是我在實際的測試過程配置了1005線程,而且經過Tomcat自帶的監控觀察到Tomcatpool大小爲1005,系統能夠正常運行,因此只能配置1000線程的說法是錯誤。
  • 基於個人環境測試,Tomcat的thread pool的大小爲300時屬於比較合理。由於這個時候的MTT(系統平均響應時間)屬於較小,而且TPS值較高而且持續較長時間運行,TPS平均值也沒有出現較大波動。
  • 基於個人環境測試,Tomcat的thread pool的大於400時,在測試的初期時,TPS的平均水平和峯值均可以獲取比較高水平。但MTT時間增長了,即系統的響應時間增長了,thread pool並非單純的增大絕對數值就能夠增長系統併發處理能力,而且在系統後期TPS回落較大,系統的可能出現假死、內存溢出等事件。因此Tomcat的線程池大小務必要根據硬件和內存等配置來設置。
  1. Tomcat的配置JVM。
  • Heap大小及回收算法的優化配置,這個優化項是很是重要的。Tomcat8的JVM默認參數爲:」 CommandLine flags: -XX:InitialHeapSize=128950016 -XX:MaxHeapSize=2063200256 -XX:+UseCompressedClassPointers -XX:+UseCompressedOops  -XX:+UseParallelGC」。垃圾收集的算法爲:ParallelGC,MaxHeapSize(堆的容量)約1.92G,能夠看到JVM是很保守的參數啓動的。這一點能夠理解,由於JVM爲了兼容絕大部分的硬件和環境而致使的,因此在硬件或要求高的狀況下,優化是必須的。
  • 由於操做系統有8G內存,除掉操做系統和一些必要的程序,Java進程可使用的內存超過6G。爲了提升Tomcat的吞吐量和減小延遲,在ParallelOld、CMS、G1三種算法選擇一種。」 Xms6144m Xmx6144m G1」組合通過8小時沒有發生Full GC,並且在TPS線也很穩定,MTT也表現優秀。另一個組合」 Xms6144m Xmx6144m CMS」表現優秀,即CMS垃圾回收算法。自從有了G1,不少人都以爲只有G1都是纔是最好的,其實,CMS也是一種優秀收集算法,特別是4G、6G級別的堆內存,差異其實不大,甚至在MTT方面表現更優秀。或者說有JDK1.8以前CMS更優秀,由於以前的G1並非很成熟,即便是JDK1.8,G1在等預測模型方面有待改進。在測試過程當中的同等條件下,CMS的TPS平均值、TPS峯值、MTT值均比G1的有更好的表現,因此說CMS表現很是優秀的。
  • ParallelOld在堆較大時,缺點是很明顯的,就是當年老代進行回收,停頓時間太長,由於ParallelOld進行一次年老代標記、清理時耗時太長了,會致使長時間STW事件,系統出現停頓、響應超時。

優化總結

    Tomcat的最大併發數,這個估計是很想人知道數值。能夠簡單的認爲,Tomcat在同一時刻能處理請求數(假設請求同時到達),那麼Tomcat的併發數是Tomcat線程池的大小。我的認爲:TPS的平均值、峯值對咱們的生產環境更有意義,TPS峯值= ThreadPool/MTT。更重要的是,Tomcat很容易達到比較高的TPS峯值,可是要想在峯值保持長時間穩定運行是很是困難的,由於峯值TPS時,堆中分配內存的速度會遠遠大於堆內存回收的速度,系統運行一段時間後,系統就會出現Full GC,系統的Full GC就會愈來愈頻繁,停頓時間會愈來愈時,MTT也會愈來愈長,請求可能出現超時、報錯,從而TPS的出現直線下跌現象,若是請求的數仍然保持較高的數值,系統就會現出崩潰OutOfMemoryError現象,以下圖。

    因此短期內Tomcat的TPS峯值是能夠達到比較高數值,具體能夠根據: ThreadPool /MTT計算,但須要長時間穩定運行,必需要考慮HeapSize、CPU處理能力、MTT、網絡、IO等綜合因素考慮,而後進行壓力測試,找出性能的拐點。

    雖然能夠經過配置進行Tomcat優化後,相對原始的Tomcat優化後有着較高提高的空間,特別是HeapSize、GC收集算法、 ThreadPool的優化配置。可是咱們系統的性能瓶頸每每不是由Tomcat致使,更多的是咱們的系統在處理業務邏輯過程存在的問題致使的,如:頻繁的數據庫操做、不合理的使用索引、沒有高命中率的緩存、過多的IO操做等操做,這些操做對系統的性能影響更大,優化後能夠得到更大的更高性能提高。因此咱們的優化順序應該是:先優化業務邏輯實現,而後再考慮優化Tomcat,而後再優化業務邏輯實現。由於業務邏輯實現的優化空間更大,更值得咱們花費時間優化。

相關文章
相關標籤/搜索