天天看點

圖解 Tomcat 體系結構

Apache Tomcat 是一款非常著名的開源 Servlet/JSP 容器。

讓我們先來浏覽一下 Tomcat 體系結構中的六個主要概念:

<a href="http://tomcat.apache.org/tomcat-5.5-doc/config/server.html">Server</a>

<a href="http://tomcat.apache.org/tomcat-5.5-doc/config/service.html">Service</a>

<a href="http://tomcat.apache.org/tomcat-5.5-doc/config/engine.html">Engine</a>

<a href="http://tomcat.apache.org/tomcat-5.5-doc/config/host.html">Host</a>

Connector

<a href="http://tomcat.apache.org/tomcat-5.5-doc/config/context.html">Context</a>

于Tomcat體系結構的内容非常豐富,是以本文非常長。是以我們盡量的使每一部分盡可能自成一體,使您可以獨立閱讀。如果您不是想全面了解Tomcat

的體系結構,隻是想解決某一部分的具體問題,那麼我們建議您使用目錄導航到相關的内容,而不必在其它的内容上花費寶貴的時間。

Server代表整個容器(container)。它可以包含一個或多個Service,還可以包含一個GlobalNamingResources。

得注意的是在标準的Server接口中沒有包括Lifecycle接口,但是在标準實作

org.apache.catalina.core.StandardServer中卻實作了Lifecycle這個接口,這使得我們可以為Tomcat

的标準實作設定Listener。一般的方法是在conf/server.xml檔案中加入:

其中的XXXLifecycleListener為您自定義的LifecycleListener,而且必須要實作LifecycleListener接口。您可以在這裡設定多個LifecycleListener,但要使用不同的名字。

由于在Tomcat的官方文檔中沒有顯著的說明,是以這種使用Listener的方式沒有展現在稍後給出的 體系結構圖 中。

您可以通過稍後給出的 體系結構圖 了解在整個Tomcat體系結構中Server所處的位置。

<a href="http://www.solol.org/technologic/java/j-tomcatarch/#top">回頁首</a>

Service中可以含有一個或多個Connector,但隻能含有一個Engine。這使得不同的Connector可以共享同一個Engine。同一個Server中的多個Service之間沒有相關性。

得注意的是在标準的Service接口中沒有包括Lifecycle接口,但是在标準實作

org.apache.catalina.core.StandardService中卻實作了Lifecycle這個接口,這使得我們可以為

Tomcat的标準實作設定Listener。

您可以通過稍後給出的 體系結構圖 了解在整個Tomcat體系結構中Service所處的位置。

Engine負責接收和處理來自它所屬的Service中的所有Connector的請求。

Engine

支援backgroundProcessorDelay、className、defaultHost、jvmRoute和name五個公共屬性,而标準

您可以通過稍後給出的 體系結構圖 了解在整個Tomcat體系結構中Engine所處的位置。

從圖中可以看出Engine右邊有四個不同顔色的小方塊,它們表示Engine所支援的四個不同的特性。相同顔色的小方塊可能也會出現在其它的地方,這表示在那裡也支援相同的或相似的特性。每種特性的具體描述可以在文中的Special Features中找到。

從圖中可以看出Engine下邊有一個紅色的圓角矩形,它們表示Engine所支援的一個内嵌元件。相同顔色的圓角矩形可能也會出現在其它的地方,這表示在那裡也支援相同的或相似的内嵌元件。每種内嵌元件的具體描述可以在文中的Nested Components中找到。

Host表示一個虛拟主機,并和一個伺服器的網絡名關聯。注意Engine中必須有一個Host的名字和Engine的defaultHost屬性比對。

有時候,網絡管理者可能希望将多個網絡名關聯到一個虛拟主機,這可以通過下文介紹的Host Name Aliases特性完成。

Host

支援appBase、autoDeploy、backgroundProcessorDelay、className、deployOnStartup和

