tomcat-tunning
書寫目的
Tomcat為我司短信平臺標準服務器,為了規范安裝步驟、優化性能以及安全加固的相關配置,特制訂以下規范。
?
1??????Tomcat性能優化
1.1???? JVM的優化
Tomcat的啟動參數位于Tomcat的安裝目錄\bin目錄下,如果你是Linux操作系統就是catalina.sh文件,如果你是Windows操作系統那么你需要改動的就是catalina.bat文件。本文以linux環境為例來講解,打開該文件,一般該文件頭部是一堆的由##包裹著的注釋文字,找到注釋文字的最后一段。
加入如下的參數:
export JAVA_OPTS="-server -Xms1400M -Xmx1400M-Xss512k
-XX:+AggressiveOpts -XX:+UseBiasedLocking-XX:PermSize=128M -XX:MaxPermSize=256M -XX:+DisableExplicitGC -XX:MaxTenuringThreshold=31
-XX:+UseConcMarkSweepGC -XX:+UseParNewGC-XX:+CMSParallelRemarkEnabled -XX:+UseCMSCompactAtFullCollection-XX:LargePageSizeInBytes=128m
-XX:+UseFastAccessorMethods-XX:+UseCMSInitiatingOccupancyOnly -Djava.awt.headless=true "
?
?
?
各個參數的簡單解釋以及個別參數的獲得辦法:
1.1.1???? -server
Tomcat以server模式運行時將擁有:更大、更高的并發處理能力,更快更強捷的JVM垃圾回收機制,可以獲得更多的負載與吞吐量。
1.1.2???? -Xms–Xmx
把Xms與Xmx兩個值設成一樣是最優的做法,而且設置為最大化參數。獲得最大參數具體值的方法:在設這個最大內存即Xmx值時請先打開一個命令行,鍵入如下的命令:
如果是在32位系統下,我們試試2G內存行不行:
試試1700m
?
連1700m都不可以,更不要說2048m了,2048m只是一個理論數值。這個跟機器也有關,有的能到1700m。
1.1.3???? -Xss
是指設定每個線程的堆棧大小。這個就要依據你的程序,看一個線程大約需要占用多少內存,可能會有多少線程同時運行等。一般不易設置超過1M,要不然容易出現outofmemory。
1.1.4? -XX:+AggressiveOpts
啟用一個優化了的線程鎖,在我們的appServer,每個http請求就是一個線程,有的請求短有的請求長,就會有請求排隊的現象,甚至還會出現線程阻塞,這個優化了的線程鎖使得你的appServer內對線程處理自動進行最優調配。
1.1.5???? -XX:PermSize=128M-XX:MaxPermSize=256M
JVM使用-XX:PermSize設置非堆內存初始值,默認是物理內存的1/64;
在數據量的很大的文件導出時,一定要把這兩個值設置上,否則會出現內存溢出的錯誤。
由XX:MaxPermSize設置最大非堆內存的大小,默認是物理內存的1/4。
那么,如果是物理內存4GB,那么64分之一就是64MB,這就是PermSize默認值,也就是永生代內存初始大小;
四分之一是1024MB,這就是MaxPermSize默認大小。
1.1.6???? -XX:+DisableExplicitGC
在程序代碼中不允許有顯示的調用”System.gc()”。
1.1.7? -XX:+UseParNewGC
對年輕代采用多線程并行回收,這樣收得快。
1.1.8? -XX:+UseConcMarkSweepGC
即CMS GC,這一特性只有jdk1.5即后續版本才具有的功能,它使用的是GC估算觸發和heap占用觸發。使用了CMS GC后可以在GC次數增多的情況下,每次GC的響應時間卻很短。
1.1.9? -XX:MaxTenuringThreshold
如果設置為0的話,則年輕代對象不經過Survivor區,直接進入年老代。對于年老代比較多的應用,可以提高效率。
1.1.10?????????????-XX:+CMSParallelRemarkEnabled
在使用UseParNewGC 的情況下, 盡量減少mark 的時間。
1.1.11?????????????-XX:+UseCMSCompactAtFullCollection
在使用concurrent gc 的情況下, 防止memoryfragmention, 對live object 進行整理, 使 memory 碎片減少。
1.1.12?????????????-XX:LargePageSizeInBytes
指定 Java heap的分頁頁面大小。
1.1.13?????????????-XX:+UseFastAccessorMethods
get,set 方法轉成本地代碼。
1.1.14?????????????-XX:+UseCMSInitiatingOccupancyOnly
指示只有在 oldgeneration 在使用了初始化的比例后concurrentcollector 啟動收集。
-XX:CMSInitiatingOccupancyFraction=70?CMSInitiatingOccupancyFraction,這個參數設置有很大技巧,基本上滿足(Xmx-Xmn)*(100- CMSInitiatingOccupancyFraction)/100>=Xmn就不會出現promotion failed。在我的應用中Xmx是6000,Xmn是512,那么Xmx-Xmn是5488兆,也就是年老代有5488 兆,CMSInitiatingOccupancyFraction=90說明年老代到90%滿的時候開始執行對年老代的并發垃圾回收(CMS),這時還剩10%的空間是5488*10%=548兆,所以即使Xmn(也就是年輕代共512兆)里所有對象都搬到年老代里,548兆的空間也足夠了,所以只要滿足上面的公式,就不會出現垃圾回收時的promotion failed;因此這個參數的設置必須與Xmn關聯在一起。
1.1.15?????????????-Djava.awt.headless=true
這個參數一般我們都是放在最后使用的,這全參數的作用是這樣的,有時我們會在我們的J2EE工程中使用一些圖表工具如:jfreechart,用于在web網頁輸出GIF/JPG等流,在winodws環境下,一般我們的app server在輸出圖形時不會碰到什么問題,但是在linux/unix環境下經常會碰到一個exception導致你在winodws開發環境下圖片顯示的好好可是在linux/unix下卻顯示不出來,因此加上這個參數以免避這樣的情況出現。
上述這樣的配置,基本上可以達到:
1.系統響應增快
2. JVM回收速度增快同時又不影響系統的響應率
3. JVM內存最大化利用
4. 線程阻塞情況最小化
?
?
1.2?? Tomcat容器內的優化
前面對Tomcat啟動時的命令進行了優化,增加了系統的JVM可使用數、垃圾回收效率與線程阻塞情況、增加了系統響應效率等還有一個很重要的指標,我們沒有去做優化,就是吞吐量。
?
打開Tomcat安裝目錄\conf\server.xml文件,定位到這一行:
<Connectorport="8080" protocol=”HTTP/1.1” redirectPort=”8443”/> 即下圖:
這一行就是我們的Tomcat容器性能參數設置的地方,它一般都會有一個默認值,這些默認值是遠遠不夠我們的使用的,我們來看經過更改后的這一段的配置
<Connector port="8080" protocol=”HTTP/1.1”URIEncoding=”UTF-8”
maxSpareThreads=”75”minSpareThreads=”25”
enableLookups=”false”? connectionTimeout=”20000”
maxThreads=”300”acceptCount=”300”maxProcessors=”1000”minProcessors=”5”?????? useURIValidationHack=”false”? enableLookups=”false”
disableUploadTimeout=”true”compression="on"compressionMinSize="2048"?????? noCompressionUserAgents="gozilla, traviata"?????? compressableMimeType="text/html,text/xml"
redirectPort=”8443”/>
如下圖:
?
各個參數作用:
1.2.1? maxSpareThreads
空閑狀態的線程數多于設置的數目,則將這些線程中止,減少這個池中的線程總數。
1.2.2? minSpareThreads
最小備用線程數,Tomcat啟動時的初始化的線程數。
1.2.3? enableLookups
這個功效和Apache中的HostnameLookups一樣,設為關閉。
1.2.4? connectionTimeout
網絡連接超時時間毫秒數。
1.2.5? maxThreads
Tomcat使用線程來處理接收的每個請求。這個值表示Tomcat可創建的最大的線程數,即最大并發數。
1.2.6? acceptCount
當線程數達到maxThreads后,后續請求會被放入一個等待隊列,這個acceptCount是這個隊列的大小,如果這個隊列也滿了,就直接refuse connection。
1.2.7???? maxProcessors與minProcessors
在 Java中線程是程序運行時的路徑,是在一個程序中與其它控制線程無關的、能夠獨立運行的代碼段。它們共享相同的地址空間。多線程幫助程序員寫出CPU最 大利用率的高效程序,使空閑時間保持最低,從而接受更多的請求。通常Windows是1000個左右,Linux是2000個左右。
1.2.8? useURIValidationHack
useURIValidationHack設成"false",可以減少它對一些url的不必要的檢查從而減省開銷。
1.2.9? enableLookups=”false”
為了消除DNS查詢對性能的影響我們可以關閉DNS查詢。
1.2.10?????????????disableUploadTimeout
類似于Apache中的keeyalive一樣。
1.2.11? Tomcat配置gzip壓縮(HTTP壓縮)功能
compression=”on” compressionMinSize=”2048” compressableMimeType=”text/html,text/xml,text/javascript,text/css,text/plain”
HTTP 壓縮可以大大提高瀏覽網站的速度,它的原理是,在客戶端請求網頁后,從服務器端將網頁文件壓縮,再下載到客戶端,由客戶端的瀏覽器負責解壓縮并瀏覽。相對于普通的瀏覽過程HTML,CSS,Javascript , Text ,它可以節省40%左右的流量。更為重要的是,它可以對動態生成的,包括CGI、PHP , JSP , ASP ,Servlet,SHTML等輸出的網頁也能進行壓縮,壓縮效率驚人。
1)compression="on"打開壓縮功能
2)compressionMinSize="2048"啟用壓縮的輸出內容大小,這里面默認為2KB
3)noCompressionUserAgents="gozilla, traviata"對于以下的瀏覽器,不啟用壓縮
4)compressableMimeType="text/html,text/xml" 壓縮類型
最后要把8443端口的地方也加上同樣的配置,如果我們走https協議的話,我們將會用到8443端口這個段的配置,參數跟以上一樣。
Tomcat優化完成了,這樣做下來,優化過的Tomcat要比未經過優化的,性能提高20~60倍。
?
2??????Tomcat安全性配置
2.1????首次安裝完成后立即刪除webapps下面的所有代碼
rm -rf /Tomcat/webapps/*
2.2????注釋或刪除 Tomcat-users.xml 所有用戶權限,需要注釋節點如下:
# vi conf/Tomcat-users.xml
<?xml version='1.0' encoding='utf-8'?>
<Tomcat-users>
</Tomcat-users>
?
2.3????隱藏Tomcat版本信息
vim $CATALINA_HOME/conf/server.xml
?
<Connector port="80"protocol="HTTP/1.1"
??????????????connectionTimeout="20000"
??????????????redirectPort="8443"
???????????????????????????????????????????????????????????? maxThreads="8192"
???????????????????????????????????????????????????????????? minSpareThreads="64"
???????????????????????????????????????????????????????????? maxSpareThreads="128"
???????????????????????????????????????????????????????????? acceptCount="128"
???????????????????????????????????????????????????????????? enableLookups="false"
server="Neo App Srv 1.0"/>
其中紅字為添加的參數配置,“”中為修改的服務器信息,使用以下命令查看當前服務器版本信息:
# curl -I http://localhost:8080/
HTTP/1.1 400 Bad Request
Transfer-Encoding: chunked
Date: Thu, 20 Oct 2011 09:51:55 GMT
Connection: close
Server: Neo App Srv 1.0
服務器信息已經被改為Server: Neo App Srv 1.0
?
2.4????啟動用戶與端口
不要使用root用戶啟動Tomcat,Java程序與C程序不同。nginx,httpd 使用root用戶啟動守護80端口,子進程/線程會通過setuid(),setgid()兩個函數切換到普通用戶。即父進程所有者是root用戶,子進程與多線程所有者是一個非root用戶,這個用戶沒有shell,無法通過ssh與控制臺登陸系統,Java 的JVM 是與系統無關的,是建立在OS之上的,你使用什么用戶啟動Tomcat,那麼Tomcat 就會繼承該所有者的權限。
這造成了一個問題,Linux系統小于1024的端口只有root可以使用,這也是為什么Tomcat默認端口是8080。如果你想使用80端口只能使用root啟動Tomcat。這有帶來了很多安全問題。
解決辦法:
創建一個不同用戶,如:
groupadd -g 80 daemon
adduser -o --home /daemon --shell/sbin/nologin --uid 80 --gid 80 -c "Web Server" daemon
接下來解決80端口問題, 思路就是80去調用8080,或者映射端口。
?
下面是影射方案,80 跳轉 8080
iptables -t nat -A PREROUTING -p tcp --dport80 -j REDIRECT --to-port 8080
?
取消跳轉
iptables -t nat -D PREROUTING -p tcp --dport80 -j REDIRECT --to-port 8080
?
查看規則
iptables -t nat -L
另一個就是從80請求去調用8080的方案
這個方案可以在 Tomcat 前段增加反向代理,例如:Nginx,Apache,Squid,Varnish或者F5, Array這類設備等等
?
2.5????關閉war自動部署
<Host name="localhost"? appBase=""????? unpackWARs="false" autoDeploy="false">防止被植入木馬等惡意程序
應用程序部署與Tomcat啟動,不能使用同一個用戶。
我的Tomcat 安裝在 /srv目錄下,Tomcat啟動用戶為daemon; 應用程序放在/www目錄下www所有者是www用戶。這樣的目的是一旦Tomcat被植入web shell程序,它將不能創建或編輯/www目錄下面的任何內容。
adduser --home /www -c "WebApplication" www
?
2.6?????刪除管理界面(webapps下面的所有代碼已經被刪除,此項安全問題已經不大,設置上為多一層保險)
在server.xml中,在HOST容器中有一個配置,如?
???????unpackWARs="true"?
???????xmlValidation="false"xmlNamespaceAware="false">
。。。。。?
;?
將appBase=修改成你的應用所在的目錄,比如appBase=/home/mc/mobilePlat
這樣修改以后,系統自動啟動的時候就不會加載webapps中的默認程序了,包括admin和manager等,只會啟動htdocs目錄中帶xml配置參數的應用,當然如果你htdocs下面就直接是程序了,建議配置如下:?
???????unpackWARs="true"?
???????xmlValidation="false"xmlNamespaceAware="false">
2.7???? 屏蔽目錄文件自動列出的方法
??? 在Tomcat的conf/web.xml文件里把listings值改為false
如:
<servlet>
<servlet-name>default</servlet-name>
<servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
<init-param>
<param-name>debug</param-name>
<param-value>0</param-value>
</init-param>
<init-param>
<param-name>listings</param-name>
<param-value>false</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
?
2.8???? 打印訪問日志
默認情況下Tomcat并不記錄訪問日志文件(access log): Catalina/conf/server.xml;將文件中這一段的注釋去掉,然后將pattern的值改為combined ,這個模式下記錄的日志比較詳細。
???????? <!--
???????? <ValveclassName="org.apache.catalina.valves.AccessLogValve"?
?????????????????directory="logs"?? prefix="localhost_access_log."suffix=".txt"
?????????????????pattern="combined" resolveHosts="false"/>
???????? -->
重新啟動一下Tomcat
?
2.9???? 錯誤頁面
如果找不到網頁即出現404錯誤,會顯示服務器版本號,服務器配置也一目了然,為了避免這種情況,在Tomcat的web.xml文件中,根元素下配置:(自定義錯誤頁面)
<error-page>
<error-code>錯誤代碼(404....)</error-code>
<location>錯誤頁面地址</location>
</error-page>
還可以對出現的異常進行統一的錯誤處理
<error-page>
<exception-type>異常類型</exception-type>
<location>錯誤頁面地址</location>
</error-page>
2.10???????Tomcat? Session過期時間
Tomcat采用數據庫連接池技術,當用戶在一定時間不對數據庫有操作時間后,就自動關閉這個連接,這是為了更好的利用資源,防止浪費寶貴的數據庫連接資源。
可以采用如下三種方式,設置這個連接(Session)的過期時間:
修改Tomcat的配置文件conf
1)在server.xml中定義context時采用如下定義:?
xml 代碼
<Context path="/livsorder"docBase="/home/httpd/html/livsorder"???????
defaultSessionTimeOut="3600"isWARExpanded="true"???????
isWARValidated="false" isInvokerEnabled="true"???????
isWorkDirPersistent="false"/>???
3600秒=1小時
?
2)Tomcat,我在web.xml中配置了session超時的時間? 如下: <session-config> <session-timeout>30</session-timeout> </session-config> 這里是以分鐘為單位的,默認是30分; ? 3)webapp級別 在webapp中的 WEB-INF/web.xml Xml代碼?? <!--?配置Session失效時間?-->?? <session-config>?? ????????<session-timeout>30</session-timeout>?? </session-config>?? 也是以min為單位; ?2.11???????關閉服務器端口:
server.xml默認有下面一行: <Server port="8005" shutdown="SHUTDOWN"> 這樣允許任何人只要telnet到服務器的8005端口,輸入"SHUTDOWN",然后回車,服務器立即就被關掉了。 從安全的角度上考慮,我們需要把這個shutdown指令改成一個別人不容易猜測的字符串,可以同時把端口也改了。 例如修改如下: <Server port="8005" shutdown="c1gstudio"> 這樣就只有在telnet到8005,并且輸入"c1gstudio"才能夠關閉Tomcat. 注意:這個修改不影響shutdown.bat的執行。運行shutdown.bat一樣可以關閉服務器。 ? ?2.12???????OutOfMemory異常時獲取堆棧快照
1.打開/Tomcat_home/bin/catalina.sh文件? 2.加上:JAVA_OPTS="$JAVA_OPTS -server -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=D:\heapdump" 如下圖位置: ? 注:其中不設-XX:HeapDumpPath時,dump出的文件在/Tomcat_home/bin目錄下 ??
?
?
?
?
?
?
?
?
總結
以上是生活随笔為你收集整理的tomcat-tunning的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 24 碰到的一个 idea的奇怪的编码问
- 下一篇: Android FM 模块学习之四 源码