tomcat8.5配置高並發


 

最近部署的tomcat應用,有一天壓測的時候,測試一致反饋下載不了,結果查看日志才發現如下錯誤:

INFO: Maximum number of threads (200) created for connector with address null and port 8091

才驚醒這個tomcat根本知識解壓就使用的,配置都沒動過,肯定不能支持高並發了。所以這里給出一個高並發的配置。百度一下也會發現很多類似的配置文章,經本人親測,特別是壓力測試下是沒問題的;

開始修改tomcat的server.xml文件:

<Executor name="tomcatThreadPool" # 配置TOMCAT共享線程池,NAME為名稱 
  namePrefix="HTTP-8088-exec-"  # 線程的名字前綴,用於標記線程名稱
  prestartminSpareThreads="true" # executor啟動時,是否開啟最小的線程數
  maxThreads="5000"    # 允許的最大線程池里的線程數量,默認是200,大的並發應該設置的高一些,這里設置可以支持到5000並發
  maxQueueSize="100"  # 任務隊列上限
  minSpareThreads="50"# 最小的保持活躍的線程數量,默認是25.這個要根據負載情況自行調整了。太小了就影響反應速度,太大了白白占用資源
  maxIdleTime="10000"  # 超過最小活躍線程數量的線程,如果空閑時間超過這個設置后,會被關別。默認是1分鍾。

/>

同時配置下Connector:

<Connector port="8088" protocol="org.apache.coyote.http11.Http11NioProtocol"
  connectionTimeout="5000" redirectPort="443" proxyPort="443" executor="tomcatThreadPool"   # 采用上面的共享線程池
  URIEncoding="UTF-8"/>

這里本人的最大線程數是5000,當然先上壓測的時候並發4000是完全沒壓力的,當時服務器的資源20%都沒用到,所以這一個配置完全足夠實現5000高並發。

在這補充下tomcat的知識。


tomcat8.0的內存優化配置及垃圾回收管理

一、Tomcat並發優化

tomcat並發量與其配置息息相關,一般的機器幾百的並發量足矣,如果設置太高可能引發各種問題,內存、網絡等問題也能在高並發下暴露出來,因此,配置參數的設置非常重要。

(1) tomcat並發參數

 

  1. maxThreads:最大的並發請求數,當cpu利用率高的時候,不宜增加線程的個數,當cpu利用率不高,大部分是io阻塞類的操作時,可以適當增加該值。
    maxSpareThreads:Tomcat連接器的最大空閑 socket 線程數
    acceptCount:當處理任務的線程數達到最大時,接受排隊的請求個數
    connectionTimeout:網絡連接超時,單位毫秒
    enableLookups:若為false則不進行DNS查詢,提高業務能力應設置為false
    disableUploadTimeout:若為true則禁用上傳超時

    以上是一些比較常用的參數,Tomcat中server.xml配置詳解 會有更加詳細的介紹。

    (2) tomcat並發配置
    在conf下的server.xml文件中<Connector>節點進行配置
    <Connector port="8080" protocol="HTTP/1.1"
    connectionTimeout="30000"
    redirectPort="8443"
    maxThreads="400"
    minSpareThreads="50"
    maxSpareThreads="200"
    acceptCount="400"
    enableLookups="false"
    disableUploadTimeout="true" />

二、Tomcat內存配置
tomcat一般都有默認的內存大小,其默認值對整個物理內存來說非常小,如果不配置tomcat的內存,會大大浪費服務器的資源,驗證影響系統的性能,所以對tomcat的內存配置對用戶量比較大的系統尤為重要。

(1) tomcat內存參數
  -server:一定要作為第一個參數,在多個CPU時性能佳
  -Xms:java Heap初始大小。 默認是物理內存的1/64。
  -Xmx:java heap最大值。建議均設為物理內存的一半。不可超過物理內存。
  -XX:PermSize:設定內存的永久保存區初始大小。缺省值為64M。
  -XX:MaxPermSize:設定內存的永久保存區最大 大小。缺省值為64M。
  -Xmn:young generation(年輕代)的heap大小。一般設置為Xmx的3、4分之一
(2) tomcat內存配置
  在bin下的catalina.bat文件中echo Using CATALINA_BASE: "%CATALINA_BASE%"的前一行加入如下代碼。
  set JAVA_OPTS=%JAVA_OPTS% -server -Xms8192m -Xmx8192m -Xmn1890m