name六個公共屬性,而标準實作org.apache.catalina.core.StandardHost還可能支援一些擴充屬性。詳細的内容您可

您可以通過稍後給出的 體系結構圖 了解在整個Tomcat體系結構中Host所處的位置。

從圖中可以看出Host右邊有八個不同顔色的小方塊,它們表示Host所支援的八個不同的特性。相同顔色的小方塊可能也會出現在其它的地方,這表示在那裡也支援相同的或相似的特性。每種特性的具體描述可以在文中的Special Features中找到。

從圖中可以看出Host下邊有一個紅色的圓角矩形,它們表示Host所支援的一個内嵌元件。相同顔色的圓角矩形可能也會出現在其它的地方,這表示在那裡也支援相同的或相似的内嵌元件。每種内嵌元件的具體描述可以在文中的Nested Components中找到。

您可以通過稍後給出的 體系結構圖 了解在整個Tomcat體系結構中Connector所處的位置。

Context表示在虛拟主機中運作的web應用程式。一個虛拟主機中能夠運作多個Context,它們通過各自的Context Path進行互相區分。如果Context Path為"",那麼該web應用為該虛拟主機的預設的web應用。

目前可以通過四種方式将Context加入Host:

$CATALINA_HOME/conf/context.xml,其中Context元素中的資訊會被所有web應用程式加載

$CATALINA_HOME/conf/[enginename]/[hostname]/context.xml.default,其中Context元素中的資訊會被hostname主機下的所有web應用程式加載

$CATALINA_HOME/conf/[enginename]/[hostname]/目錄中所有以.xml為擴充名的檔案,其中Context元素中的資訊會被hostname主機下的所有web應用程式加載

如果通過上面的步驟沒有找到,那麼最後要從web應用程式的/META-INF/context.xml目錄中查找

Context

支援backgroundProcessorDelay、className、cookies、crossContext、docBase、

override、privileged、path、reloadable和wrapperClass十個公共屬性,而标準實作

您可以通過稍後給出的 體系結構圖 了解在整個Tomcat體系結構中Context所處的位置。

從圖中可以看出Context右邊有十個不同顔色的小方塊,它們表示Context所支援的十個不同的特性。相同顔色的小方塊可能也會出現在其它的地方,這表示在那裡也支援相同的或相似的特性。每種特性的具體描述可以在文中的Special Features中找到。

圖中可以看出Context下邊有五個不同顔色的圓角矩形,它們表示Context所支援的五個内嵌元件。相同顔色的圓角矩形可能也會出現在其它的地方,

這表示在那裡也支援相同的或相似的内嵌元件。每種内嵌元件的具體描述可以在文中的Nested Components中找到。

Tomcat 的體系結構圖

圖解 Tomcat 體系結構

GlobalNamingResources 元件為 Server 定義全局 JNDI 資源。這些資源出現在 Server 的全局 JNDI 資源上下文中。這個上下文和每個 web 應用程式的 JNDI 上下文不同。在全局 JNDI 上下文中定義的資源在每個

從前面給出的 體系結構圖

中可以看出GlobalNamingResources右邊有四個不同顔色的小方塊,它們表示GlobalNamingResources所支援的四個不

同的特性。相同顔色的小方塊可能也會出現在其它的地方,這表示在那裡也支援相同的或相似的特性。每種特性的具體描述可以在文中的Special

Features中找到。

從前面給出的 體系結構圖 中可以看出,Realm元件在Engine、Host和Context中都有支援。

Realm

是一個"資料庫"存儲着使用者名、密碼和角色資訊。通過自定義Realm可以将Catalina內建到其它的環境。Engine、Host和Context

中的Realm可以被較低級别的容器繼承,即Host繼承Engine的Realm,Context繼承Host的Realm,除非我們顯示的禁止這種繼

承。

Realm支援className一個公共屬性。Tomcat提供了多個實作:

