前言java
關於 Tomcat 性能調優,一直以來就是運維面試的一個重要話題。今天咱們就簡單聊聊 Tomcat 如何進行性能優化? 首先聲明,我不會去說 Tomcat 是什麼,內部結構,原理什麼的。我不懂......我只是會說一些我在工做當中的一些參數以及本身所瞭解的方法,主要仍是和你們溝通、交流。程序員
1、關於選型面試
簡單說明,關於Openjdk 和 Oracle jdk的選擇,我我的比較傾向於使用Oracle jdk,雖然它很流氓可是我以爲東西仍是靠譜;其次是在版本上的選擇,建議選擇最新穩定版進行在生產環境使用,以此來得到更高效的性能;apache
1、JVM相關參數優化tomcat
export JAVA_OPTS=""-Dfile.encoding=UTF-8 -server -Xms1400M -Xmx1400M -Xss512k -XX:+AggressiveOpts -XX:+UseBiasedLocking -XX:PermSize=128M -XX:MaxPermSize=256M -XX:+DisableExplicitGC -XX:MaxTenuringThreshold=30 -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:+CMSParallelRemarkEnabled -XX:ReservedCodeCacheSize=32m -XX:+UseCMSCompactAtFullCollection -XX:LargePageSizeInBytes=128m -XX:+UseFastAccessorMethods -XX:+UseCMSInitiatingOccupancyOnly -Djava.awt.headless=true"
提示:在java 8中永久代已被移除,若是你是java8的環境,須要你去掉"-XX:PermSize=128M -XX:MaxPermSize=256M"參數,而且"-XX:MaxTenuringThreshold=31"參數值只能設置在0-15,不然會提示相關錯誤; 性能優化
配置說明:bash
Tomcat Connector(Tomcat鏈接器)有bio、nio、apr三種運行模式,簡單介紹(抄百度的,有本事來打我):服務器
特性:一個線程處理一個請求。缺點:併發量高時,線程數較多,浪費資源。網絡
12-Dec-2017 14:17:46.429 信息 [main] org.apache.coyote.AbstractProtocol.init Initializing ProtocolHandler ["http-nio-8080"]
12-Dec-2017 14:17:46.445 信息 [main] org.apache.tomcat.util.net.NioSelectorPool.getSharedSelector Using a shared selector for servlet write/read
12-Dec-2017 14:17:46.473 信息 [main] org.apache.coyote.AbstractProtocol.init Initializing ProtocolHandler ["ajp-nio-8009"]
12-Dec-2017 14:17:46.474 信息 [main] org.apache.tomcat.util.net.NioSelectorPool.getSharedSelector Using a shared selector for servlet write/read
12-Dec-2017 14:17:46.476 信息 [main] org.apache.catalina.startup.Catalina.load Initialization processed in 1031 ms
特性:利用Java的異步IO處理,能夠經過少許的線程處理大量的請求。多線程
3.2 tomcat server.xml配置優化
線程池參數配置:
<?xml version="1.0" encoding="UTF-8"?>
<Service name="Catalina">
<!--The connectors can use a shared executor, you can define one or more named thread pools-->
<!--
<Executor name="tomcatThreadPool" namePrefix="catalina-exec-"
maxThreads="150" minSpareThreads="4"/>
-->
<Executor name="tomcatThreadPool" namePrefix="catalina-exec-"
maxThreads="1000"
minSpareThreads="100"
maxIdleTime="60000"
prestartminSpareThreads = "true"
maxQueueSize = "100"
className="org.apache.catalina.core.StandardThreadExecutor" />
提示:網上不少混淆了,異步servlet和非阻塞connector,一個是Executor,一個是connector,二者的工做階段不一樣。
鏈接器配置:
<Connector executor="tomcatThreadPool" URIEncoding="utf-8" port="8080" protocol="org.apache.coyote.http11.Http11Nio2Protocol" enableLookups="false" maxConnections="2000" useURIValidationHack="false" keepAliveTimeout="60000" connectionTimeout="20000"
maxThreads="1000"
minSpareThreads="100"
maxSpareThreads="2000"
minProcessors="100"
maxProcessors="1000" tcpNoDelay="true" redirectPort="8443" />
提示:Tomcat 中能夠同時接收的鏈接數爲maxConnections+acceptCount 。上面這些參數須要手動開啓,默認值配置都較低,沒法發揮最佳性能。能夠去大家生產環境看看,是否是不少沒有作優化呢;
4、關於性能分析
4.1 常見工具
4.2 其餘
查看tomcat鏈接數:
netstat –nat | grep 8080
查看 tomcat 線程數:
# 查看進程ID ps -ef |grep java # 查看線程 ps -o nlwp 3598
提示:經過使用該方式能夠查看到該進程有多少線程,但並無排除處於idle狀態的線程。因此,要想獲取當前進程running的線程數,還須要執行以下命令。
ps -eLo pid,stat | grep 3598 | grep running | wc -l
其中ps -eLo pid,stat能夠找出全部線程,並打印其所在的進程號和線程當前的狀態;兩個grep命令分別篩選進程號和線程狀態;wc統計個數。SL表示空閒狀態。