三、Tomcat垃圾回收
垃圾回收(gc)機制非常重要,有時系統會因為內存沒有及時回收導致內存溢出,或是內存飽和出現無法響應用戶請求的情況,這就要要求我們對空閑內存進行清理,以確保系統正常運行,tomcat GC的最佳配置是確保系統正常運行的關鍵。

(1) JVM中對象的划分及管理
JVM根據運行於其中的對象的生存時間大致的分為3種。並且將這3種不同的對象分別存放在JVM從系統分配到的不同的內存空間。這種對象存放空間的管理方式叫做Generation管理方式。

  Young Generation(年輕代):用於存放“早逝”對象(即瞬時對象)。例如:在創建對象時或者調用方法時使用的臨時對象或局部變量。
  Tenured Generation(年老代):用於存放“駐留”對象(即較長時間被引用的對象)。往往體現為一個大型程序中的全局對象或長時間被使用的對象。
  Perm Generation(永久保存區域):用於存放“永久”對象。這些對象管理着運行於JVM中的類和方法。

(2) jvm垃圾搜集參數
  -verbose:gc:顯示垃圾收集信息(在虛擬機發生內存回收時在輸出設備顯示信息)
  UseConcMarkSweepGC:開啟此參數使用ParNew & CMS(serial old為替補)搜集器
  MaxTenuringThreshold:晉升老年代的最大年齡。默認為15,比如設為10,則對象在10次普通GC后將會被放入年老代。
  -XX:+ExplicitGCInvokesConcurrent:System.gc()可以與應用程序並發執行。
  GCTimeRatio:設置系統的吞吐量。比如設為99,則GC時間比為1/1+99=1%,也就是要求吞吐量為99%。若無法滿足會縮小新生代大小。
  CMSInitiatingOccupancyFraction:觸發CMS收集器的內存比例。比如60%的意思就是說,當內存達到60%,就會開始進行CMS並發收集。
  CMSFullGCsBeforeCompaction:設置在幾次CMS垃圾收集后,觸發一次內存整理。
  -Xnoclassgc:禁用類垃圾回收,性能會高一點;
  -XX:SoftRefLRUPolicyMSPerMB=N:官方解釋是:Soft reference在虛擬機中比在客戶集中存活的更長一些。其清除頻率可以用命令行參數 -XX:SoftRefLRUPolicyMSPerMB=來控制,這可以指定每兆堆空閑空間的 soft reference 保持存活(一旦它不強可達了)的毫秒數,這意味着每兆堆中的空閑空間中的 soft reference 會(在最后一個強引用被回收之后)存活1秒鍾。注意,這是一個近似的值,因為 soft reference 只會在垃圾回收時才會被清除,而垃圾回收並不總在發生。系統默認為一秒。

  以上是一些基本的參數配置,通過JVM內存管理——垃圾搜集器參數精解查看更詳細的配置,通過Tomcat中Java垃圾收集調優查看原理

(3) tomcat垃圾搜集配置
  tomcat的垃圾搜集是和內存設置一起配置的,內存和gc的設置也不是越大越好,良好的比例可以使你的系統性能提升一般甚至更多,下面是tomcat7 ,服務器物理內存16g的標准配置

在bin下的catalina.bat文件中echo Using CATALINA_BASE: "%CATALINA_BASE%"的前一行加入如下代碼。
  set JAVA_OPTS=%JAVA_OPTS% 
  -server -Xms8192m -Xmx8192m -Xmn1890m -verbose:gc 
  -XX:+UseConcMarkSweepGC -XX:MaxTenuringThreshold=5 -XX:+ExplicitGCInvokesConcurrent -XX:GCTimeRatio=19 -XX:CMSInitiatingOccupancyFraction=70 -    XX:CMSFullGCsBeforeCompaction=0 -Xnoclassgc -XX:SoftRefLRUPolicyMSPerMB=0

 配置后系統的jvm內存運行狀況如下: 

可以看到系統在內存到達2g后就會回收空閑內存,基本不會發生溢出的情況,8g的最大內存最高才用了2g,說明系統的性能還是很優越的,用戶數再增加也能在一定程度上保證系統穩定性。

四、Tomcat宕機預防