org.apache.catalina.realm.JDBCRealm

org.apache.catalina.realm.DataSourceRealm

org.apache.catalina.realm.JNDIRealm

org.apache.catalina.realm.MemoryRealm

從前面給出的 體系結構圖 中可以看出,Loader元件隻在Context中都有支援。

Loader是web應用程式的類裝載器。必須有一個類裝載器按照Servlet Specification的要求從如下的位置裝載類:

從web應用程式的/WEB-INF/classes目錄裝載

從web應用程式的/WEB-INF/lib目錄中的jar檔案中裝載

從Catalina中裝載對于所有web應用可見的資源

從前面給出的 體系結構圖 中可以看出,Manager元件隻在Context中有支援。

Manager是session管理器(session manager),負責session的建立和維護。

Manager元素應該嵌入到Context元素中,如果沒有設定那麼會自動建立一個預設的Manager。

Manager

支援className和distributable兩個公共屬性,而标準實作

org.apache.catalina.session.StandardManager和

從前面給出的 體系結構圖 中可以看出,Resources元件隻在Context中有支援。

Resources元素應該嵌入到Context元素中,如果沒有設定那麼會自動建立一個預設的基于檔案系統的Resources。

從前面給出的 體系結構圖 中可以看出,WatchedResource元件隻在Context中都有支援。

WatchedResource用來告知Auto Deployer那些靜态資源的更新需要被監控。如果被監控的資源被更新了那麼該資源所對應的web應用将會被重新裝載。這個元素的内容必須是一個String。

從前面給出的 體系結構圖 中可以看出,Logging特性在Engine、Host和Context中都有支援。這個特性使得我們可以區分日志記錄的具體來源。

在Engine、Host和Context中的日志類别分别為:

<code>org.apache.catalina.core.ContainerBase.[enginename]</code>

<code>org.apache.catalina.core.ContainerBase.[enginename].[hostname]</code>

<code>org.apache.catalina.core.ContainerBase.[enginename].[hostname].[path]</code>

其中中括号([])中為具體的名稱。

Logging特性的實作是通過org.apache.catalina.core.ContainerBase來完成的。

從前面給出的 體系結構圖 中可以看出,Access Logs特性在Engine、Host和Context中都有支援。

Engine中的Access Logs記錄所有Engine處理的請求的通路日志

Host中的Access Logs記錄所有Host處理的請求的通路日志

Context中的Access Logs記錄所有Context處理的請求的通路日志

一般的配置方法是在conf/server.xml檔案的相關元素中加入:

上面的&lt;Engine&gt;,在Host中要被換成&lt;Host&gt;,在Context中要被換成&lt;Context&gt;。

從前面給出的 體系結構圖 中可以看出,Lifecycle Listeners特性在Engine、Host和Context中都有支援。這個特性使得我們可以友善的進行生命周期的管理。

值得一提的是在Tomcat的标準實作中Server和Service也支援生命周期的管理,但是在官方文檔中沒有顯著的說明,是以沒有在圖中展現出來。細節可以查閱Server和Service部分。

Engine中的Lifecycle Listeners監聽該Engine的生命周期事件(Eifecycle Event)

Host中的Lifecycle Listeners監聽該Host的生命周期事件(Eifecycle Event)

Context中的Lifecycle Listeners監聽該Context的生命周期事件(Eifecycle Event)

另外,可以通過&lt;Listener&gt;元素為listener添加屬性。

注意和Container Event差別。

從前面給出的 體系結構圖 中可以看出,Request Filters特性在Engine、Host和Context中都有支援。

Engine中的Request Filters過濾所有Engine處理的請求

Host中的Request Filters過濾所有Host處理的請求

Context中的Request Filters過濾所有Context處理的請求

從前面給出的 體系結構圖 中可以看出,Automatic Application Deployment特性隻在Host中都有支援。

