Tomcat是一個免費的開源的Serlvet容器,它是Apache基金會的Jakarta專案中的一個核心專案,由Apache、Sun和其它一些公司及個人共同開發而成。由於有了Sun的參與和支援,最新的Servlet和Jsp規範總能在 Tomcat中得到體現。
儘管Tomcat也可以作為獨立的Java Web伺服器,但在對靜態資源(HTML、影像檔案等)的處理速度,Web伺服器管理等方面都不如Apache、IIS伺服器等其他專業的HTTP伺服器,因此在實際應用中,常常把Tomcat與其他的HTTP伺服器整合使用。對於不支援Servlet/JSP的HTTP伺服器,可以通過Tomcat伺服器來執行Servlet/JSP元件。
當Tomcat與其他HTTP伺服器整合時,Tomcat伺服器的工作模式通常為程式外的Servlet容器,Tomcat伺服器與其他HTTP伺服器之間通過專門的外掛來通訊。
Tomcat的目錄結構
$CATALINA_HOME Tomcat安裝目錄下面有
- bin: 啟動和關閉Tomcat指令碼檔案。
- conf: Tomcat伺服器的各種配置檔案,包括:server.xml、web.xml、catalina.policy等。
- lib: Tomcat伺服器和所有web應用可以訪問的jar包。
- logs: Tomcat的日誌檔案。
- webapps: Tomcat自帶的兩個web應用:admin和manager,用來管理Tomcat的Web服務。
- work: JSP經過Tomcat編譯後生成的Servlet。
- temp: Tomcat執行時的臨時檔案。
Tomcat層次結構
Tomcat伺服器由一系列可配置元件構成,其中核心元件是Catalina Servlet容器,它是其他所有Tomcat元件的頂層容器。在server.xml配置檔案中,各元件之間關係如下
<Server>................................Server層
<Service>............................Service層
<Connector/>
<Engine>..........................Engine層
<Host>.........................Host層
<Context/>...............Context層
</Host>
</Engine>
</Service>
<Server>
Server層
對應Server元件,表示整個Tomcat(Catalina Servlet容器),它處於Tomcat頂層,可以包含一個或多個Service層。
Service層
對應Service元件,是Server層中的一個邏輯功能層,包含一個Engine層,以及一個或多個Connector,Service元件將一個或多個Connector元件繫結到Engine層上,Connector元件偵聽埠,獲得使用者請求,並將請求轉發到Engine層處理,同時把處理結果轉發給使用者,從而實現一個特定的功能。
Engine層
對應Engine元件,負責請求分發處理,可以連線多個Connector,它從Connector接收請求後,解析出可以完成使用者請求的URL,根據URL可以把請求匹配到正確的Host上,當Host處理完使用者請求後,Engine層把結果返回給適合聯結器,再由聯結器傳輸給使用者。
Host層
對應Host元件,表示一個虛擬主機,一個Engine層可以包含多個Host層,每個Host層可以包含一個或多個Context層,對應不同的web應用。
Context層
對應Context元件,代表某個虛擬主機上的實際目錄或一個WAR,即單個Web應用程式,它執行在特定的虛擬主機中,使用最為頻繁。一個Host層包含多個Context層,每一個Context都有唯一的路徑,Host層接到請求後,根據使用者請求的URL,將請求定位到Context層。
Tomcat常用配置檔案
server.xml:Tomcat中最重要的配置檔案,定義了tomcat的體系結構,包括聯結器埠、連線數、叢集、虛擬目錄、訪問日誌等的設定。
context.xml:全域性context的配置檔案,包括JNDI等資訊的配置。
tocmat-users.xml:Tocmat管理員身份的配置檔案,關鍵是設定管理員賬號的密碼。
logging.properties:Tocmat日誌配置檔案,可以修改預設的Tocmat日誌路徑和名稱。
Tomcat JVM引數調整
根據系統實體記憶體大小合理設定下列五個引數catalina.sh/catalina.bat
-server -Xms512m -Xmx512m -XX:PermSize=128m -XX:MaxPermSize=128m
一般情況下,設定-Xms=-Xmx、-XX:PermSize=-XX:MaxPermSize,正式伺服器必須設定以上引數,以儘可能壓榨伺服器效能。相關引數取值需要根據實際情況考慮,不要超過(實體記憶體-其他程式記憶體)的80%即可。
沒有特殊理由,儘量不要對上述五個引數外的其他JVM引數進行設定:
無法保證各種作業系統平臺的可移植性
過度干涉JVM記憶體管理會導致無法預料的後果
如果在Windows平臺上將解壓版的Tomcat安裝為服務,可以通過修改批處理檔案$CATALINA_HOME/bin/service.bat對JVM引數進行調整。
Tomcat日誌配置
Tomcat日誌資訊包括訪問日誌和執行日誌。
訪問日誌用於對使用者訪問系統的行為進行跟蹤記錄,主要記錄使用者訪問的時間、對應的IP地址、訪問的資料等資訊。記錄訪問日誌主要是基於對系統安全的考慮,對系統中一些重要、敏感資訊的資料訪問歷史進行記錄,便於對資源的訪問歷史進行追蹤,對於敏感資訊未經授權訪問等進行事後追查有一定幫助。但記錄訪問日誌會對伺服器效能產生一定的影響,在生產系統中需要慎用。
執行日誌主要記錄程式執行的一些資訊,其中的異常錯誤資訊可以為我們定位錯誤。從6.0版本開始,Tomcat的日誌介面採用是對Apache Commons Logging日誌介面進行獨立封裝,預設配置下,該日誌介面採用硬編碼使用java.util.logging日誌框架。
由於Tomcat釋出版本中獨立封裝的Apache Commons Logging介面並沒有對介面完全實現,如果要選擇不同的日誌框架就需要將該日誌介面替換為完全實現的版本。
預設配置下,Tomcat是不記錄訪問日誌的,可以通過如下配置允許Tomcat記錄訪問日誌:
修改$CATALINA_HOME/server.xml,在Host標籤下,找到如下配置資訊,去掉兩端的註釋就會啟用訪問日誌記錄功能:
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
prefix="localhost_access_log." suffix=".txt" pattern="common" resolveHosts="false"/>
通過對pattern項的修改,可以改變日誌輸出的內容。該項值可以為: common 與 combined,對應的日誌輸出內容如下所示:
common: %h %l %u %t %r %s %b
combined: %h %l %u %t %r %s %b %{Referer}i %{User-Agent}i
pattern 也可以根據需要自由組合, 例如 pattern="%h %l",對 於各 fields 欄位的含義請參照Tomcat官方文件。
在不同的環境下,需要設定不同的日誌級別,在生產環境中,為了提高效率和穩定性,一般會將日誌級別設定為相對較高的級別,而開發環境中為了跟蹤程式流程,可以將日誌級別調整為較低的級別。不同日誌框架有不同的日誌級別,常用的日誌框架對應級別如下:
Java.util.logging對應的日誌級別由高到低分別為:
severe > warning > info > config > fine > finer > finest
org.apache.log4j對應的日誌級別由高到低分別為:
fatal > error > warn > info > debug > trace
在預設配置下,Tomcat採用Java.util.logging日誌框架,對應的配置檔案為$CATALINA_HOME/ logging.properties,常用的日誌級別設定方法如下:
設定catalina日誌的級別為:FINE
1catalina.org.apache.juli.FileHandler.level = FINE
禁用catalina日誌的輸出:
1catalina.org.apache.juli.FileHandler.level = OFF
設定catalina所有的日誌訊息均輸出:
1catalina.org.apache.juli.FileHandler.level = ALL
Log4j是目前應用最廣的日誌框架,可以使用Log4j替換Tomcat預設採用的java.util.logging日誌框架,步驟如下:
建立log4j配置檔案log4j.properties ,儲存在$CATALINA_HOME/lib 下。
從Apache官網Log4J專案下載Log4J(1.2版本以後)。
從Apache官網Tomcat專案下載tomcat-juli.jar和tomcat-juli-adapters.jar。
複製log4j.jar、tomcat-juli-adapters.jar到$CATALINA_HOME/lib下。
用tomcat-juli.jar覆蓋$CATALINA_HOME/bin下的同名檔案。
刪除Tomcat的預設日誌配置檔案$CATALINA_HOME/conf/ logging.properties,以避免生成一些冗餘的空日誌檔案。
Tomcat URL編碼格式設定
預設情況下,如果URL當中包含有非英文字元,需要通過在程式對URL進行轉碼處理,否則URL中的非英文字元無法保證正確解析。在無特殊要求的情況下,需要將URL編碼設定為和專案統一的編碼格式,目前公司大部分專案都統一採用UTF-8字元編碼方式,示例如下:
<Connector port="8087" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443"
URIEncoding="utf-8" />
Tomcat 常見問題總結
JVM記憶體溢位(OOM),分為堆記憶體溢位和PermGen區記憶體溢位:
java.lang.OutOfMemoryError: PermGen space
PermGen space(Permanent Generation space),是指記憶體的永久儲存區域,主要用於存放Class和Meta資訊的,Class在被Loader時就會被放到PermGen space中, 它和存放類例項(Instance)的Heap區域不同,GC(Garbage Collection)不會在主程式執行期對其進行清理,所以如果應用中有很多CLASS的話,就很可能出現PermGen space錯誤。如果載入的Class超過MaxPermSize,就會丟擲該異常,可以通過調整MaxPermSize進行解決。
java.lang.OutOfMemoryError: Java heap space
JVM堆是指java程式執行過程中JVM可以調配使用的記憶體空間。JVM在啟動的時候會自動設定Heap size的值,其初始空間(-Xms)是實體記憶體的1/64,最大空間(-Xmx)是實體記憶體的1/4。可以利用JVM提供的-Xmn -Xms -Xmx等選項可進行設定。Heap size 的大小是Young Generation 和Tenured Generaion 之和。在JVM中如果98%的時間是用於GC且可用的Heap size 不足2%的時候將丟擲此異常資訊。
JDK安裝及JAVA_HOME設定
啟動不成功,沒有日誌,一般是JDK安裝不正確或沒有設定環境變數。
大量使用者訪問時瀏覽器沒有響應
併發執行緒數設定太小,調整$CATALINA/conf/server.xml中聯結器對應的請求處理執行緒數。