tomcat在運行一段時間后,出現無法訪問的情況,檢查內存完全正常,查看服務器端口發現大量close_wait,導致網絡阻塞,以至於無法響應無法的請求,這就是tomcat最經常發生的宕機假死現象。

(1) TCP端口狀態

  1. LISTENING狀態 
    FTP服務啟動后首先處於偵聽(LISTENING)狀態。
  2. ESTABLISHED狀態 
    ESTABLISHED的意思是建立連接。表示兩台機器正在通信。
  3. CLOSE_WAIT 
    對方主動關閉連接或者網絡異常導致連接中斷,這時我方的狀態會變成CLOSE_WAIT 此時我方要調用close()來使得連接正確關閉。
  4. TIME_WAIT 
    我方主動調用close()斷開連接,收到對方確認后狀態變為TIME_WAIT。TCP協議規定TIME_WAIT狀態會一直持續2MSL(即兩倍的分段最大生存期),以此來確保舊的連接狀態不會對新連接產生影響。處於TIME_WAIT狀態的連接占用的資源不會被內核釋放,所以作為服務器,在可能的情況下,盡量不要主動斷開連接,以減少TIME_WAIT狀態造成的資源浪費。

      更詳細的TCP端口狀態請參考TCP端口狀態說明

(2) Windows系統下的TCP參數

  1. KeepAliveTime 
      KeepAliveTime的值控制系統嘗試驗證空閑連接是否仍然完好的頻率。如果該連接在一段時間內沒有活動,那么系統會發送保持連接的信號,如果網絡正常並且接收方是活動的,它就會響應。如果需要對丟失接收方的情況敏感,也就是說需要更快地發現是否丟失了接收方,請考慮減小該值。而如果長期不活動的空閑連接的出現次數較多,但丟失接收方的情況出現較少,那么可能需要增大該值以減少開銷。 
      缺省情況下,如果空閑連接在7200000毫秒(2小時)內沒有活動,系統就會發送保持連接的消息。
  2. KeepAliveInterval 
      KeepAliveInterval的值表示未收到另一方對“保持連接”信號的響應時,系統重復發送“保持連接”信號的頻率。在無任何響應的情況下,連續發送“保持連接”信號的次數超過TcpMaxDataRetransmissions(下文將介紹)的值時,將放棄該連接。如果網絡環境較差,允許較長的響應時間,則考慮增大該值以減少開銷;如果需要盡快驗證是否已丟失接收方,則考慮減小該值或TcpMaxDataRetransmissions值。 
      缺省情況下,在未收到響應而重新發送“保持連接”的信號之前,系統會等待1000毫秒(1秒)。
  3. KeepAliveInterval 
      KeepAliveInterval的值表示未收到另一方對“保持連接”信號的響應時,系統重復發送“保持連接”信號的頻率。在無任何響應的情況下,連續發送“保持連接”信號的次數超過TcpMaxDataRetransmissions(下文將介紹)的值時,將放棄該連接。如果網絡環境較差,允許較長的響應時間,則考慮增大該值以減少開銷;如果需要盡快驗證是否已丟失接收方,則考慮減小該值或TcpMaxDataRetransmissions值。 
      缺省情況下,在未收到響應而重新發送“保持連接”的信號之前,系統會等待1000毫秒(1秒)。

      更多系統參數請參考Windows系統下的TCP參數

(3) tomcat假死分析及預防

close_wait發生的原因是TCP連接沒有調用關閉方法,需要應用來處理網絡鏈接關閉,對於Web請求出現這個原因,經常是因為Response的BodyStream沒有調用Close,除了調整代碼外,可以調整windows系統參數解決tomcat假死問題

 

tomcat假死時利用netstat -ano查看端口現象如下: 
這里寫圖片描述 
KeepLive在Windows操作系統下默認是7200000毫秒,也就是2個小時才清理一次,對與大量close_wait情況下,可以減小其時間 
在注冊表的[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters]改動或創建以下項 
“KeepAliveTime”=dword:afc8 (45000毫秒) 
“KeepAliveInterval”=dword:1 
“TcpMaxDataRetransmissions”=dword:”5″ 
情況會明顯改善,但不保證大並發下服務器不會出現假死現象,畢竟代碼的規范性也占很大比重。


免責聲明!

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



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