tomcat8.5配置高併發

 

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

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

才驚醒這個tomcat根本知識解壓就使用的,配置都沒動過,確定不能支持高併發了。因此這裏給出一個高併發的配置。百度一下也會發現不少相似的配置文章,經本人親測,特別是壓力測試下是沒問題的;apache

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

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

/>服務器

同時配置下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高併發。jvm

在這補充下tomcat的知識。socket


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

1、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" />

2、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的三、4分之一
(2) tomcat內存配置
  在bin下的catalina.bat文件中echo Using CATALINA_BASE: "%CATALINA_BASE%"的前一行加入以下代碼。
  set JAVA_OPTS=%JAVA_OPTS% -server -Xms8192m -Xmx8192m -Xmn1890m

3、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,說明系統的性能仍是很優越的,用戶數再增長也能在必定程度上保證系統穩定性。

4、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″ 狀況會明顯改善,但不保證大併發下服務器不會出現假死現象,畢竟代碼的規範性也佔很大比重。

相關文章
相關標籤/搜索