Tomcat8–模板配置記錄
http://71.oopspy.com/?p=2230
參考:http://tomcat.apache.org/tomcat-8.5-doc/config/http.html
聯結器選擇:
cat catalina.sh
- #!/bin/sh
- JAVA_HOME="/opt/programs/jdk_1.8.0_111"
- CPU_N=`cat /proc/cpuinfo| grep "processor"| wc -l`
- JMX_PORTS=`grep "jmx.port" $CATALINA_BASE/conf/catalina.properties | cut -d= -f2`
- if["$1"x ="start"x ];then
- JMX_OPTS="-Dcom.sun.management.jmxremote.port=$JMX_PORTS -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false"
- else
- echo "stop: not to bind jmx port"
- fi
- JAVA_OPTS="
- -server
- -Xmx1024M
- -Xms1024M
- -Xmn256M
- -XX:MetaspaceSize=256m
- -XX:MaxMetaspaceSize=512m
- -Xss512K
- -XX:+ExplicitGCInvokesConcurrent
- -XX:+UseConcMarkSweepGC
- -XX:+UseParNewGC
- -XX:ParallelGCThreads=$CPU_N
- -XX:+CMSParallelRemarkEnabled
- -XX:+CMSClassUnloadingEnabled
- -XX:LargePageSizeInBytes=128M
- -XX:+UseFastAccessorMethods
- -XX:CMSInitiatingOccupancyFraction=80
- -XX:SoftRefLRUPolicyMSPerMB=0
- -XX:+PrintGC
- -XX:+PrintGCDetails
- -XX:+PrintGCTimeStamps
- -XX:+PrintGCDateStamps
- -XX:+PrintHeapAtGC
- -XX:+PrintGCApplicationStoppedTime
- -Xloggc:$CATALINA_BASE/logs/`date +%Y%m%d%H%M%S`_gc.log
- -XX:+HeapDumpOnOutOfMemoryError"
- JAVA_OPTS="$JAVA_OPTS $JMX_OPTS -Djava.nio.channels.spi.SelectorProvider=sun.nio.ch.EPollSelectorProvider"
- ......
#上述的配置效果:
系統響應時間增快
JVM回收速度增快同時又不影響系統的響應率
JVM記憶體最大化利用
執行緒阻塞情況最小化
nio支援epoll,啟用epoll對併發idle connection會有大幅度的效能提升
cat server.xml
- <?xml version='1.0' encoding='utf-8'?>
- <Serverport="${shutdown.port}"shutdown="SHUTDOWN">
- Listener className="org.apache.catalina.startup.VersionLoggerListener" />
- <!-- Security listener. Documentation at /docs/config/listeners.html
- <Listener className="org.apache.catalina.security.SecurityListener" />
- -->
- <!--APR library loader. Documentation at /docs/apr.html -->
- <ListenerclassName="org.apache.catalina.core.AprLifecycleListener"SSLEngine="on"/>
- <!--Initialize Jasper prior to webapps are loaded. Documentation at /docs/jasper-howto.html -->
- <ListenerclassName="org.apache.catalina.core.JasperListener"/>
- <!-- Prevent memory leaks due to use of particular java/javax APIs-->
- <ListenerclassName="org.apache.catalina.core.JreMemoryLeakPreventionListener"/>
- <ListenerclassName="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener"/>
- <ListenerclassName="org.apache.catalina.core.ThreadLocalLeakPreventionListener"/>
- <GlobalNamingResources>
- <Resourcename="UserDatabase"auth="Container"
- type="org.apache.catalina.UserDatabase"
- description="User database that can be updated and saved"
- factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
- pathname="conf/tomcat-users.xml"/>
- </GlobalNamingResources>
- <Servicename="Catalina">
- <!--The connectors can use a shared executor, you can define one or more named thread pools-->
- <Executorname="tomcatThreadPool"
- namePrefix="catalina-exec-"
- maxThreads="1500"
- minSpareThreads="50"/>
- <!-- A "Connector" represents an endpoint by which requests are received
- and responses are returned. Documentation at :
- Java HTTP Connector: /docs/config/http.html
- Java AJP Connector: /docs/config/ajp.html
- APR (HTTP/AJP) Connector: /docs/apr.html
- Define a non-SSL/TLS HTTP/1.1 Connector on port 8080-->
- <ConnectorURIEncoding="UTF-8"executor="tomcatThreadPool"
- asyncTimeout="900000"
- maxConnections="40000"
- port="${http.port}"
- server="nginx"
- protocol="org.apache.coyote.http11.Http11Nio2Protocol"
- enableLookups="false"
- maxKeepAliveRequests="20"
- connectionTimeout="40000"
- acceptCount="200"
- maxThreads="20000"
- disableUploadTimeout="true"
- redirectPort="{https.port}"/>
- <ConnectorURIEncoding="UTF-8"executor="tomcatThreadPool"
- asyncTimeout="900000"
- maxConnections="40000"
- port="${ajp.port}"
- protocol="org.apache.coyote.ajp.AjpNio2Protocol"
- enableLookups="false"
- maxKeepAliveRequests="20"
- connectionTimeout="40000"
- acceptCount="200"
- maxThreads="20000"
- disableUploadTimeout="true"
- redirectPort="{https.port}"/>
- <Enginename="Catalina"
- defaultHost="localhost">
- <RealmclassName="org.apache.catalina.realm.UserDatabaseRealm"
- resourceName="UserDatabase"/>
- <Hostname="localhost"appBase="webapps"
- unpackWARs="false"autoDeploy="false"
- xmlValidation="false"xmlNamespaceAware="false">
- <ValveclassName="org.apache.catalina.valves.AccessLogValve"directory="logs"
- prefix="access."suffix=".log"pattern="%h %l %u %t %r %s %b %D"resolveHosts="false"/>
- </Host>
- </Engine>
- </Service>
- </Server>
說明:
1、tomcat8 nio最大連線數配置
使用maxConnections,預設10000。
2、JVM的GC日誌的主要引數
-XX:+PrintGC 輸出GC日誌
-XX:+PrintGCDetails 輸出GC的詳細日誌
-XX:+PrintGCTimeStamps 輸出GC的時間戳(以基準時間的形式)
-XX:+PrintGCDateStamps 輸出GC的時間戳(以日期的形式,如 2013-05-04T21:53:59.234+0800)
-XX:+PrintHeapAtGC 在進行GC的前後打印出堆的資訊
-XX:+PrintGCApplicationStoppedTime // 輸出GC造成應用暫停的時間
-Xloggc:../logs/gc.log 日誌檔案的輸出路徑
-XX:+HeapDumpOnOutOfMemoryError //發生OOM的時候自動dump堆疊方便分析
3、如何看垃圾收集策略
jmap -heap 其他:jmap -clstats
4、如何實時看堆記憶體的使用情況
jstat -gcutil [pid] [interval] //實時列印gc情況以及各代記憶體佔用比例
常用命令
jstat -gcutil -h10 vmid1000
統計gc資訊統計
S0 — Heap上的 Survivor space 0 區已使用空間的百分比
S1 — Heap上的 Survivor space 1 區已使用空間的百分比
E — Heap上的 Eden space 區已使用空間的百分比
O — Heap上的 Old space 區已使用空間的百分比
M — 元資料區已使用空間的百分比
YGC — 從應用程式啟動到取樣時發生 Young GC 的次數
YGCT– 從應用程式啟動到取樣時 Young GC 所用的時間(單位秒)
FGC — 從應用程式啟動到取樣時發生 Full GC 的次數
FGCT– 從應用程式啟動到取樣時 Full GC 所用的時間(單位秒)
GCT — 從應用程式啟動到取樣時用於垃圾回收的總時間(單位秒)
jmap -dump:format=b,file=f1 //dump記憶體到二進位制檔案
jmap -histo [pid] //按佔大小倒序列出記憶體中的例項型別
- jstat –options參看可選的option:
- -class//檢視類載入情況的統計
- -compiler //檢視HotSpot中即時編譯器編譯情況的統計
- -gc
- -gccapacity //新生代、老生代及持久代的儲存容量情況
- -gccause
- -gcmetacapacity //檢視元資料區的容量
- -gcnew //新生代垃圾收集的情況
- -gcnewcapacity //新生代的儲存容量情況
- -gcold
- -gcoldcapacity
- -gcutil
- -printcompilation // HotSpot編譯方法的統計
5、如何檢視執行緒棧
jstack 程序PID
這樣可以列出當前pid對應jvm的所有執行緒棧描述,描述主要包括了每個執行緒的狀態以及堆疊內各棧幀的方法全限定名,程式碼位置。注意這只是為了可閱讀性,並不是說棧裡存著的就是這些字串。
6、JVM記憶體模型三區域
執行緒棧區—它壓入的每個棧幀(Stack Frame)是程式指令以及區域性變量表,每個方法呼叫對應一個棧幀。區域性變量表包括各種基本資料型別:boolean、byte、char、short、int、float、long、double以及物件的引用。我們需要注意到每個執行緒都有獨立的棧並且是互相隔離的。
JAVA堆區—是被所有執行緒共享的一塊記憶體區域,在虛擬機器啟動時建立。此記憶體區域的唯一目的就是存放物件例項,幾乎所有的物件例項都在這裡分配記憶體。
靜態方法區—又稱為永久代(Perm Generation)。它用於儲存已被虛擬機器載入的類資訊、常量、靜態變數、即時編譯器編譯後的程式碼等資料。常見的JVM配置包括:-XX:MaxPermSize=512m(JDK8中移除了),JDK8中用metaspace代替permsize,因此在許多我們設定permsize大小的地方需要修改配置為metaspace
將-XX:PermSize=xxm;-XX:MaxPermSize=yym;修改為:-XX:MetaspaceSize=xxm;-XX:MaxMetaspaceSize=yym;
JDK 8的HotSpot JVM現在使用的是本地記憶體來表示類的元資料,這個區域就叫做元空間。
- 元空間的特點:
- 充分利用了Java語言規範中的好處:類及相關的元資料的生命週期與類載入器的一致。
- 每個載入器有專門的儲存空間
- 只進行線性分配
- 不會單獨回收某個類
- 省掉了GC掃描及壓縮的時間
- 元空間裡的物件的位置是固定的
- 如果GC發現某個類載入器不再存活了,會把相關的空間整個回收掉
- 元空間的記憶體分配模型:
- 絕大多數的類元資料的空間都從本地記憶體中分配
- 用來描述類元資料的類也被刪除了
- 分元資料分配了多個虛擬記憶體空間
- 給每個類載入器分配一個記憶體塊的列表。塊的大小取決於類載入器的型別; sun/反射/代理對應的類載入器的塊會小一些
- 歸還記憶體塊,釋放記憶體塊列表
- 一旦元空間的資料被清空了,虛擬記憶體的空間會被回收掉
- 減少碎片的策略
元空間的調優:
使用-XX:MaxMetaspaceSize引數可以設定元空間的最大值,預設是沒有上限的,也就是說你的系統記憶體上限是多少它就是多少。-XX:MetaspaceSize選項指定的是元空間的初始大小,如果沒有指定的話,元空間會根據應用程式執行時的需要動態地調整大小。
MaxMetaspaceSize的調優
-XX:MaxMetaspaceSize={unlimited}
元空間的大小受限於你機器的記憶體
限制類的元資料使用的記憶體大小,以免出現虛擬記憶體切換以及本地記憶體分配失敗。如果懷疑有類載入器出現洩露,應當使用這個引數;32位機器上,如果地址空間可能會被耗盡,也應當設定這個引數。
元空間的初始大小是21M——這是GC的初始的高水位線,超過這個大小會進行Full GC來進行類的回收。
如果啟動後GC過於頻繁,請將該值設定得大一些
可以設定成和持久代一樣的大小,以便推遲GC的執行時間
使用-XX:MaxMetaspaceSize引數可以設定元空間的最大值,預設是沒有上限的,也就是說你的系統記憶體上限是多少它就是多少。-XX:MetaspaceSize選項指定的是元空間的初始大小,如果沒有指定的話,元空間會根據應用程式執行時的需要動態地調整大小。
MaxMetaspaceSize的調優
-XX:MaxMetaspaceSize={unlimited}
元空間的大小受限於你機器的記憶體
限制類的元資料使用的記憶體大小,以免出現虛擬記憶體切換以及本地記憶體分配失敗。如果懷疑有類載入器出現洩露,應當使用這個引數;32位機器上,如果地址空間可能會被耗盡,也應當設定這個引數。
元空間的初始大小是21M——這是GC的初始的高水位線,超過這個大小會進行Full GC來進行類的回收。
如果啟動後GC過於頻繁,請將該值設定得大一些
可以設定成和持久代一樣的大小,以便推遲GC的執行時間。
7、堆劃分為新生代和老年代
然後新生代又可以劃分為一個Eden區和兩個Survivor(倖存)區。
按照規定,新物件會首先分配在Eden中(如果物件過大,比如大陣列,將會直接放到老年代)。在GC中,Eden中的物件會被移動到survivor中,直至物件滿足一定的年紀(定義為熬過minor GC的次數),會被移動到老年代。
新生代 ( Young )與老年代 ( Old ) 的比例的值為 1:2 ( 該值可以通過引數 –XX:NewRatio 來指定 )
預設的,Eden : from : to = 8 : 1 : 1 ( 可以通過引數 –XX:SurvivorRatio 來設定 ),
即: Eden = 8/10 的新生代空間大小,from = to = 1/10 的新生代空間大小。
8、關於晉升到老年代的條件
物件有兩種可能會進入old區:
存活物件過多。在s1和s2都已經溢位了。如果從eden遷往survior區時,發現放不下,則直接進入old Gen
從eden到s區來回拷貝次數達到一定的數量,總沒有回收掉,進入old區。(從eden到survior1遷到,引用持有中,s1中放不下新遷物件,則清理s1,存活物件,晉升入s2;再下次或繼續遷移,就把s2中的。準備說,可能是,這些個物件從s1<->s2來回拷貝一定次數後,會進入old Gen)。這塊Servivor Space 調整合適的存活次數 Threshold 通過-XX:MaxTenuringThreshold。但也只是一個建議,最終仍由虛擬機器決定。
9、併發數引數優化
執行緒數限制併發數
1)、系統最大執行緒數:
/proc/sys/kernel/threads-max 與 /proc/sys/vm/max_map_count 定義了總的最大執行緒數
mmap這個system_call的最大數量(也就是從記憶體方面限制了執行緒數)
2)、理論上我們能分配給執行緒的記憶體除以單個執行緒佔用的記憶體就是最大執行緒數。所以說對Java程序來講,既然分配給了堆,棧和靜態方法區(或叫永久代,perm區),我們可以大致認為:
執行緒數 = (系統空閒記憶體-堆記憶體(-Xms, -Xmx)- perm區記憶體(-XX:MaxPermSize)) / 執行緒棧大小(-Xss)
注意這只是幫助我們樹立一個概念,實際上還有許多因素影響。
棧的大小還影響到一個就是如果單個棧超過了這個大小,就會丟擲StackOverflowError,一般來說遞迴呼叫是常見的原因。