Tomcat7并发和线程数
最近一直在解決線上一個問題,表現是:
? ?Tomcat每到凌晨會有一個高峰,峰值的并發(fā)達到了3000以上,最后的結果是Tomcat線程池滿了,日志看很多請求超過了1s。
服務器性能很好,Tomcat版本是7.0.54,配置如下:
<Executor name="tomcatThreadPool" namePrefix="catalina-exec-"maxThreads="3000" minSpareThreads="800"/><Connector executor="tomcatThreadPool" port="8084" protocol="org.apache.coyote.http11.Http11AprProtocol"connectionTimeout="60000"keepAliveTimeout="30000"maxKeepAliveRequests="8000"maxHttpHeaderSize="8192"URIEncoding="UTF-8"enableLookups="false"acceptCount="1000"disableUploadTimeout="true"redirectPort="8443" />事后thread dump看其實真正處于RUNNABLE狀態(tài)的線程很少,絕大部分線程都處于TIMED_WAITING狀態(tài):
于是大伙都開始糾結為什么線程會漲到3000,而且發(fā)現即使峰值過了線程數并不會降下來。我們首先想到的是:
? 后端應用的處理瞬間比較慢,“堵住了”導致前端線程數漲了起來。
但是優(yōu)化一個版本上線后發(fā)現雖然漲的情況有所好轉,但是最終線程池還是會達到3000這個最大值。
==================================分割線=========================================
以上是大背景,中間的過程省略,直接跟各位說下目前我得到的結論:
1、首先是為什么線程不釋放的問題?
簡單說下我驗證的Tomcat(7.0.54)線程池大概的工作機制
- Tomcat啟動時如果沒有請求過來,那么線程數(都是指線程池的)為0;
- 一旦有請求,Tomcat會初始化minSapreThreads設置的線程數;
- Tomcat不會主動對線程池進行收縮,除非確定沒有任何請求的時候,Tomcat才會將線程池收縮到minSpareThreads設置的大小;
- Tomcat6之前的版本有一個maxSpareThreads參數,但是在7中已經移除了,所以只要前面哪怕只有一個請求,Tomcat也不會釋放多于空閑的線程。
至于Tomcat為什么移除maxSpareThreads這個參數,我想也是出于性能的考慮,不停的收縮線程池性能肯定不高,而多余的線程處于等待狀態(tài)的好處是一有新請求過來立刻可以處理。
- 而且大量的Tomcat線程處于等待狀態(tài)不會消耗CPU,但是會消耗一些JVM存儲。
?
補充:上面標紅的一句有點問題,進一步驗證發(fā)現只有使用Keep-Alive(客戶端和服務端都支持)時才是這種表現,如果客戶端沒有使用Keep-Alive那么線程會隨著TCP連接的釋放而回收。
Tomcat中Keep-Alive相關的參數:
maxKeepAliveRequests:
The maximum number of HTTP requests which can be pipelined until the connection is closed by the server. Setting this attribute to 1 will disable HTTP/1.0 keep-alive, as well as HTTP/1.1 keep-alive and pipelining. Setting this to -1 will allow an unlimited amount of pipelined or keep-alive HTTP requests. If not specified, this attribute is set to 100.
keepAliveTimeout:
The number of milliseconds this?Connector?will wait for another HTTP request before closing the connection. The default value is to use the value that has been set for the?connectionTimeout?attribute. Use a value of -1 to indicate no (i.e. infinite) timeout.?
?
2、為什么線程池會滿?
這是我現在糾結的核心。到底是不是應用的性能慢導致的,我現在的結論是有關系,但關鍵是并發(fā)。
- Tomcat的線程池的線程數跟你的瞬間并發(fā)有關系,比如maxThreads設置為1000,當瞬間并發(fā)達到1000那么Tomcat就會起1000個線程來處理,這時候跟你應用的快慢關系不大。
那么是不是并發(fā)多少Tomcat就會起多少個線程呢?這里還跟Tomcat的這幾個參數設置有關系,看官方的解釋是最靠譜的:
maxThreads:
The maximum number of request processing threads to be created by this?Connector, which therefore determines the maximum number of simultaneous requests that can be handled. If not specified, this attribute is set to 200. If an executor is associated with this connector, this attribute is ignored as the connector will execute tasks using the executor rather than an internal thread pool.
maxConnections:
The maximum number of connections that the server will accept and process at any given time. When this number has been reached, the server will accept, but not process, one further connection. This additional connection be blocked until the number of connections being processed falls below?maxConnections?at which point the server will start accepting and processing new connections again. Note that once the limit has been reached, the operating system may still accept connections based on the?acceptCount?setting. The default value varies by connector type. For BIO the default is the value of?maxThreads?unless an?Executor?is used in which case the default will be the value of maxThreads from the executor. For NIO the default is?10000. For APR/native, the default is?8192.
……
acceptCount:
The maximum queue length for incoming connection requests when all possible request processing threads are in use. Any requests received when the queue is full will be refused. The default value is 100.
minSpareThreads:
The minimum number of threads always kept running. If not specified, the default of?10?is used.
我簡單理解就是:
maxThreads:Tomcat線程池最多能起的線程數;
maxConnections:Tomcat最多能并發(fā)處理的請求(連接);
acceptCount:Tomcat維護最大的對列數;
minSpareThreads:Tomcat初始化的線程池大小或者說Tomcat線程池最少會有這么多線程。
比較容易弄混的是maxThreads和maxConnections這兩個參數:
maxThreads是指Tomcat線程池做多能起的線程數,而maxConnections則是Tomcat一瞬間做多能夠處理的并發(fā)連接數。比如maxThreads=1000,maxConnections=800,假設某一瞬間的并發(fā)時1000,那么最終Tomcat的線程數將會是800,即同時處理800個請求,剩余200進入隊列“排隊”,如果acceptCount=100,那么有100個請求會被拒掉。
注意:根據前面所說,只是并發(fā)那一瞬間Tomcat會起800個線程處理請求,但是穩(wěn)定后,某一瞬間可能只有很少的線程處于RUNNABLE狀態(tài),大部分線程是TIMED_WAITING,如果你的應用處理時間夠快的話。所以真正決定Tomcat最大可能達到的線程數是maxConnections這個參數和并發(fā)數,當并發(fā)數超過這個參數則請求會排隊,這時響應的快慢就看你的程序性能了。
轉載于:https://www.cnblogs.com/moonandstar08/p/7091931.html
總結
以上是生活随笔為你收集整理的Tomcat7并发和线程数的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 语种识别及翻译?
- 下一篇: 360浏览器设置允许弹出窗口(360浏览