如果使用Host的标準實作,同時deployOnStartup屬性值為true(這是預設值),那麼Catalina在首次啟動時會自動完成下面的工作:

$CATALINA_HOME/conf/[engine_name]/[host_name]目錄下的所有XML檔案都被假定含有&lt;Context&gt;元素。

appBase

目錄下的所有沒有展開的war檔案(沒有展開的意思是沒有和war檔案名不包括.war擴充名對應的目錄存在)會被自動展開,除非unpackWARs屬

性值為false。如果重新部署更新的war檔案,在重起Tomcat之前要删除先前展開的目錄(如果autoDeploy屬性值為true那麼隻要删除

先前展開的目錄更新後的war檔案就會自動展開)。

于appBase中含有/WEB-INF/web.xml檔案的任何子目錄都會自動産生一個Context,不管該子目錄是否在conf

/server.xml檔案中出現過。這個新産生的Context将會根據DefaultContext的屬性值進行設定,其context

path為“/目錄名”。如果目錄名為ROOT,那麼context path為“”。

是以要使用上面的規則需要将XML設定檔案拷貝到$CATALINA_HOME/conf/[engine_name]/[host_name]目錄下或将war檔案和含有web應用的目錄拷貝到appBase目錄下。

自動部署(Auto Deployer)也會跟蹤如下web應用程式的變化:

更新WEB-INF/web.xml檔案将會使web應用程式重新加載

更新已展開的war檔案會使web應用程式解除安裝(undeploy)(同時移除先前展開的目錄)并重新部署(deployment)

更新XML設定檔案會使web應用程式解除安裝(undeploy)(不移除任何展開的目錄)并重新部署(deployment)

在使用自動部署的時候XML設定檔案中的docBase要指向appBase目錄之外。否則部署将很困難或應用程式會被部署兩次。

如果要顯示的定義context,那麼需要關閉自動部署。否則相應的context将會部署兩次,這可能會有問題。

從前面給出的 體系結構圖 中可以看出,Host Name Aliases特性隻在Host中都有支援。

在一些時候,網絡管理者會将多個網絡名(在DNS伺服器中)解析到同一個伺服器。通常每一個網絡名會對應到一個Host。不過有時候需要将多個網絡名對應到一個Host,Host Name Aliases用來完成這個目标。

&lt;Host&gt;元素中可以嵌入一個或多個&lt;Alias&gt;元素。

從前面給出的 體系結構圖 中可以看出,Single Sign On特性隻在Host中都有支援。

在一些時候,特别是在Portal環境下,可能會希望當使用者通路一個虛拟主機下的多個web應用時隻登陸一次,即所謂的單點登陸。

Single Sign On操作遵循下面的規則:

該虛拟主機下的所有Web應用程式必須共享同一個Realm。在實踐中通常通過為Host或(對應的Engine)嵌入Realm而不是為每一個Context嵌入相同的Realm來實作。

在使用者通路該虛拟主機下的所有Web應用程式中的非保護資源時不需要驗證。

在使用者通路該虛拟主機下的所有Web應用程式中的保護資源時需要驗證。

一旦被驗證,就會對該虛拟主機下的所有Web應用程式有效,而不用每個應用程式單獨驗證。

如果使用者從一個Web應用中退出,那麼所有Web應用程式中的session都會失效。

使用SSO需要客戶環境支援cookies。

從前面給出的 體系結構圖 中可以看出,User Web Applications特性隻在Host中都有支援。

許多Web伺服器都可以處理如下形式的請求:

其中craigmcc為系統的一位使用者名。具體的處理過程和作業系統相關。

在類Unix或Linux等作業系統下配置方法如下:

在Windows等作業系統下配置方法如下:

這兩種配置最主要的差別就是發現使用者和為使用者比對路徑。PasswdUserDatabase依據/etc/passwd發現使用者而HomesUserDatabase依據homeBase="c:/Homes"發現使用者。

