tomcat/bin/setenv.sh 用於tomcat啟動的參數配置(當前目錄下,會在tomcat啟動時自動調用)
cat tomcat/bin/catalina.sh
if [ -r "$SETENVPATH/bin/setenv.sh" ]; then
. "$SETENVPATH/bin/setenv.sh"
elif [ -r "$CATALINA_HOME/bin/setenv.sh" ]; then
. "$CATALINA_HOME/bin/setenv.sh"
fi
cat tomcat/bin/setenv.sh
#!/bin/sh
export CATALINA_OPTS="-Xmx350M -Xms350M -XX:PermSize=64M -XX:MaxPermSize=64m -XX:+UseParallelGC -Dlog4j.configuration=file:///home/www/config/java/scheduler_log4j.xml"
export CATALINA_PID="$CATALINA_BASE/logs/catalina.pid"
............
--------------------------------------------------------------------------
1、Apache Tomcat6 中支持了Java語言的特性 NIO( New I/O),使用NIO在服務器端會有更好的性能,加強服務器端對並發處理的性能。但是,在tomcat6在默認的配置選項中是沒有把NIO功能打開。在tomcat的配置文件conf/server.xml中,找到以下配置:
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
在控制台的啟動信息里看見,默認狀態下 沒有被打開nio配置,啟動時的信息,如下:
2010-2-1 12:59:40 org.apache.coyote.http11.Http11Protocol init
信息: Initializing Coyote HTTP/1.1 on http-8080
2010-2-1 12:59:40 org.apache.catalina.startup.Catalina load
修改成支持NIO的類型,配置如下 :
<Connector port="8080" protocol="org.apache.coyote.http11.Http11NioProtocol "
connectionTimeout="20000"
redirectPort="8443" />
進行測試,被打開nio配置,啟動時的信息,如下:
2010-2-1 13:01:01 org.apache.tomcat.util.net.NioSelectorPool getSharedSelector
信息: Using a shared selector for servlet write/read
2010-2-1 13:01:01 org.apache.coyote.http11.Http11NioProtocol init
信息: Initializing Coyote HTTP/1.1 on http-8080
2、JAVA虛擬機性能優化
Tomcat本身不能直接在計算機上運行,需要依賴於硬件基礎之上的操作系統和一個java虛擬機。可以根據自己的需要選擇不同的操作系統和對應的JDK版本(只要是符合Sun發布的Java規范的),推薦使用Sun公司發布的JDK。確保所使用的版本是最新的,因為Sun公司和其它一些公司一直在為提高性能而對java虛擬機做一些升級改進。一些報告顯示JDK1.4在性能上比JDK1.3提高了將近10%到20%。
可以給Java虛擬機設置使用的內存,但是如果選擇不對的話,虛擬機不會補償。可通過命令行的方式改變虛擬機使用內存的大小。
-Xms<size> 表示JVM初始化堆的大小,-Xmx<size>表示JVM堆的最大值。一般建議堆的最大值設置為可用內存的最大值的80%,並將-Xms和-Xmx選項設置為相同。
堆內存分配
JVM初始分配的內存由-Xms指定,默認是物理內存的1/64;JVM最大分配的內存由-Xmx指定,默認是物理內存的1/4。默認空余堆內存小於40%時,JVM就會增大堆直到-Xmx的最大限制;空余堆內存大於70%時,JVM會減少堆直到-Xms的最小限制。因此服務器一般設置-Xms、-Xmx相等避免在每次GC 后調整堆的大小。
非堆內存分配
JVM使用-XX:PermSize設置非堆內存初始值,默認是物理內存的1/64;由XX:MaxPermSize設置最大非堆內存的大小,默認是物理內存的1/4。
JVM內存限制(最大值)
首先JVM內存限制於實際的最大物理內存,假設物理內存無限大的話,JVM內存的最大值跟操作系統有很大的關系。簡單的說就32位處理器雖然可控內存空間有4GB,但是具體的操作系統會給一個限制,這個限制一般是2GB-3GB(一般來說Windows系統下為1.5G-2G,Linux系統下為2G-3G),而64bit以上的處理器就不會有限制了。
JAVA_OPTS="-server -Xms2048M -Xmx2048M -Xss256k -XX:+AggressiveOpts -XX:+UseParallelGC-XX:+UseBiasedLocking"
配置示例:JAVA_OPTS="-server -XX:PermSize=128M -XX:MaxPermSize=256M -XX:MaxNewSize=256M"
JAVA_OPTS="$JAVA_OPTS -Xms2048M -Xmx2048M -Xss128K"
修改apache-tomcat-6.0.18\bin\catalina.bat(catalina.sh)配置文件為以下:
set JAVA_OPTS=-Xms1024m -Xmx1024m -XX:PermSize=128M -XX:MaxPermSize=256m
這一句加在
rem ---------------------------------------------------------------------------
與
rem Guess CATALINA_HOME if not defined
之間的位置,不要加到那些if里面去了,否則不一定會生效。
3、停用DNS查詢
當web應用程序向要記錄客戶端的信息時,它也會記錄客戶端的IP地址或者通過域名服務器查找機器名轉換為IP地址。
DNS查詢需要占用網絡,並且包括可能從很多很遠的服務器或者不起作用的服務器上去獲取對應的IP的過程,這樣會消耗一定的時間。
修改server.xml文件中的enableLookups參數值: enableLookups="false"
<Connector
port="8887" maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
enableLookups="false" redirectPort="8443" acceptCount="100"
debug="0" connectionTimeout="20000"
disableUploadTimeout="true" />
加上enableLookups="false";這樣就不使用DNS查詢,也不會有延遲了。除非需要所有連接到服務器的HTTP客戶端的完整主機名稱。
注:Connector的enableLookups性屬的意義是:調用request.getRemoteHost()是否會通過DNS查詢來取得遠處客戶端的真正主機名稱。true表示會查詢,false表示以字符串格式傳回客戶端的IP地址。默認值是:true。
4、調整線程的數目
通過應用程序的連接器(Connector)進行性能控制的的參數是創建的處理請求的線程數。
Tomcat使用線程池加速響應速度來處理請求。在Java中線程是程序運行時的路徑,是在一個程序中與其它控制線程無關的、能夠獨立運行的代碼段。它們共享相同的地址空間。多線程幫助程序員寫出CPU最大利用率的高效程序,使空閑時間保持最低,從而接受更多的請求。
示例如下:
<Connector port="80" protocol="HTTP/1.1"
maxThreads="600" 最多運行線程數,默認值為200
minSpareThreads="100" 初始化創建的線程數
maxSpareThreads="500"最多能創建的線程數,一旦創建的線程超過這個值,Tomcat就會關閉不再需要socket線程.
acceptCount="700" 指定當所有可以使用的處理請求的線程數都被使用時可以放到處理隊列中的請求數,超過這個數的請求將不予處理,默認值為100
connectionTimeout="20000"
enableLookups="false"
redirectPort="8443" />
5、Tomcat6線程池(Executor Thread pool)的配置
第一步,打開共享的線程池
<Executor name="tomcatThreadPool" namePrefix="catalina-exec-"
maxThreads="1000" minSpareThreads="50" maxIdleTime="600000"/>
name 這個是線程池的名字,必須唯一,后面的配置里要用到這個東西
namePrefix 線程的名字前綴,用來標記線程名字,每個線程就用這個前綴加上線程編號了,比如
catalina-exec-1
catalina-exec-2
maxThreads 允許的最大線程池里的線程數量,默認是200,大的並發應該設置的高一些,只是限制而已,不占用資源。
minSpareThreads 最小的保持活躍的線程數量,默認是25.
要根據負載情況自行調整了:太小影響反應速度,太大占用資源。
maxIdleTime 超過最小活躍線程數量的線程,空閑時間超過這個設置后,會被關閉,默認是1分鍾。
threadPriority 線程的等級。默認是Thread.NORM_PRIORITY
第二步 在Connector里指定使用共享線程池
<Connector port="8009" ... maxThreads="5000" executor="tomcatThreadPool" ... />
注意,一旦使用了線程池,則其它的線程屬性,比如 maxThreads等將被忽略
6.在tomcat中設置session過期時間
在\conf\web.xml中通過參數指定:
<session-config>
<session-timeout>180</session-timeout>
</session-config> 單位為分鍾。
tomcat容器調優詳參:
vim $CATALINA_HOME/conf/server.xml
...
<Connector port="8080" protocol="HTTP/1.1"
URIEncoding="UTF-8" minSpareThreads="25" maxSpareThreads="75"
enableLookups="false" disableUploadTimeout="true" connectionTimeout="20000"
acceptCount="500" maxThreads="300"
useURIValidationHack="false"
compression="on" compressionMinSize="2048"
compressableMimeType="text/html,text/xml,text/javascript,text/css,text/plain"
redirectPort="8443"
/>
...
【注釋】
URIEncoding:URI編碼,這里參數是UTF-8,很容易理解,即支持中文域名
minSpareThreads:最小空閑線程,即tomcat可以保留的最小線程
maxSpareThreads:最大空閑進程,如果超出這個參數,則會被回收
(這兩個參數根據實際環境而定,如果每天都有一個並發爆發期,則最好min設置的大一些)
enableLookups:是否開啟域名解析,這個一般都禁止,域名解析影響性能
disableUploadTimeout:
connectionTimeout:連接超時時間,單位是ms,根據程序性能決定
maxThreads:同一時刻可以接收的最大請求,即並發量
acceptCount:若超出maxThreads,則超出部分不能超過此參數值,若超過,則拒絕
useURIValidationHack:設置為false可以減少tomcat對一些url的不必要的檢查從而減省開銷【不明覺厲】
compression:是否啟用壓縮,肯定啟用了
compressionMinSize:壓縮文件大小下限,單位字節
compressableMimeType:壓縮文件的Mime類型
redirectPort:重定向(因此若為443https,則8443 connector也應該加入以上參數)
jvm調優
vim $CATALINA_HOME/bin/catalina.sh
...
export JAVA_OPTS="-server -Xms8192M -Xmx8192M -Xmn3072M -Xss512k -XX:+AggressiveOpts -XX:+UseBiasedLocking -XX:PermSize=256M -XX:MaxPermSize=4096M -XX:+DisableExplicitGC -XX:MaxTenuringThreshold=31 -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:+CMSParallelRemarkEnabled -XX:+UseCMSCompactAtFullCollection -XX:LargePageSizeInBytes=128m -XX:+UseFastAccessorMethods -XX:+UseCMSInitiatingOccupancyOnly -Djava.awt.headless=true"
...
【注釋信息】
jvm調優其實就是在catalina啟動時臨時加上JAVA_OPTS變量值的。
-server:意思就是將tomcat改為生產模式,這個看網上說明,不加的話,就如同實驗環境一樣。因此,必加參數
-Xms:jvm最小堆內存
-Xmx:jvm最大堆內存
這兩個值的差值叫做保留內存,不過建議最好設置的一樣,即最小內存隨同最大內存,之所以這么設置是因為,內存回收的時候,也是需要消耗cpu的,如果此時突然並發又來了,而tomcat卻在回收內存,那么就不爽了
-Xmn:新生態內存,這個官方建議是jvm堆內存的3/8,堆內存=新生內存+老年內存+持久內存
-Xss:設定每個線程的堆棧大小
-XX:+AggressiveOpts:作用如其名(aggressive),啟用這個參數,則每當JDK版本升級時,你的JVM都會使用最新加入的優化技術
-XX:+UseBiasedLocking:啟用一個優化了的線程鎖,我們知道在我們的appserver,每個http請求就是一個線程,有的請求短有的請求長,就會有請求排隊的現象,甚至還會出現線程阻塞,這個優化了的線程鎖使得你的appserver內對線程處理自動進行最優調配。
-XX:PermSize:持久態最小內存,默認為物理內存大小的1/64
-XX:MaxPermSize:持久態最大內存,默認為物理內存大小的1/4
-XX:+DisableExplicitGC:在程序代碼中不允許有顯示的調用”System.gc()”,【不明覺厲】
-XX:MaxTenuringThreshold:設置對象在年輕態停留的時間,時間越長,被回收概率越大,若為0,則直接轉到老年態
-XX:+UseConcMarkSweepGC:CMS gc,這一特性只有jdk1.5即后續版本才具有的功能,它使用的是gc估算觸發和heap占用觸發。
我們知道頻頻繁的GC會造面JVM的大起大落從而影響到系統的效率,因此使用了CMS GC后可以在GC次數增多的情況下,每次GC的響應時間卻很短,比如說使用了CMS GC后經過jprofiler的觀察,GC被觸發次數非常多,而每次GC耗時僅為幾毫秒。【不明覺厲】
-XX:+UseParNewGC:年輕代采用多線程並行回收,加速回收
-XX:+CMSParallelRemarkEnabled:在使用UseParNewGC 的情況下, 盡量減少 mark 的時間【不明覺厲】
-XX:+UseCMSCompactAtFullCollection:在使用concurrent gc 的情況下, 防止 memoryfragmention, 對live object 進行整理, 使 memory 碎片減少【不知道啥意思】
-XX:LargePageSizeInBytes:指定 Java heap的分頁頁面大小
-XX:+UseFastAccessorMethods:get,set 方法轉成本地代碼【不知道啥意思】
-XX:+UseCMSInitiatingOccupancyOnly:指示只有在 oldgeneration 在使用了初始化的比例后concurrent collector 啟動收集【不知道啥意思】
-Djava.awt.headless=true":這個參數一般我們都是放在最后使用的,這全參數的作用是這樣的,有時我們會在我們的J2EE工程中使用一些圖表工具如:jfreechart,用於在 web網頁輸出GIF/JPG等流,在winodws環境下,一般我們的app server在輸出圖形時不會碰到什么問題,但是在linux/unix環境下經常會碰到一個exception導致你在winodws開發環境下圖片顯 示的好好可是在linux/unix下卻顯示不出來,因此加上這個參數以免避這樣的情況出現。【雖然知道結果,就是不知道因在何處】
server.xml示例文件:

