最近部署的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的內存優化配置及垃圾回收管理
tomcat併發量與其配置息息相關,通常的機器幾百的併發量足矣,若是設置過高可能引起各類問題,內存、網絡等問題也能在高併發下暴露出來,所以,配置參數的設置很是重要。
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,說明系統的性能仍是很優越的,用戶數再增長也能在必定程度上保證系統穩定性。
tomcat在運行一段時間後,出現沒法訪問的狀況,檢查內存徹底正常,查看服務器端口發現大量close_wait,致使網絡阻塞,以致於沒法響應沒法的請求,這就是tomcat最常常發生的宕機假死現象。
TIME_WAIT
我方主動調用close()斷開鏈接,收到對方確認後狀態變爲TIME_WAIT。TCP協議規定TIME_WAIT狀態會一直持續2MSL(即兩倍的分段最大生存期),以此來確保舊的鏈接狀態不會對新鏈接產生影響。處於TIME_WAIT狀態的鏈接佔用的資源不會被內核釋放,因此做爲服務器,在可能的狀況下,儘可能不要主動斷開鏈接,以減小TIME_WAIT狀態形成的資源浪費。
更詳細的TCP端口狀態請參考TCP端口狀態說明
KeepAliveInterval
KeepAliveInterval的值表示未收到另外一方對「保持鏈接」信號的響應時,系統重複發送「保持鏈接」信號的頻率。在無任何響應的狀況下,連續發送「保持鏈接」信號的次數超過TcpMaxDataRetransmissions(下文將介紹)的值時,將放棄該鏈接。若是網絡環境較差,容許較長的響應時間,則考慮增大該值以減小開銷;若是須要儘快驗證是否已丟失接收方,則考慮減少該值或TcpMaxDataRetransmissions值。
缺省狀況下,在未收到響應而從新發送「保持鏈接」的信號以前,系統會等待1000毫秒(1秒)。
更多系統參數請參考Windows系統下的TCP參數
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″ 狀況會明顯改善,但不保證大併發下服務器不會出現假死現象,畢竟代碼的規範性也佔很大比重。