一千個人眼中就有一千個哈姆雷特。——僞西方諺語
關於Tomcat
的優化點之多,我估計沒有上萬,也有成千。不同的應用場景,不同的架構,不同的需求,都會對優化設置有不同要求。在這裏我所記述的只是我自己在一些Tomcat
應用中所設置的優化項,以備不時之需,並不是放之四海而皆準的準則。
pom.xml
對於maven
項目來說,pom.xml
設置是整個設置的核心,如果pom.xml
設置不當,雖然有時候也可以編譯運行,但總是會出現一些令人討厭的警告。爲了消除這些警告,還需要根治pom.xml
。
重複依賴
首先要解決的是重複依賴問題,有時候我們會在編譯項目時遇到下面的這樣的警告:
[WARNING]
[WARNING] Some problems were encountered while building the effective model for com.qiban.supplier:saas-supplier:war:1.0-SNAPSHOT
[WARNING] 'dependencies.dependency.(groupId:artifactId:type:classifier)' must be unique: commons-codec:commons-codec:jar -> duplicate declaration of version 1.9 @ line 264, column 21
[WARNING]
[WARNING] It is highly recommended to fix these problems because they threaten the stability of your build.
[WARNING]
[WARNING] For this reason, future Maven versions might no longer support building such malformed projects.
[WARNING]
解決的方法很簡單:在pom.xml
中搜索出現重複依賴的jar
包名稱,你肯定會發現對於同一個jar
包,重複引用了多次,也許版本相同,也許版本不同,只要刪除掉那些重複的就可以了。
maven編譯器版本
有時候會遇到下面這樣的錯誤:
[WARNING]
[WARNING] Some problems were encountered while building the effective model for com.qiban.supplier:saas-supplier:war:1.0-SNAPSHOT
[WARNING] 'build.plugins.plugin.version' for org.apache.maven.plugins:maven-compiler-plugin is missing. @ line 297, column 21
[WARNING]
[WARNING] It is highly recommended to fix these problems because they threaten the stability of your build.
[WARNING]
[WARNING] For this reason, future Maven versions might no longer support building such malformed projects.
[WARNING]
這意思是說你沒有在pom.xml
裏指定maven
的版本,在pom.xml
裏添加maven
的版本就可以了:
<build>
<finalName>saas-supplier</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
重點是上面那個<version>3.5.1</version>
。
jdom
有的時候會遇到一行簡單的警告:
[WARNING] The artifact jdom:jdom:jar:1.1 has been relocated to org.jdom:jdom:jar:1.1
這個的意思是說在你的pom.xml
裏,你需要把jdom
的groupId
改爲org.jdom
:
<dependency>
<groupId>org.jdom</groupId>
<artifactId>jdom</artifactId>
<version>1.1</version>
</dependency>
activemq-spring
下面這個警告不會在編譯時出現,但是會在運行時出現,也非常噁心:
SLF4J: Class path contains multiple SLF4J bindings
我們需要把pom.xml
裏的activemq-all
改成activemq-spring
:
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-spring</artifactId>
<version>5.11.1</version>
</dependency>
詳細解釋可以看我的這篇文章。
log4j.properties
終於改完了pom.xml
,我們開始處理log4j。
xmemcached
如果你使用了xmemcached
,那麼日誌裏會不斷地出現xmemcached
的警告,而這些警告對我們來說根本就不是警告,毫無意義,並且會掩蓋真正的錯誤,所以我們通過修改log4j.properties
文件屏蔽它:
# xmemcached
log4j.logger.com.google.code=OFF
log4j.logger.net.rubyeye.xmemcached=OFF
我這裏比較野蠻粗暴地直接使用了OFF
選項,如果你不放心,可以改成ERROR
選項,效果是一樣的。
webapp名稱+%c
如果你有多個webapp
,爲了準確顯示到底是哪個webapp
的哪個class
報的錯,我們需要在log4j.properties
文件裏註明我們的webapp
名稱,再加上一個%c符號:
log4j.appender.STDOUT.layout.ConversionPattern=[%d{yyyy-MM-dd HH:mm:ss}] %-5p - activity - %c - %m%n
這樣下回再有任何錯誤,我們可以第一時間迅速定位到到底是哪個webapp
的哪個class
出的錯誤。
logrotate
如果我們不管不顧的話,Tomcat
的日誌文件幾乎會無限制增長,最終會耗盡我們的硬盤空間,所以我們需要用logrotate
來限制它一下,在/etc/logrotate.d
文件夾下創建一個文件tomcat
:
/opt/tomcat1/logs/catalina.out
/opt/tomcat2/logs/catalina.out
{
copytruncate
daily
rotate 7
compress
missingok
size 10M
}
setenv.sh
Tomcat
不問青紅皁白,上來就要佔領我們主機整個物理內存的四分之一,我們需要限制它的大小,寧可浪費一些CPU
和硬盤的時間去讓它不斷地垃圾回收,也不想讓它佔用這麼多的內存,所以我們需要在/opt/tomcat/bin
下建立一個setenv.sh
文件,強制讓它最多佔用1G
內存:
export CATALINA_OPTS="$CATALINA_OPTS -Xms512m"
export CATALINA_OPTS="$CATALINA_OPTS -Xmx1024m"
這樣我們一臺16G
內存的主機,可以同時運行16
個Tomcat
,而不像以前,最多隻能同時運行4
個Tomcat
。
jarsToSkip
Tomcat
啓動時會不斷地掃描所有.jar
文件,並且報一些不知所謂的警告:
09-Dec-2017 20:03:14.289 FINE [localhost-startStop-1] org.apache.jasper.servlet.TldScanner$TldScannerCallback.scan No TLD files were found in [file:/home/apache-tomcat-8.5.4/lib/tomcat-redis-session-manager-master-2.0.0.jar]. Consider adding the JAR to the tomcat.util.scan.StandardJarScanFilter.jarsToSkip property in CATALINA_BASE/conf/catalina.properties file.
直接在/opt/tomcat/conf/catalina.properties
文件裏把這一句話改成:
tomcat.util.scan.StandardJarScanFilter.jarsToSkip=*.jar
這個世界終於清靜了,掃什麼掃,有什麼可掃的!
startStopThreads
當你有多個webapp
的時候,Tomcat
缺省會啓完一個webapp
再啓下一個,這樣太慢了,不可忍受,我們在/opt/tomcat/conf/server.xml
文件裏把它的啓動線程數直接幹到20
個:
<Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true" startStopThreads="20" />
Dubbo
有時候Dubbo
也會跳出來搗亂,在每一個不同的webapp
下的consumer.xml
文件裏指定file
:
<dubbo:registry address="zookeeper://${zookeeper.address}" file="${dubbo.cache}" />
每個webapp
的file
名稱各不相同,它們再也不會互相打架了。
結語
以上所述也不過只是冰山之一角,好記性不如爛筆頭,記錄下來作爲以後每次優化時的依據,也許對遇到類似問題的你也略有啓發吧。