工作中項(xiàng)目的原因,項(xiàng)目云上貴州服務(wù)器有時(shí)候支撐不起太高的并發(fā)量,而且又沒那么快更換更優(yōu)的服務(wù)器蛾派,所以只能從tomcat上去做一些優(yōu)化了。
tomcat優(yōu)化我是從兩個(gè)地方入手个少,一個(gè)就是server.xml洪乍,還有一個(gè)就是catalina.sh。
server.xml
找到tomcat->conf下的server.xml
- 先來看一個(gè)tomcat的線程池夜焦,默認(rèn)的:
<!--
<Executor name="tomcatThreadPool" namePrefix="catalina-exec-"
maxThreads="150" minSpareThreads="4"/>
-->
這里默認(rèn)是注釋掉的壳澳,我們修改為:
<Executor
name="tomcatThreadPool"
namePrefix="catalina-exec-"
maxThreads="900"
minSpareThreads="100"
maxSpareThreads="500"
prestartminSpareThreads="true"
maxQueueSize="300"
/>
- maxThreads:最大并發(fā)數(shù),默認(rèn)為200茫经,一般設(shè)置在600-900
- minSpareThreads:最小備用線程數(shù)巷波,tomcat初始化時(shí)創(chuàng)建的線程,默認(rèn)為25
- maxSpareThreads:最大備用線程數(shù)
- prestartminSpareThreads:在Tomcat初始化的時(shí)候就初始化 minSpareThreads 的參數(shù)值卸伞,如果不等于 true抹镊,minSpareThreads的值就沒啥效果了
- maxQueueSize:最大的等待隊(duì)列數(shù),超過則拒絕請(qǐng)求
- 修改鏈接參數(shù):
默認(rèn)的是:
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
默認(rèn)的是http協(xié)議的荤傲,我們這里先將tomcat設(shè)置成了https協(xié)議:
<Connector port="9090"
protocol="org.apache.coyote.http11.Http11Nio2Protocol"
maxThreads="10000"
SSLEnabled="true"
scheme="https"
secure="true"
keystoreFile="cert/wtm-ssl.pfx"
keystorePass="111"
keystoreType="PKCS12"
useBodyEncodingForURI="true"
clientAuth="false"
sslProtocol="TLS"
connectionTimeout="20000"
redirectPort="8443"
需不需要改成https協(xié)議按業(yè)務(wù)來分垮耳,在此基礎(chǔ)上接著:
executor="tomcatThreadPool"
maxConnections="900"
enableLookups="false"
acceptCount="700"
maxPostSize="10485760"
disableUploadTimeout="true"
compression="on"
compressionMinSize="2048"
maxProcessors="1000"
minProcessors="5"
compressableMimeType="text/html,text/xml,text/plain,text/css,text/javascript,application/javascript"
URIEncoding="UTF-8"
/>
首先要執(zhí)行之前配置的tomcat線程池
- maxConnections:最大連接數(shù)
- enableLookups:禁用DNS查詢,為了提高性能,設(shè)置為false
- acceptCount:當(dāng)線程數(shù)達(dá)到maxThreads后后續(xù)請(qǐng)求會(huì)被放入一個(gè)等待隊(duì)列终佛,這個(gè)acceptCount就是這個(gè)隊(duì)列的大小俊嗽,默認(rèn)為100
- maxPostSize:以FORM URL參數(shù)方式提交post請(qǐng)求,限制提交最大的大小铃彰,默認(rèn)2097152字節(jié)(2M)
- disableUploadTimeout:類似于Apache中的keeyalive一樣,是否需要tomcat容器單獨(dú)設(shè)置上傳時(shí)間限制绍豁,這里是不用,還是使用標(biāo)準(zhǔn)的牙捉,不去給上傳的附件單獨(dú)做超時(shí)設(shè)置
- compression:設(shè)置是否開啟GZip壓縮HTTP 壓縮
- compressionMinSize:?jiǎn)⒂脡嚎s的輸出內(nèi)容大小竹揍,這里面默認(rèn)為2KB
- maxProcessors:線程共享地址空間
- minProcessors:線程共享地址空間
- compressableMimeType:需要壓縮的類型
catalina.sh
在tomcat/bin/catalina.sh文件中,將下列添加到文件第一行:
如果服務(wù)器只運(yùn)行一個(gè)tomcat
- 內(nèi)存4G:
CATALINA_OPTS="-Dfile.encoding=UTF-8 -server -Xms2048m -Xmx2048m -Xmn1024m
-XX:PermSize=256m -XX:MaxPermSize=512m -XX:SurvivorRatio=10
-XX:MaxTenuringThreshold=15 -XX:NewRatio=2 -XX:+DisableExplicitGC"
- 內(nèi)存8G:
CATALINA_OPTS="-Dfile.encoding=UTF-8 -server -Xms4096m -Xmx4096m -Xmn2048m
-XX:PermSize=256m -XX:MaxPermSize=512m -XX:SurvivorRatio=10
-XX:MaxTenuringThreshold=15 -XX:NewRatio=2 -XX:+DisableExplicitGC"
- 內(nèi)存16G:
CATALINA_OPTS="-Dfile.encoding=UTF-8 -server -Xms8192m -Xmx8192m -Xmn4096m
-XX:PermSize=256m -XX:MaxPermSize=512m -XX:SurvivorRatio=10
-XX:MaxTenuringThreshold=15 -XX:NewRatio=2 -XX:+DisableExplicitGC"
- 內(nèi)存32G:
CATALINA_OPTS="-Dfile.encoding=UTF-8 -server -Xms16384m -Xmx16384m -Xmn8192m
-XX:PermSize=256m -XX:MaxPermSize=512m -XX:SurvivorRatio=10
-XX:MaxTenuringThreshold=15 -XX:NewRatio=2 -XX:+DisableExplicitGC"
參數(shù)說明:
- -Dfile.encoding:默認(rèn)文件編碼
- -server:表示這是應(yīng)用于服務(wù)器的配置鹃共,JVM 內(nèi)部會(huì)有特殊處理的
- -Xmx1024m:設(shè)置JVM最大可用內(nèi)存為1024MB
- -Xms1024m:設(shè)置JVM最小內(nèi)存為1024m鬼佣。此值可以設(shè)置與-Xmx相同,以避免每次垃圾回收完成后JVM重新分配內(nèi)存霜浴。
- -Xmn1024m:設(shè)置JVM新生代大懈囱(JDK1.4之后版本)稀蟋。一般-Xmn的大小是-Xms的1/2左右,不要設(shè)置的過大或過小,過大導(dǎo)致老年代變小岗屏,頻繁Full GC夯辖,過小導(dǎo)致minor GC頻繁翰绊。如果不設(shè)置-Xmn胆屿,可以采用-XX:NewRatio=2來設(shè)置,也是一樣的效果
- -XX:NewSize:設(shè)置新生代大小
- -XX:MaxNewSize:設(shè)置最大的新生代大小
- -XX:PermSize:設(shè)置永久代大小
- -XX:MaxPermSize:設(shè)置最大永久代大小
- -XX:NewRatio=4:設(shè)置年輕代(Eden和兩個(gè)Survivor)與終身代的比值(去除永久代)
- -XX:MaxTenuringThreshold=10:設(shè)置垃圾最大年齡慕嚷,默認(rèn)為:15哥牍。如果設(shè)置為 0 的話,則年輕代對(duì)象不經(jīng)過 Survivor 區(qū)喝检,直接進(jìn)入年老代嗅辣。對(duì)于年老代比較多的應(yīng)用,可以提高效率挠说。
- -XX:+DisableExplicitGC:這個(gè)將會(huì)忽略手動(dòng)調(diào)用 GC 的代碼使得 System.gc() 的調(diào)用就會(huì)變成一個(gè)空調(diào)用澡谭,完全不會(huì)觸發(fā)任何 GC
JVM的垃圾回收機(jī)制:
jvm的內(nèi)存分為2類,一個(gè)是perm型损俭,一個(gè)是generation型蛙奖。perm區(qū)域存放的是class這些靜態(tài)信息,一般默認(rèn)為64m杆兵,如果項(xiàng)目很大雁仲,有可能已啟動(dòng)就會(huì)報(bào)錯(cuò):out of memory permsize。重新設(shè)置一下permsize就可以解決琐脏。
而generation區(qū)域攒砖,應(yīng)用代碼基本在這個(gè)區(qū)域活動(dòng),new的類都會(huì)在這個(gè)區(qū)域,而且jvm的絕大部分工作也在這里祭衩。大致理解一下:
這個(gè)區(qū)域區(qū)域包含新生代和老生代區(qū)域,所有new出來的會(huì)放置在新區(qū)域阅签,而多次回收失敗的一些一直被使用的實(shí)例則會(huì)被轉(zhuǎn)移到老生代掐暮,所以新生代區(qū)域的活動(dòng)很頻繁。新生代內(nèi)存不足會(huì)觸發(fā)一次這個(gè)區(qū)域的GC---然后再到老生代GC---最后FULL GC政钟。FULL GC代價(jià)很高路克,應(yīng)盡量避免,盡量在newsize參數(shù)的這個(gè)區(qū)gc养交,一般配置 newsize分配到總內(nèi)存1/4左右精算,---最終,如果full gc 還是內(nèi)存不足碎连,那就會(huì)引發(fā)out of memory 常見的那種灰羽。