User Web Applications是通過Listener(org.apache.catalina.startup.UserConfig)的方式實作的。即在Host啟動時該Listener會被執行,它會為每一個發現的使用者建構對應Context。

使用User Web Applications時需要考慮以下的一些問題:

依據DefaultContext來設定為每一個使用者建立Context

可以使用多個Listener元素(在這麼做之前您最好查閱一下UserConfig)

使用者所對應的目錄應該具有讀寫權限

從前面給出的 體系結構圖 中可以看出,Automatic Context Configuration特性隻在Context中都有支援。

如果使用标準的Context實作,當Catalina啟動或Web應用裝載時,會按如下的步驟自動進行設定:

如果沒有指定Loader元素,那麼一個标準的Loader将會被設定

如果沒有指定Manager元素,那麼一個标準的Manager将會被設定

如果沒有指定Resources元素,那麼一個标準的Resources将會被設定

處理conf/web.xml檔案

處理/WEB-INF/web.xml檔案

如果設定了security constraints,那麼一個對應的Authenticator會被建立

從前面給出的 體系結構圖 中可以看出,Context Parameters特性隻在Context中有支援。

如下的兩種配置等價,都是為Web配置初始參數:

從前面給出的 體系結構圖 中可以看出,Environment Entries特性在GlobalNamingResources和Context中都有支援。

如下的兩種配置等價,都是為配置environment entry resources:

這裡使用GlobalNamingResources表示environment entry resources對于所有Web應用程式可見。如果換成Context則表示隻對相應Web應用程式可見。

從前面給出的 體系結構圖 中可以看出,Resource Definitions特性在GlobalNamingResources和Context中都有支援。

如下的兩種配置等價,都是為定義Resource:

這裡使用GlobalNamingResources表示Resource對于所有Web應用程式可見。如果換成Context則表示隻對相應Web應用程式可見。

從前面給出的 體系結構圖 中可以看出,Resource Links特性在GlobalNamingResources和Context中都有支援。

ResourceLink

元素用來将資源從全局上下文(global context)中連接配接到每個Web應用的上下文(per-web-application

contexts)中。使用方式依據GlobalNamingResources和Context的不同分成兩種:

從前面給出的 體系結構圖 中可以看出,Transaction特性在GlobalNamingResources和Context中都有支援。

通過在JNDI中查詢<code>java:comp/UserTransaction</code>可以得到UserTransaction的引用。

<a>參考資料</a>

<a href="http://java.sun.com/products/servlets/">Java Servlet</a>

<a href="http://java.sun.com/products/jsp/">JavaServer Pages</a>

<a href="http://tomcat.apache.org/tomcat-5.5-doc/jndi-resources-howto.html">JNDI Resources HOW-TO</a>

<a href="http://tomcat.apache.org/tomcat-5.5-doc/config/valve.html">The Valve Component</a>

<a href="http://www.solol.org/blogs/200701/200701080000.html">Tomcat中的職責鍊模式</a>

<a href="http://www.solol.org/blogs/200701/200701051230.html">Tomcat中的觀察者模式</a>

<a href="http://www.solol.org/blogs/200701/200701051330.html">Tomcat中的觀察者模式 二</a>

<a href="http://www.solol.org/blogs/200701/200701082000.html">Tomcat中的政策模式</a>

<a href="http://www.solol.org/blogs/200701/200701102050.html">Tomcat中的TCP Server</a>

<a href="http://tomcat.apache.org/tomcat-5.5-doc/class-loader-howto.html">The ClassLoader HowTo</a>

<a href="http://tomcat.apache.org/tomcat-5.5-doc/realm-howto.html">Realm Configuration HOW-TO</a>

<a href="http://www.solol.org/blogs/200701/200701062030.html">置于檔案系統之外的web應用程式</a>

<a href="http://www.eoeandroid.com/forumdisplay.php?fid=4">國内最棒的Google Android技術社群(eoeandroid),歡迎通路!</a>