Tomcat自身的調(diào)優(yōu)是針對conf/server.xml中的幾個參數(shù)的調(diào)優(yōu)設(shè)置。首先是對這幾個參數(shù)的含義要有深刻而清楚的理解。以tomcat8.5為例,講解參數(shù)。
同時也得認識到一點,tomcat調(diào)優(yōu)也受制于linux內(nèi)核。linux內(nèi)核對tcp連接也有幾個參數(shù)可以調(diào)優(yōu)。
因此我們可以將tomcat調(diào)優(yōu)分為linux內(nèi)核優(yōu)化、java虛擬機調(diào)優(yōu)和tomcat自身的優(yōu)化。
一、Tomcat自身優(yōu)化
1. maxThreads:tomcat創(chuàng)建的最大線程數(shù),也就是同時處理的請求最大并發(fā)數(shù)。默認值是200
官網(wǎng):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. Note that if an executor is configured any value set for this attribute will be recorded correctly but it will be reported (e.g. via JMX) as -1to make clear that it is not used.
maxThreads如何配置(轉(zhuǎn))
一般的服務(wù)器操作都包括量方面:1計算(主要消耗cpu),2等待(io、數(shù)據(jù)庫等)
第一種極端情況,如果我們的操作是純粹的計算,那么系統(tǒng)響應(yīng)時間的主要限制就是cpu的運算能力,此時maxThreads應(yīng)該盡量設(shè)的小,降低同一時間內(nèi)爭搶cpu的線程個數(shù),可以提高計算效率,提高系統(tǒng)的整體處理能力。
第二種極端情況,如果我們的操作純粹是IO或者數(shù)據(jù)庫,那么響應(yīng)時間的主要限制就變?yōu)榈却獠抠Y源,此時maxThreads應(yīng)該盡量設(shè)的大,這樣才能提高同時處理請求的個數(shù),從而提高系統(tǒng)整體的處理能力。此情況下因為tomcat同時處理的請求量會比較大,所以需要關(guān)注一下tomcat的虛擬機內(nèi)存設(shè)置和linux的open file限制。
我在測試時遇到一個問題,maxThreads我設(shè)置的比較大比如3000,當服務(wù)的線程數(shù)大到一定程度時,一般是2000出頭,單次請求的響應(yīng)時間就會急劇的增加,
百思不得其解這是為什么,四處尋求答案無果,最后我總結(jié)的原因可能是cpu在線程切換時消耗的時間隨著線程數(shù)量的增加越來越大,
cpu把大多數(shù)時間都用來在這2000多個線程直接切換上了,當然cpu就沒有時間來處理我們的程序了。
以前一直簡單的認為多線程=高效率。。其實多線程本身并不能提高cpu效率,線程過多反而會降低cpu效率。
當cpu核心數(shù)<線程數(shù)時,cpu就需要在多個線程直接來回切換,以保證每個線程都會獲得cpu時間,即通常我們說的并發(fā)執(zhí)行。
所以maxThreads的配置絕對不是越大越好。
現(xiàn)實應(yīng)用中,我們的操作都會包含以上兩種類型(計算、等待),所以maxThreads的配置并沒有一個最優(yōu)值,一定要根據(jù)具體情況來配置。
最好的做法是:在不斷測試的基礎(chǔ)上,不斷調(diào)整、優(yōu)化,才能得到最合理的配置。
2. acceptCount:當tomcat的線程數(shù)達到了最大時,接收排隊的最大請求個數(shù)。默認值為100
官網(wǎng):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.
maxThreads與acceptCount這兩個值是如何起作用的呢?
情況1:接受一個請求,此時tomcat起動的線程數(shù)沒有到達maxThreads,tomcat會起動一個線程來處理此請求。
情況2:接受一個請求,此時tomcat起動的線程數(shù)已經(jīng)到達maxThreads,tomcat會把此請求放入等待隊列,等待空閑線程。
情況3:接受一個請求,此時tomcat起動的線程數(shù)已經(jīng)到達maxThreads,等待隊列中的請求個數(shù)也達到了acceptCount,此時tomcat會直接拒絕此次請求,返回connection refused。
對于第3種情況,在看過一篇分析connection timeout問題產(chǎn)生的原因后,等待隊列的請求個數(shù)這個值可能是由acceptCount參數(shù)決定,也有可能由linux內(nèi)核參數(shù)net.core.somaxconn決定。
關(guān)聯(lián):我在網(wǎng)上看來一篇文章寫分析linux上TCP connection timeout的原因,這篇文章中提到一個內(nèi)核參數(shù) net.core.somaxconn。
我就想tomcat的acceptCount與net.core.somaxconn到底是什么關(guān)系呢。
我做了一個實驗,
1. 我將tomcat的acceptCount設(shè)置為3000 ,net.core.somaxconn設(shè)置為8192
那么我用ss -lt 指令查看在tomcat起的端口上的send_q值是3000 可見這是acceptCount的值。
2.我將tomcat的acceptCount設(shè)置為10000,net.core.somaxconn設(shè)置為8192
同樣用ss -lt指令查看在tomcat起的端口上的send_q值是8192,可見這是somaxconn的值。
所以,我總結(jié)的是,acceptCount設(shè)置的值要一般小于net.core.somaxconn這個參數(shù),這樣acceptCount的值才會起作用。net.core.somaxconn 這個參數(shù)默認值是128 ,所以需要改這個參數(shù)值。后面再介紹改這個值的方法。
acceptCount如何配置?(轉(zhuǎn))
我一般是設(shè)置的跟maxThreads一樣大,這個值應(yīng)該是主要根據(jù)應(yīng)用的訪問峰值與平均值來權(quán)衡配置的。
如果設(shè)的較小,可以保證接受的請求較快相應(yīng),但是超出的請求可能就直接被拒絕
如果設(shè)的較大,可能就會出現(xiàn)大量的請求超時的情況,因為我們系統(tǒng)的處理能力是一定的。
3. maxConnections
官網(wǎng):
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 belowmaxConnectionsat 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 theacceptCountsetting. The default value varies by connector type. For NIO and NIO2 the default is10000. For APR/native, the default is8192.
Note that for APR/native on Windows, the configured value will be reduced to the highest multiple of 1024 that is less than or equal to maxConnections. This is done for performance reasons.
If set to a value of -1, the maxConnections feature is disabled and connections are not counted.
Tomcat允許的同時存在的最大連接數(shù)
acceptCount、maxConnections是tcp層相關(guān)的參數(shù)。
4.connectionTimeOut:connectionTimeOut=10000是說建立一個socket連接后,如果一直沒有收到客戶端的FIN,也沒有數(shù)據(jù)過來,那么此連接也必須等到10s后,才能被超時釋放,我理解是tomcat就直接釋放這個連接。以毫秒為單位,server.xml默認設(shè)置是20秒。
官網(wǎng):The number of milliseconds this Connectorwill wait, after accepting a connection, for the request URI line to be presented. Use a value of -1 to indicate no (i.e. infinite) timeout. The default value is 60000 (i.e. 60 seconds) but note that the standard server.xml that ships with Tomcat sets this to 20000 (i.e. 20 seconds). UnlessdisableUploadTimeoutis set tofalse, this timeout will also be used when reading the request body (if any).
修改方法: vi server.xml 打開server.xml文件 將 修改為:將 修改為
下面的圖為TCP三次握手與accept交互
SYN隊列稱為半連接隊列,由內(nèi)核參數(shù) net.ipv4.tcp_max_syn_backlog 設(shè)置.
Accept隊列稱為完全連接隊列,三次握手已經(jīng)完成,但還未被應(yīng)用層接收(accept),但也處于ESTABLISHED狀態(tài)。隊列長度由listen的backlog參數(shù)和內(nèi)核的 net.core.somaxconn 參數(shù)共同決定。由listen()函數(shù)的第二個參數(shù) backlog 指定,內(nèi)核硬限制由 net.core.somaxconn 限制,即隊列長度實際的值由min(backlog,somaxconn) 來決定
客戶端使用connect向服務(wù)器發(fā)送TCP連接,三次握手就發(fā)生了。當1.1步驟 客戶端首先發(fā)送SYN到達服務(wù)端后,內(nèi)核會把連接信息放到SYN隊列中,同時回一個SYN+ACK包給客戶端。一段時間后,客戶端再次發(fā)來ACK包后,內(nèi)核會把連接從SYN隊列中取出,再把這個連接放到ACCEPT隊列中。應(yīng)用服務(wù)器調(diào)用accept時,其實就是直接從ACCEPT隊列中取出已經(jīng)建立成功的連接套接字。
還有一張圖是TCP握手建立連接的流程和隊列
Tomcat原理概要
Tomcat大致分為兩個部分,Connector組件及Container組件。Connector組件負責(zé)控制入口連接,并關(guān)聯(lián)著一個Executor。Container負責(zé)Servlet容器的實現(xiàn),Executor負責(zé)具體的業(yè)務(wù)邏輯,如Servlet的執(zhí)行。一個請求到達服務(wù)器后,經(jīng)過以下關(guān)鍵幾步,參見下圖:
OS與客戶端握手并建立連接,并將建立的連接放入完成隊列,不妨叫Acceptor Queque。這個隊列的長度就是Connector的acceptCount值。
Tomcat中的acceptor線程,不斷從Acceptor Queque中獲取連接。
Acceptor Queque隊列中沒有連接,Acceptor線程繼續(xù)監(jiān)視
Acceptor Queque隊列中有新連接,Acceptor線程將檢查當前的連接數(shù)是否超過了maxConnections
如果超過maxConnections,則阻塞。直到連接數(shù)小于maxConnections,acceptor線程將請求交由Executor負責(zé)執(zhí)行。
Executor將分配worker線程來處理請求數(shù)據(jù)的讀取,處理(servlet的執(zhí)行)以及響應(yīng)。
acceptCount
acceptCount 實際上是Bind Socket時候傳遞的backlog值,在linux平臺下含義是已經(jīng)建立連接還沒有被應(yīng)用獲取的連接隊列最大長度。此時,如果請求個數(shù)達到了acceptCount,新進的請求將拋出refuse connection.
二、Linux內(nèi)核參數(shù)優(yōu)化
1. linux系統(tǒng)對當前用戶的單一進程同時可打開的文件數(shù)量的限制
查看系統(tǒng)允許當前用戶進程打開的文件數(shù)量的限制:ulimit -u 默認值為1024 。即是Linux操作系統(tǒng)對一個進程打開的文件句柄數(shù)量的限制
對于想支持更高數(shù)量的TCP并發(fā)連接的通訊處理程序,就必須修改Linux對當前用戶的進程同時打開的文件數(shù)量的軟限制(soft limit)和硬限制(hardlimit)。其中軟限制是指Linux在當前系統(tǒng)能夠承受的范圍內(nèi)進一步限制用戶同時打開的文件數(shù);硬限制則是根據(jù)系統(tǒng)硬件資源狀況(主要是系統(tǒng)內(nèi)存)計算出來的系統(tǒng)最多可同時打開的文件數(shù)量。通常軟限制小于或等于硬限制。
修改方法:
sudo vi /etc/security/limits.conf
增加如下:
prouser soft nofile 65536
prouser hard nofile 65536
prouser soft nproc 65536
prouser hard nproc 65536
修改完后保存此文件。
nproc是操作系統(tǒng)級別對每個用戶創(chuàng)建的進程數(shù)的限制
2.Linux網(wǎng)絡(luò)內(nèi)核對TCP連接的有關(guān)限制
修改方法:
sudo vi /etc/sysctl.conf
增加如下:
net.ipv4.tcp_tw_reuse = 1 net.ipv4.tcp_tw_recycle = 1 net.ipv4.tcp_fin_timeout = 30 net.ipv4.ip_local_port_range = 10000 65000 net.ipv4.tcp_max_syn_backlog = 8192 net.ipv4.tcp_max_tw_buckets = 10000 net.core.somaxconn=8192 accept隊列的長度跟這個參數(shù)有關(guān) sudo /sbin/sysctl -p 實時生效
三、JVM調(diào)優(yōu)
JAVA_OPTS="$JAVA_OPTS -server -Xmn2000m -Xms4000m -Xmx4000m -XX:PermSize=128m -XX:+UseConcMarkSweepGC -XX:MaxPermSize=512m -Djuli-logback.configurationFile=file:$CATALINA_HOME/conf/logback.xml"
默認值:
修改為:
參數(shù)解釋:
maxThreads:最大并發(fā)數(shù),默認設(shè)置 200,一般建議在 500 ~ 800,根據(jù)硬件設(shè)施和業(yè)務(wù)來判斷
minSpareThreads:Tomcat 初始化時創(chuàng)建的線程數(shù),默認設(shè)置 25
maxIdleTime:如果當前線程大于初始化線程,那空閑線程存活的時間,單位毫秒,默認60000=60秒=1分鐘。
prestartminSpareThreads:在 Tomcat 初始化的時候就初始化 minSpareThreads 的參數(shù)值,如果不等于 true,minSpareThreads 的值就沒啥效果了
maxQueueSize:最大的等待隊列數(shù),超過則拒絕請求
審核編輯:黃飛
-
cpu
+關(guān)注
關(guān)注
68文章
10981瀏覽量
214686 -
TCP
+關(guān)注
關(guān)注
8文章
1393瀏覽量
79945 -
數(shù)據(jù)庫
+關(guān)注
關(guān)注
7文章
3874瀏覽量
65352 -
JVM
+關(guān)注
關(guān)注
0文章
159瀏覽量
12420 -
線程
+關(guān)注
關(guān)注
0文章
507瀏覽量
19964
原文標題:三、JVM調(diào)優(yōu)
文章出處:【微信號:magedu-Linux,微信公眾號:馬哥Linux運維】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關(guān)推薦
jvm的類加載器的整體結(jié)構(gòu)及過程解析

評論