Tomcat入门
1.Tomcat基礎(chǔ)入門
1.1 tomcat是什么
Tomcat 是由 Apache 開(kāi)發(fā)的一個(gè) Servlet 容器,實(shí)現(xiàn)了對(duì) Servlet 和 JSP 的支持,并提供了作為Web服務(wù)器的一些特有功能,如Tomcat管理和控制平臺(tái)、安全域管理和Tomcat閥等。
由于 Tomcat 本身也內(nèi)含了一個(gè) HTTP 服務(wù)器,它也可以被視作一個(gè)單獨(dú)的 Web 服務(wù)器
1.2 基礎(chǔ)目錄
-
/bin - Tomcat 腳本存放目錄(如啟動(dòng)、關(guān)閉腳本)。 *.sh 文件用于 Unix 系統(tǒng); *.bat 文件用于 Windows 系統(tǒng)。
-
/conf - Tomcat 配置文件目錄。
-
/logs - Tomcat 默認(rèn)日志目錄。
-
/webapps - webapp 運(yùn)行的目錄。在手動(dòng)拷貝war包到此目錄下啟動(dòng)時(shí),war包的名稱就是啟動(dòng)項(xiàng)目的上下文
|-- webapp # 站點(diǎn)根目錄 META-INF 目錄用于存放工程自身相關(guān)的一些信息,元文件信息,通常由開(kāi)發(fā)工具,環(huán)境自動(dòng)生成。|-- META-INF # META-INF 目錄| `-- MANIFEST.MF # 配置清單文件|-- WEB-INF # WEB-INF 目錄| |-- classes # class文件目錄| | |-- *.class # 程序需要的 class 文件| | `-- *.xml # 程序需要的 xml 文件| |-- lib # 庫(kù)文件夾| | `-- *.jar # 程序需要的 jar 包
1.3 安裝
-
window安裝:tomcat8.5要求JDK1.7以上,進(jìn)入tomcat官方網(wǎng)站下載,解壓到本地即可使用。
-
linux安裝
# 下載解壓到本地wget http://mirrors.hust.edu.cn/apache/tomcat/tomcat-8/v8.5.24/bin/apache-tomcat-8.5.24.tar.gztar -zxf apache-tomcat-8.5.24.tar.gz# 啟動(dòng) Tomcat./apache-tomcat-8.5.24/bin/startup.sh
啟動(dòng)后,訪問(wèn) http://localhost:8080 ,可以看到 Tomcat 安裝成功的測(cè)試頁(yè)面
1.4 配置文件解析
./conf/servre.xml是tomcat的主要配置文件,下面對(duì)里面的一些主要配置進(jìn)行解釋:
-
server
server 元素表示整個(gè) Catalina servlet 容器。因此,它必須是 conf/server.xml 配置文件中的根元素。它的屬性代表了整個(gè) servlet 容器的特性。| 屬性 | 描述 | 備注 |
| :------| ------: | :------: |
| className | 這個(gè)類必須實(shí)現(xiàn)org.apache.catalina.Service接口 | 默認(rèn) org.apache.catalina.core.StandardService |
| address | 服務(wù)器等待關(guān)機(jī)命令的TCP / IP地址。如果沒(méi)有指定地址,則使用localhost。 | |
| port | 服務(wù)器等待關(guān)機(jī)命令的TCP / IP端口號(hào)。設(shè)置為-1以禁用關(guān)閉端口。|
| shutdown | 必須通過(guò)TCP / IP連接接收到指定端口號(hào)的命令字符串,以關(guān)閉Tomcat| -
service
Service元素表示一個(gè)或多個(gè)連接器組件的組合,這些組件共享一個(gè)用于處理傳入請(qǐng)求的引擎組件。Server 中可以有多個(gè) Service。
其中name表示此服務(wù)的顯示名稱,如果您使用標(biāo)準(zhǔn) Catalina 組件,將包含在日志消息中。與特定服務(wù)器關(guān)聯(lián)的每個(gè)服務(wù)的名稱必須是唯一的。
- Executor
表示在Tomcat中組件之間共享的線程池。
| className | 這個(gè)類必須實(shí)現(xiàn)org.apache.catalina.Executor接口 | 默認(rèn) org.apache.catalina.core.StandardService |
| name | 線程池名稱 | 要求唯一, 供Connector元素的executor屬性使用 |
| namePrefix | 線程名稱前綴 | |
| maxThreads | 最大活躍線程數(shù) | 默認(rèn)200 |
| minSpareThreads | 最小活躍線程數(shù) | 默認(rèn)25 |
| maxIdleTime | 當(dāng)前活躍線程大于minSpareThreads時(shí),空閑線程關(guān)閉的等待最大時(shí)間 | 默認(rèn)60000ms |
| maxQueueSize | 線程池滿情況下的請(qǐng)求排隊(duì)大小 | 默認(rèn)Integer.MAX_VALUE |
- connector
Connector代表連接組件。Tomcat 支持三種協(xié)議:HTTP/1.1、HTTP/2.0、AJP。
| asyncTimeout | Servlet3.0規(guī)范中的異步請(qǐng)求超時(shí) | 默認(rèn)30s |
| port | 請(qǐng)求連接的TCP Port | 設(shè)置為0,則會(huì)隨機(jī)選取一個(gè)未占用的端口號(hào) |
| protocol | 協(xié)議. 一般情況下設(shè)置為 HTTP/1.1,這種情況下連接模型會(huì)在NIO和APR/native中自動(dòng)根據(jù)配置選擇 | |
| URIEncoding | 對(duì)URI的編碼方式 | 如果設(shè)置系統(tǒng)變量org.apache.catalina.STRICT_SERVLET_COMPLIANCE為true,使用 ISO-8859-1編碼;如果未設(shè)置此系統(tǒng)變量且未設(shè)置此屬性, 使用UTF-8編碼 |
| useBodyEncodingForURI | 是否采用指定的contentType而不是URIEncoding來(lái)編碼URI中的請(qǐng)求參數(shù) |
以下屬性在標(biāo)準(zhǔn)的Connector(NIO, NIO2 和 APR/native)中有效:
| acceptCount | 當(dāng)最大請(qǐng)求連接maxConnections滿時(shí)的最大排隊(duì)大小 | 默認(rèn)100,注意此屬性和Executor中屬性maxQueueSize的區(qū)別.這個(gè)指的是請(qǐng)求連接滿時(shí)的堆棧大小,Executor的maxQueueSize指的是處理線程滿時(shí)的堆棧大小 |
| connectionTimeout | 請(qǐng)求連接超時(shí) | 默認(rèn)60000ms |
| executor | 指定配置的線程池名稱 | |
| keepAliveTimeout | keeAlive超時(shí)時(shí)間 | 默認(rèn)值為connectionTimeout配置值.-1表示不超時(shí) |
| maxConnections | 最大連接數(shù) | 連接滿時(shí)后續(xù)連接放入最大為acceptCount的隊(duì)列中. 對(duì) NIO和NIO2連接,默認(rèn)值為10000;對(duì) APR/native,默認(rèn)值為8192 |
| maxThreads | 如果指定了Executor, 此屬性忽略;否則為Connector創(chuàng)建的內(nèi)部線程池最大值 | 默認(rèn)200 |
| minSpareThreads | 如果指定了Executor, 此屬性忽略;否則為Connector創(chuàng)建線程池的最小活躍線程數(shù) | 默認(rèn)10 |
| processorCache | 協(xié)議處理器緩存Processor對(duì)象的大小 | -1表示不限制.當(dāng)不使用servlet3.0的異步處理情況下: 如果配置Executor,配置為Executor的maxThreads;否則配置為Connnector的maxThreads. 如果使用Serlvet3.0異步處理, 取maxThreads和maxConnections的最大值 |
1.5 開(kāi)啟遠(yuǎn)程調(diào)試模式
我們常常會(huì)遇到,本地項(xiàng)目運(yùn)行一切正常,在測(cè)試服務(wù)器上出問(wèn)題,可是日志信息并不能方便的查看出原因。我們可以通過(guò)遠(yuǎn)程調(diào)試模式來(lái)查看項(xiàng)目運(yùn)行信息。現(xiàn)在介紹在tomcat8.5下的開(kāi)啟遠(yuǎn)程調(diào)試方式:
- 1.5.1 tomcat開(kāi)啟遠(yuǎn)程調(diào)試模式
開(kāi)啟遠(yuǎn)程調(diào)試模式需要JDPA方式啟動(dòng)tomcat,tomcat8.5已經(jīng)添加JDPA的配置
如圖,默認(rèn)端口為8000,且只能在本機(jī)進(jìn)行調(diào)試,我們可以去掉localhost和修改需要的端口號(hào)。
然后在bin目錄下修改startup.bat文件,在最后一行添加jdpa
然后雙擊startup.bat啟動(dòng)tomcat即可。
- 1.5.2 客戶端遠(yuǎn)程連接
我們打開(kāi)IDE開(kāi)發(fā)工具,選擇remote連接
,然后填寫連接信息即可。
端口號(hào)即為上面配置的JPDA_ADDRESS,然后debug啟動(dòng),控制臺(tái)打印以下信息,說(shuō)明連接成功。
接下來(lái)就可以愉快的打斷點(diǎn)進(jìn)行調(diào)試了。
問(wèn)題:其中tomcat7需要手動(dòng)添加JPDA_OPTS設(shè)置,非tomcat8.5版本開(kāi)啟遠(yuǎn)程調(diào)試模式會(huì)與本文有所不同。
還有在idea中通過(guò)配置tomcat啟動(dòng)項(xiàng)目時(shí),無(wú)法正確的連接,暫時(shí)還沒(méi)找到原因,只能通過(guò)bin目錄手動(dòng)雙擊startup.bat啟動(dòng)tomcat。
1.6 將tomcat注冊(cè)成window服務(wù)
1.7 tomcat調(diào)優(yōu)
通常tomcat的默認(rèn)配置在生產(chǎn)環(huán)境下不能滿足要求,我們需要修改配置提高性能和穩(wěn)定性,可以通過(guò)以下幾種方式:
1.7.1 修改JVM參數(shù)
Tomcat 啟動(dòng)命令行中的優(yōu)化參數(shù),就是 JVM 的優(yōu)化 。Tomcat 首先跑在 JVM 之上的,因?yàn)樗膯?dòng)其實(shí)也只是一個(gè) java 命令行,首先我們需要對(duì)這個(gè) JAVA 的啟動(dòng)命令行進(jìn)行調(diào)優(yōu)。不管是 YGC 還是 Full GC,GC 過(guò)程中都會(huì)對(duì)導(dǎo)致程序運(yùn)行中中斷,正確的選擇不同的 GC 策略,調(diào)整 JVM、GC 的參數(shù),可以極大的減少由于 GC 工作,而導(dǎo)致的程序運(yùn)行中斷方面的問(wèn)題,進(jìn)而適當(dāng)?shù)奶岣?Java 程序的工作效率。
Tomcat 的啟動(dòng)參數(shù)位于安裝目錄 ${JAVA_HOME}/bin目錄下,Linux 操作系統(tǒng)就是 catalina.sh 文件。JAVA_OPTS,就是用來(lái)設(shè)置 JVM 相關(guān)運(yùn)行參數(shù)的變量,還可以在 CATALINA_OPTS 變量中設(shè)置。關(guān)于這 2 個(gè)變量,還是多少有些區(qū)別的:
JAVA_OPTS:用于當(dāng) Java 運(yùn)行時(shí)選項(xiàng)“start”、“stop”或“run”命令執(zhí)行。
CATALINA_OPTS:用于當(dāng) Java 運(yùn)行時(shí)選項(xiàng)“start”或“run”命令執(zhí)行。
為什么有兩個(gè)不同的變量?它們之間都有什么區(qū)別呢?
首先,在啟動(dòng) Tomcat 時(shí),任何指定變量的傳遞方式都是相同的,可以傳遞到執(zhí)行“start”或“run”命令中,但只有設(shè)定在 JAVA_OPTS 變量里的參數(shù)被傳遞到“stop”命令中。對(duì)于 Tomcat 運(yùn)行過(guò)程,可能沒(méi)什么區(qū)別,影響的是結(jié)束程序,而不是啟動(dòng)程序。
第二個(gè)區(qū)別是更微妙,其他應(yīng)用程序也可以使用 JAVA_OPTS 變量,但只有在 Tomcat 中使用 CATALINA_OPTS 變量。如果你設(shè)置環(huán)境變量為只使用 Tomcat,最好你會(huì)建議使用 CATALINA_OPTS 變量,而如果你設(shè)置環(huán)境變量使用其它的 Java 應(yīng)用程序,例如 JBoss,你應(yīng)該把你的設(shè)置放在JAVA_OPTS 變量中。
32 位系統(tǒng)下 JVM 對(duì)內(nèi)存的限制:不能突破 2GB ,那么這時(shí)你的 Tomcat 要優(yōu)化,就要講究點(diǎn)技巧了,而在 64 位操作系統(tǒng)上無(wú)論是系統(tǒng)內(nèi)存還是 JVM 都沒(méi)有受到 2GB 這樣的限制。
針對(duì)于 JMX 遠(yuǎn)程監(jiān)控也是在這里設(shè)置,以下為 64 位系統(tǒng)環(huán)境下的配置,內(nèi)存加入的參數(shù)如下:
CATALINA_OPTS=" -server -Xms6000M -Xmx6000M -Xss512k -XX:NewSize=2250M -XX:MaxNewSize=2250M -XX:PermSize=128M -XX:MaxPermSize=256M -XX:+AggressiveOpts -XX:+UseBiasedLocking -XX:+DisableExplicitGC -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:MaxTenuringThreshold=31 -XX:+CMSParallelRemarkEnabled -XX:+UseCMSCompactAtFullCollection -XX:LargePageSizeInBytes=128m -XX:+UseFastAccessorMethods -XX:+UseCMSInitiatingOccupancyOnly -Duser.timezone=Asia/Shanghai -Djava.awt.headless=true"為了看著方便,將每個(gè)參數(shù)單獨(dú)寫一行。上面參數(shù)好多啊,可能有人寫到現(xiàn)在都沒(méi)見(jiàn)過(guò)一個(gè)在 Tomcat 的啟動(dòng)命令里加了這么多參數(shù),當(dāng)然,這些參數(shù)只是我機(jī)器上的,不一定適合你,尤其是參數(shù)后的 value(值)是需要根據(jù)你自己的實(shí)際情況來(lái)設(shè)置的。
上述這樣的配置,基本上可以達(dá)到:
系統(tǒng)響應(yīng)時(shí)間增快;
JVM回收速度增快同時(shí)又不影響系統(tǒng)的響應(yīng)率;
JVM內(nèi)存最大化利用;
線程阻塞情況最小化。
JVM 常用參數(shù)詳解:
-server:一定要作為第一個(gè)參數(shù),在多個(gè) CPU 時(shí)性能佳,還有一種叫 -client 的模式,特點(diǎn)是啟動(dòng)速度比較快,但運(yùn)行時(shí)性能和內(nèi)存管理效率不高,通常用于客戶端應(yīng)用程序或開(kāi)發(fā)調(diào)試,在 32 位環(huán)境下直接運(yùn)行 Java 程序默認(rèn)啟用該模式。Server 模式的特點(diǎn)是啟動(dòng)速度比較慢,但運(yùn)行時(shí)性能和內(nèi)存管理效率很高,適用于生產(chǎn)環(huán)境,在具有 64 位能力的 JDK 環(huán)境下默認(rèn)啟用該模式,可以不配置該參數(shù)。
-Xms:表示 Java 初始化堆的大小,-Xms 與-Xmx 設(shè)成一樣的值,避免 JVM 反復(fù)重新申請(qǐng)內(nèi)存,導(dǎo)致性能大起大落,默認(rèn)值為物理內(nèi)存的 1/64,默認(rèn)(MinHeapFreeRatio參數(shù)可以調(diào)整)空余堆內(nèi)存小于 40% 時(shí),JVM 就會(huì)增大堆直到 -Xmx 的最大限制。
-Xmx:表示最大 Java 堆大小,當(dāng)應(yīng)用程序需要的內(nèi)存超出堆的最大值時(shí)虛擬機(jī)就會(huì)提示內(nèi)存溢出,并且導(dǎo)致應(yīng)用服務(wù)崩潰,因此一般建議堆的最大值設(shè)置為可用內(nèi)存的最大值的80%。如何知道我的 JVM 能夠使用最大值,使用 java -Xmx512M -version 命令來(lái)進(jìn)行測(cè)試,然后逐漸的增大 512 的值,如果執(zhí)行正常就表示指定的內(nèi)存大小可用,否則會(huì)打印錯(cuò)誤信息,默認(rèn)值為物理內(nèi)存的 1/4,默認(rèn)(MinHeapFreeRatio參數(shù)可以調(diào)整)空余堆內(nèi)存大于 70% 時(shí),JVM 會(huì)減少堆直到-Xms 的最小限制。
-Xss:表示每個(gè) Java 線程堆棧大小,JDK 5.0 以后每個(gè)線程堆棧大小為 1M,以前每個(gè)線程堆棧大小為 256K。根據(jù)應(yīng)用的線程所需內(nèi)存大小進(jìn)行調(diào)整,在相同物理內(nèi)存下,減小這個(gè)值能生成更多的線程,但是操作系統(tǒng)對(duì)一個(gè)進(jìn)程內(nèi)的線程數(shù)還是有限制的,不能無(wú)限生成,經(jīng)驗(yàn)值在 3000~5000 左右。一般小的應(yīng)用, 如果棧不是很深, 應(yīng)該是128k 夠用的,大的應(yīng)用建議使用 256k 或 512K,一般不易設(shè)置超過(guò) 1M,要不然容易出現(xiàn)out ofmemory。這個(gè)選項(xiàng)對(duì)性能影響比較大,需要嚴(yán)格的測(cè)試。
-XX:NewSize:設(shè)置新生代內(nèi)存大小。
-XX:MaxNewSize:設(shè)置最大新生代新生代內(nèi)存大小
-XX:PermSize:設(shè)置持久代內(nèi)存大小
-XX:MaxPermSize:設(shè)置最大值持久代內(nèi)存大小,永久代不屬于堆內(nèi)存,堆內(nèi)存只包含新生代和老年代。
-XX:+AggressiveOpts:作用如其名(aggressive),啟用這個(gè)參數(shù),則每當(dāng) JDK 版本升級(jí)時(shí),你的 JVM 都會(huì)使用最新加入的優(yōu)化技術(shù)(如果有的話)。
-XX:+UseBiasedLocking:啟用一個(gè)優(yōu)化了的線程鎖,我們知道在我們的appserver,每個(gè)http請(qǐng)求就是一個(gè)線程,有的請(qǐng)求短有的請(qǐng)求長(zhǎng),就會(huì)有請(qǐng)求排隊(duì)的現(xiàn)象,甚至還會(huì)出現(xiàn)線程阻塞,這個(gè)優(yōu)化了的線程鎖使得你的appserver內(nèi)對(duì)線程處理自動(dòng)進(jìn)行最優(yōu)調(diào)配。
-XX:+DisableExplicitGC:在 程序代碼中不允許有顯示的調(diào)用“System.gc()”。每次在到操作結(jié)束時(shí)手動(dòng)調(diào)用 System.gc() 一下,付出的代價(jià)就是系統(tǒng)響應(yīng)時(shí)間嚴(yán)重降低,就和關(guān)于 Xms,Xmx 里的解釋的原理一樣,這樣去調(diào)用 GC 導(dǎo)致系統(tǒng)的 JVM 大起大落。
-XX:+UseConcMarkSweepGC:設(shè)置年老代為并發(fā)收集,即 CMS gc,這一特性只有 jdk1.5
后續(xù)版本才具有的功能,它使用的是 gc 估算觸發(fā)和 heap 占用觸發(fā)。我們知道頻頻繁的 GC 會(huì)造面 JVM
的大起大落從而影響到系統(tǒng)的效率,因此使用了 CMS GC 后可以在 GC 次數(shù)增多的情況下,每次 GC 的響應(yīng)時(shí)間卻很短,比如說(shuō)使用了 CMS
GC 后經(jīng)過(guò) jprofiler 的觀察,GC 被觸發(fā)次數(shù)非常多,而每次 GC 耗時(shí)僅為幾毫秒。
-XX:+UseParNewGC:對(duì)新生代采用多線程并行回收,這樣收得快,注意最新的 JVM 版本,當(dāng)使用 -XX:+UseConcMarkSweepGC 時(shí),-XX:UseParNewGC 會(huì)自動(dòng)開(kāi)啟。因此,如果年輕代的并行 GC 不想開(kāi)啟,可以通過(guò)設(shè)置 -XX:-UseParNewGC 來(lái)關(guān)掉。
-XX:MaxTenuringThreshold:設(shè)置垃圾最大年齡。如果設(shè)置為0的話,則新生代對(duì)象不經(jīng)過(guò) Survivor 區(qū),直接進(jìn)入老年代。對(duì)于老年代比較多的應(yīng)用(需要大量常駐內(nèi)存的應(yīng)用),可以提高效率。如果將此值設(shè)置為一 個(gè)較大值,則新生代對(duì)象會(huì)在 Survivor 區(qū)進(jìn)行多次復(fù)制,這樣可以增加對(duì)象在新生代的存活時(shí)間,增加在新生代即被回收的概率,減少Full GC的頻率,這樣做可以在某種程度上提高服務(wù)穩(wěn)定性。該參數(shù)只有在串行 GC 時(shí)才有效,這個(gè)值的設(shè)置是根據(jù)本地的 jprofiler 監(jiān)控后得到的一個(gè)理想的值,不能一概而論原搬照抄。
-XX:+CMSParallelRemarkEnabled:在使用 UseParNewGC 的情況下,盡量減少 mark 的時(shí)間。
-XX:+UseCMSCompactAtFullCollection:在使用 concurrent gc 的情況下,防止 memoryfragmention,對(duì) live object 進(jìn)行整理,使 memory 碎片減少。
-XX:LargePageSizeInBytes:指定 Java heap 的分頁(yè)頁(yè)面大小,內(nèi)存頁(yè)的大小不可設(shè)置過(guò)大, 會(huì)影響 Perm 的大小。
-XX:+UseFastAccessorMethods:使用 get,set 方法轉(zhuǎn)成本地代碼,原始類型的快速優(yōu)化。
-XX:+UseCMSInitiatingOccupancyOnly:只有在 oldgeneration 在使用了初始化的比例后 concurrent collector 啟動(dòng)收集。
-Duser.timezone=Asia/Shanghai:設(shè)置用戶所在時(shí)區(qū)。
-Djava.awt.headless=true:這個(gè)參數(shù)一般我們都是放在最后使用的,這全參數(shù)的作用是這樣的,有時(shí)我們會(huì)在我們的 J2EE 工程中使用一些圖表工具如:jfreechart,用于在 web 網(wǎng)頁(yè)輸出 GIF/JPG 等流,在 winodws 環(huán)境下,一般我們的 app server 在輸出圖形時(shí)不會(huì)碰到什么問(wèn)題,但是在linux/unix 環(huán)境下經(jīng)常會(huì)碰到一個(gè) exception 導(dǎo)致你在 winodws 開(kāi)發(fā)環(huán)境下圖片顯示的好好可是在 linux/unix 下卻顯示不出來(lái),因此加上這個(gè)參數(shù)以免避這樣的情況出現(xiàn)。
-Xmn:新生代的內(nèi)存空間大小,注意:此處的大小是(eden+ 2 survivor space)。與 jmap -heap 中顯示的 New gen 是不同的。整個(gè)堆大小 = 新生代大小 + 老生代大小 + 永久代大小。在保證堆大小不變的情況下,增大新生代后,將會(huì)減小老生代大小。此值對(duì)系統(tǒng)性能影響較大,Sun官方推薦配置為整個(gè)堆的 3/8。
-XX:CMSInitiatingOccupancyFraction:當(dāng)堆滿之后,并行收集器便開(kāi)始進(jìn)行垃圾收集,例如,當(dāng)沒(méi)有足夠的空間來(lái)容納新分配或提升的對(duì)象。對(duì)于 CMS 收集器,長(zhǎng)時(shí)間等待是不可取的,因?yàn)樵诓l(fā)垃圾收集期間應(yīng)用持續(xù)在運(yùn)行(并且分配對(duì)象)。因此,為了在應(yīng)用程序使用完內(nèi)存之前完成垃圾收集周期,CMS 收集器要比并行收集器更先啟動(dòng)。因?yàn)椴煌膽?yīng)用會(huì)有不同對(duì)象分配模式,JVM 會(huì)收集實(shí)際的對(duì)象分配(和釋放)的運(yùn)行時(shí)數(shù)據(jù),并且分析這些數(shù)據(jù),來(lái)決定什么時(shí)候啟動(dòng)一次 CMS 垃圾收集周期。這個(gè)參數(shù)設(shè)置有很大技巧,基本上滿足(Xmx-Xmn)(100-CMSInitiatingOccupancyFraction)/100 >= Xmn 就不會(huì)出現(xiàn) promotion failed。例如在應(yīng)用中 Xmx 是6000,Xmn 是 512,那么 Xmx-Xmn 是 5488M,也就是老年代有 5488M,CMSInitiatingOccupancyFraction=90 說(shuō)明老年代到 90% 滿的時(shí)候開(kāi)始執(zhí)行對(duì)老年代的并發(fā)垃圾回收(CMS),這時(shí)還 剩 10% 的空間是 548810% = 548M,所以即使 Xmn(也就是新生代共512M)里所有對(duì)象都搬到老年代里,548M 的空間也足夠了,所以只要滿足上面的公式,就不會(huì)出現(xiàn)垃圾回收時(shí)的 promotion failed,因此這個(gè)參數(shù)的設(shè)置必須與 Xmn 關(guān)聯(lián)在一起。
-XX:+CMSIncrementalMode:該標(biāo)志將開(kāi)啟 CMS 收集器的增量模式。增量模式經(jīng)常暫停 CMS 過(guò)程,以便對(duì)應(yīng)用程序線程作出完全的讓步。因此,收集器將花更長(zhǎng)的時(shí)間完成整個(gè)收集周期。因此,只有通過(guò)測(cè)試后發(fā)現(xiàn)正常 CMS 周期對(duì)應(yīng)用程序線程干擾太大時(shí),才應(yīng)該使用增量模式。由于現(xiàn)代服務(wù)器有足夠的處理器來(lái)適應(yīng)并發(fā)的垃圾收集,所以這種情況發(fā)生得很少,用于但 CPU情況。
-XX:NewRatio:年輕代(包括 Eden 和兩個(gè) Survivor 區(qū))與年老代的比值(除去持久代),-XX:NewRatio=4 表示年輕代與年老代所占比值為 1:4,年輕代占整個(gè)堆棧的 1/5,Xms=Xmx 并且設(shè)置了 Xmn 的情況下,該參數(shù)不需要進(jìn)行設(shè)置。
-XX:SurvivorRatio:Eden 區(qū)與 Survivor 區(qū)的大小比值,設(shè)置為 8,表示 2 個(gè) Survivor 區(qū)(JVM 堆內(nèi)存年輕代中默認(rèn)有 2 個(gè)大小相等的 Survivor 區(qū))與 1 個(gè) Eden 區(qū)的比值為 2:8,即 1 個(gè) Survivor 區(qū)占整個(gè)年輕代大小的 1/10。
-XX:+UseSerialGC:設(shè)置串行收集器。
-XX:+UseParallelGC:設(shè)置為并行收集器。此配置僅對(duì)年輕代有效。即年輕代使用并行收集,而年老代仍使用串行收集。
-XX:+UseParallelOldGC:配置年老代垃圾收集方式為并行收集,JDK6.0 開(kāi)始支持對(duì)年老代并行收集。
-XX:ConcGCThreads:早期 JVM 版本也叫-XX:ParallelCMSThreads,定義并發(fā) CMS 過(guò)程運(yùn)行時(shí)的線程數(shù)。比如 value=4 意味著 CMS 周期的所有階段都以 4 個(gè)線程來(lái)執(zhí)行。盡管更多的線程會(huì)加快并發(fā) CMS 過(guò)程,但其也會(huì)帶來(lái)額外的同步開(kāi)銷。因此,對(duì)于特定的應(yīng)用程序,應(yīng)該通過(guò)測(cè)試來(lái)判斷增加 CMS 線程數(shù)是否真的能夠帶來(lái)性能的提升。如果還標(biāo)志未設(shè)置,JVM 會(huì)根據(jù)并行收集器中的 -XX:ParallelGCThreads 參數(shù)的值來(lái)計(jì)算出默認(rèn)的并行 CMS 線程數(shù)。
-XX:ParallelGCThreads:配置并行收集器的線程數(shù),即:同時(shí)有多少個(gè)線程一起進(jìn)行垃圾回收,此值建議配置與 CPU 數(shù)目相等。
-XX:OldSize:設(shè)置 JVM 啟動(dòng)分配的老年代內(nèi)存大小,類似于新生代內(nèi)存的初始大小 -XX:NewSize。
以上就是一些常用的配置參數(shù),有些參數(shù)是可以被替代的,配置思路需要考慮的是 Java 提供的垃圾回收機(jī)制。虛擬機(jī)的堆大小決定了虛擬機(jī)花費(fèi)在收集垃圾上的時(shí)間和頻度。收集垃圾能夠接受的速度和應(yīng)用有關(guān),應(yīng)該通過(guò)分析實(shí)際的垃圾收集的時(shí)間和頻率來(lái)調(diào)整。假如堆的大小很大,那么完全垃圾收集就會(huì)很慢,但是頻度會(huì)降低。假如您把堆的大小和內(nèi)存的需要一致,完全收集就很快,但是會(huì)更加頻繁。調(diào)整堆大小的的目的是最小化垃圾收集的時(shí)間,以在特定的時(shí)間內(nèi)最大化處理客戶的請(qǐng)求。在基準(zhǔn)測(cè)試的時(shí)候,為確保最好的性能,要把堆的大小設(shè)大,確保垃圾收集不在整個(gè)基準(zhǔn)測(cè)試的過(guò)程中出現(xiàn)。
假如系統(tǒng)花費(fèi)很多的時(shí)間收集垃圾,請(qǐng)減小堆大小。一次完全的垃圾收集應(yīng)該不超過(guò) 3-5 秒。假如垃圾收集成為瓶頸,那么需要指定代的大小,檢查垃圾收集的周詳輸出,研究垃圾收集參數(shù)對(duì)性能的影響。當(dāng)增加處理器時(shí),記得增加內(nèi)存,因?yàn)榉峙淠軌虿⑿羞M(jìn)行,而垃圾收集不是并行的。
常見(jiàn)的 Java 內(nèi)存溢出有以下三種
(1) java.lang.OutOfMemoryError: Java heap space —-JVM Heap(堆)溢出
JVM 在啟動(dòng)的時(shí)候會(huì)自動(dòng)設(shè)置 JVM Heap 的值,其初始空間(即-Xms)是物理內(nèi)存的1/64,最大空間(-Xmx)不可超過(guò)物理內(nèi)存。可以利用 JVM提供的 -Xmn -Xms -Xmx 等選項(xiàng)可進(jìn)行設(shè)置。Heap 的大小是 Young Generation 和 Tenured Generaion 之和。在 JVM 中如果 98% 的時(shí)間是用于 GC,且可用的 Heap size 不足 2% 的時(shí)候?qū)伋龃水惓P畔ⅰ?br /> 解決方法:手動(dòng)設(shè)置 JVM Heap(堆)的大小。
(2) java.lang.OutOfMemoryError: PermGen space —- PermGen space溢出。
PermGen space 的全稱是 Permanent Generation space,是指內(nèi)存的永久保存區(qū)域。為什么會(huì)內(nèi)存溢出,這是由于這塊內(nèi)存主要是被 JVM 存放Class 和 Meta 信息的,Class 在被 Load 的時(shí)候被放入 PermGen space 區(qū)域,它和存放 Instance 的 Heap 區(qū)域不同,sun 的 GC 不會(huì)在主程序運(yùn)行期對(duì) PermGen space 進(jìn)行清理,所以如果你的 APP 會(huì)載入很多 CLASS 的話,就很可能出現(xiàn) PermGen space 溢出。
解決方法: 手動(dòng)設(shè)置 MaxPermSize 大小
(3) java.lang.StackOverflowError —- 棧溢出
棧溢出了,JVM 依然是采用棧式的虛擬機(jī),這個(gè)和 C 與 Pascal 都是一樣的。函數(shù)的調(diào)用過(guò)程都體現(xiàn)在堆棧和退棧上了。調(diào)用構(gòu)造函數(shù)的 “層”太多了,以致于把棧區(qū)溢出了。通常來(lái)講,一般棧區(qū)遠(yuǎn)遠(yuǎn)小于堆區(qū)的,因?yàn)楹瘮?shù)調(diào)用過(guò)程往往不會(huì)多于上千層,而即便每個(gè)函數(shù)調(diào)用需要 1K 的空間(這個(gè)大約相當(dāng)于在一個(gè) C 函數(shù)內(nèi)聲明了 256 個(gè) int 類型的變量),那么棧區(qū)也不過(guò)是需要 1MB 的空間。通常棧的大小是 1-2MB 的。
通常遞歸也不要遞歸的層次過(guò)多,很容易溢出。
解決方法:修改程序。
轉(zhuǎn)自IDONGXU博客
1.7.2 線程池的優(yōu)化
默認(rèn)配置下,Tomcat 會(huì)為每個(gè)連接器創(chuàng)建一個(gè)綁定的線程池(最大線程數(shù) 200),服務(wù)啟動(dòng)時(shí),默認(rèn)創(chuàng)建了 5 個(gè)空閑線程隨時(shí)等待用戶請(qǐng)求。
首先,打開(kāi) ${TOMCAT_HOME}/conf/server.xml,搜索【<Executor name=“tomcatThreadPool”】,開(kāi)啟并調(diào)整為
然后在connect里指定使用的executor,
<Connector executor="tomcatThreadPool"port="8080" protocol="HTTP/1.1"URIEncoding="UTF-8"connectionTimeout="30000"enableLookups="false"disableUploadTimeout="false"connectionUploadTimeout="150000"acceptCount="300"keepAliveTimeout="120000"maxKeepAliveRequests="1"compression="on"compressionMinSize="2048"compressableMimeType="text/html,text/xml,text/javascript,text/css,text/plain,image/gif,image/jpg,image/png" redirectPort="8443" />maxThreads :Tomcat 使用線程來(lái)處理接收的每個(gè)請(qǐng)求,這個(gè)值表示 Tomcat 可創(chuàng)建的最大的線程數(shù),默認(rèn)值是 200
minSpareThreads:最小空閑線程數(shù),Tomcat 啟動(dòng)時(shí)的初始化的線程數(shù),表示即使沒(méi)有人使用也開(kāi)這么多空線程等待,默認(rèn)值是 10。
maxSpareThreads:最大備用線程數(shù),一旦創(chuàng)建的線程超過(guò)這個(gè)值,Tomcat 就會(huì)關(guān)閉不再需要的 socket 線程。
上邊配置的參數(shù),最大線程 500(一般服務(wù)器足以),要根據(jù)自己的實(shí)際情況合理設(shè)置,設(shè)置越大會(huì)耗費(fèi)內(nèi)存和 CPU,因?yàn)?CPU 疲于線程上下文切換,沒(méi)有精力提供請(qǐng)求服務(wù)了,最小空閑線程數(shù) 20,線程最大空閑時(shí)間 60 秒,當(dāng)然允許的最大線程連接數(shù)還受制于操作系統(tǒng)的內(nèi)核參數(shù)設(shè)置,設(shè)置多大要根據(jù)自己的需求與環(huán)境。當(dāng)然線程可以配置在“tomcatThreadPool”中,也可以直接配置在“Connector”中,但不可以重復(fù)配置。
URIEncoding:指定 Tomcat 容器的 URL 編碼格式,語(yǔ)言編碼格式這塊倒不如其它 WEB 服務(wù)器軟件配置方便,需要分別指定。
connnectionTimeout: 網(wǎng)絡(luò)連接超時(shí),單位:毫秒,設(shè)置為 0 表示永不超時(shí),這樣設(shè)置有隱患的。通常可設(shè)置為 30000 毫秒,可根據(jù)檢測(cè)實(shí)際情況,適當(dāng)修改。
enableLookups: 是否反查域名,以返回遠(yuǎn)程主機(jī)的主機(jī)名,取值為:true 或 false,如果設(shè)置為false,則直接返回IP地址,為了提高處理能力,應(yīng)設(shè)置為 false。
disableUploadTimeout:上傳時(shí)是否使用超時(shí)機(jī)制。
connectionUploadTimeout:上傳超時(shí)時(shí)間,畢竟文件上傳可能需要消耗更多的時(shí)間,這個(gè)根據(jù)你自己的業(yè)務(wù)需要自己調(diào),以使Servlet有較長(zhǎng)的時(shí)間來(lái)完成它的執(zhí)行,需要與上一個(gè)參數(shù)一起配合使用才會(huì)生效。
acceptCount:指定當(dāng)所有可以使用的處理請(qǐng)求的線程數(shù)都被使用時(shí),可傳入連接請(qǐng)求的最大隊(duì)列長(zhǎng)度,超過(guò)這個(gè)數(shù)的請(qǐng)求將不予處理,默認(rèn)為100個(gè)。
keepAliveTimeout:長(zhǎng)連接最大保持時(shí)間(毫秒),表示在下次請(qǐng)求過(guò)來(lái)之前,Tomcat 保持該連接多久,默認(rèn)是使用 connectionTimeout 時(shí)間,-1 為不限制超時(shí)。
maxKeepAliveRequests:表示在服務(wù)器關(guān)閉之前,該連接最大支持的請(qǐng)求數(shù)。超過(guò)該請(qǐng)求數(shù)的連接也將被關(guān)閉,1表示禁用,-1表示不限制個(gè)數(shù),默認(rèn)100個(gè),一般設(shè)置在100~200之間。
compression:是否對(duì)響應(yīng)的數(shù)據(jù)進(jìn)行 GZIP 壓縮,off:表示禁止壓縮;on:表示允許壓縮(文本將被壓縮)、force:表示所有情況下都進(jìn)行壓縮,默認(rèn)值為off,壓縮數(shù)據(jù)后可以有效的減少頁(yè)面的大小,一般可以減小1/3左右,節(jié)省帶寬。
compressionMinSize:表示壓縮響應(yīng)的最小值,只有當(dāng)響應(yīng)報(bào)文大小大于這個(gè)值的時(shí)候才會(huì)對(duì)報(bào)文進(jìn)行壓縮,如果開(kāi)啟了壓縮功能,默認(rèn)值就是2048。
compressableMimeType:壓縮類型,指定對(duì)哪些類型的文件進(jìn)行數(shù)據(jù)壓縮。
noCompressionUserAgents=“gozilla, traviata”: 對(duì)于以下的瀏覽器,不啟用壓縮。
如果已經(jīng)對(duì)代碼進(jìn)行了動(dòng)靜分離,靜態(tài)頁(yè)面和圖片等數(shù)據(jù)就不需要 Tomcat 處理了,那么也就不需要配置在 Tomcat 中配置壓縮了。
1.7.3 數(shù)據(jù)庫(kù)性能調(diào)優(yōu)
Tomcat性能在等待數(shù)據(jù)庫(kù)查詢被執(zhí)行期間會(huì)降低。如今大多數(shù)應(yīng)用程序都是使用可能包含“命名查詢”的關(guān)系型數(shù)據(jù)庫(kù)。如果是那樣的話,Tomcat會(huì)在啟動(dòng)時(shí)默認(rèn)加載命名查詢,這個(gè)可能會(huì)提升性能。另一件重要事是確保所有數(shù)據(jù)庫(kù)連接正確地關(guān)閉。給數(shù)據(jù)庫(kù)連接池設(shè)置正確值也是十分重要的。我所說(shuō)的值是指Resource要素的最大空閑數(shù)(maxIdle),最大連接數(shù)(maxActive),最大建立連接等待時(shí)間(maxWait)屬性的值。因?yàn)榕渲靡蕾嚺c應(yīng)用要求,我也不能在本文指定正確的值。你可以通過(guò)調(diào)用數(shù)據(jù)庫(kù)性能測(cè)試來(lái)找到正確的值。
1.7.4 其他
- 開(kāi)啟瀏覽器緩存
- 一般https會(huì)比http請(qǐng)求慢,當(dāng)然為了安全,我們肯定要選擇https
總結(jié)
- 上一篇: spring event的事件驱动模型的
- 下一篇: nginx必知必会