<?xml version='1.0' encoding='utf-8'?> <Server port="8123" shutdown="SHUTDOWN"> <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" /> <Listener className="org.apache.catalina.core.JasperListener" /> <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" /> <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" /> <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" /> <GlobalNamingResources> <Resource name="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> <Service name="Catalina"> <Executor name="tomcatThreadPool" namePrefix="catalina-exec-" maxThreads="2000" minSpareThreads="500"/> <!-- <Connector port="9095" protocol="org.apache.coyote.http11.Http11NioProtocol" connectionTimeout="20000" maxThreads="512" minSpareThreads="25" acceptCount="512" disableUploadTimeout="true" enableLookups="false" URIEncoding="UTF-8" redirectPort="9444" /> --> <Connector port="8080" protocol="org.apache.coyote.http11.Http11NioProtocol" executor="tomcatThreadPool" compression="on" compressionMinSize="2048" enableLookups="false" redirectPort="8443" acceptCount="4000" connectionTimeout="20000" disableUploadTimeout="true" URIEncoding="UTF-8" useBodyEncodingForURI="true" /> <!-- A "Connector" using the shared thread pool--> <!-- <Connector executor="tomcatThreadPool" port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" /> --> <!-- Define a SSL HTTP/1.1 Connector on port 8443 This connector uses the JSSE configuration, when using APR, the connector should be using the OpenSSL style configuration described in the APR documentation --> <!-- <Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true" maxThreads="150" scheme="https" secure="true" clientAuth="false" sslProtocol="TLS" /> --> <!-- Define an AJP 1.3 Connector on port 8009 --> <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" /> <!-- An Engine represents the entry point (within Catalina) that processes every request. The Engine implementation for Tomcat stand alone analyzes the HTTP headers included with the request, and passes them on to the appropriate Host (virtual host). Documentation at /docs/config/engine.html --> <!-- You should set jvmRoute to support load-balancing via AJP ie : <Engine name="Catalina" defaultHost="localhost" jvmRoute="jvm1"> --> <Engine name="Catalina" defaultHost="localhost"> <!--For clustering, please take a look at documentation at: /docs/cluster-howto.html (simple how to) /docs/config/cluster.html (reference documentation) --> <!-- <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/> --> <!-- Use the LockOutRealm to prevent attempts to guess user passwords via a brute-force attack --> <Realm className="org.apache.catalina.realm.LockOutRealm"> <!-- This Realm uses the UserDatabase configured in the global JNDI resources under the key "UserDatabase". Any edits that are performed against this UserDatabase are immediately available for use by the Realm. --> <Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase"/> </Realm> <Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true"> <!-- SingleSignOn valve, share authentication between web applications Documentation at: /docs/config/valve.html --> <!-- <Valve className="org.apache.catalina.authenticator.SingleSignOn" /> --> <!-- Access log processes all example. Documentation at: /docs/config/valve.html Note: The pattern used is equivalent to using pattern="common" <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="localhost_access_log." suffix=".txt" pattern="%h %l %u %t "%r" %s %b request_time %D msec %T status %s" resolveHosts="false"/>--> </Host> </Engine> </Service> </Server>