本文目錄:
1. 入門示例:虛擬主機提供web服務
2. tomcat體系結構基本說明
3. tomcat的appBase和docBase詳細說明
4. tomcat進階:tomcat配置文件server.xml詳解
4.1 頂級元素server
4.2 頂級元素service
4.3 執行器executor
4.4 鏈接器connector
4.5 容器類engine
4.6 容器類host
4.7 容器類context
4.8 被嵌套類realm
4.9 被嵌套類valve javascript
該示例經過設置虛擬主機來提供web服務,由於是入門示例,因此設置極其簡單,只需修改$CATALINA_HOME/conf/server.xml文件爲以下內容便可。其中大部分都採用了默認設置,只是在engine容器中添加了兩個Host容器。php
<?xml version="1.0" encoding="UTF-8"?>
<Server port="8005" shutdown="SHUTDOWN">
<Listener className="org.apache.catalina.startup.VersionLoggerListener" />
<Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
<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">
<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" enableLookups="false" />
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
<Engine name="Catalina" defaultHost="localhost">
<Realm className="org.apache.catalina.realm.LockOutRealm">
<Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase" />
</Realm>
<!-- 今後處開始添加如下兩個Host容器做爲虛擬主機 -->
<Host name="www.longshuai.com" appBase="/www/webapps/longshuai" unpackWARs="true" autoDeploy="true">
<Context path="" docBase="/www/webapps/longshuai" reloadable="true" />
<Context path="/xuexi" docBase="xuexi" reloadable="true" />
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="longshuai_access_log" suffix=".txt" pattern="%h %l %u %t "%r" %s %b" />
</Host>
<Host name="www.xiaofang.com" appBase="/www/webapps/xiaofang" unpackWARs="true" autoDeploy="true">
<Context path="" docBase="/www/webapps/xiaofang" reloadable="true" />
<Context path="/xuexi" docBase="xuexi" reloadable="true" />
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="xiaofang_access_log" suffix=".txt" pattern="%h %l %u %t "%r" %s %b" />
</Host>
<Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true">
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="localhost_access_log" suffix=".txt" pattern="%h %l %u %t "%r" %s %b" />
</Host>
</Engine>
</Service>
</Server>
除了engine中定義的默認localhost虛擬主機,另外佈置了兩個虛擬主機www.longshuai.com和www.xiaofang.com,它們的程序目錄分別爲/www/longshuai和/www/xiaofang,因此須要提早創建好這兩個目錄。另外,在context中定義了docBase,對於uri路徑/xuexi,它的文件系統路徑爲/www/{longshuai,xiaofang}/xuexi目錄,因此也要在上面兩個程序根目錄中定義好xuexi目錄。除此以外,還分別爲這3個虛擬主機定義了日誌,它們的路徑爲相對路徑logs,相對於$CATALINA_HOME。css
再提供appBase目錄和docBase目錄。html
mkdir -p /www/{longshuai,xiaofang}/xuexi
再提供測試用的index.jsp文件。內容大體以下,分別複製到/www/{longshuai,xiaofang}/和/www/{longshuai,xiaofang}/xuexi/下,並將out.println的輸出內容分別稍做修改,使可以區分讀取的是哪一個index.jsp。前端
<%@ page language="java" %>
<%@ page import="java.util.*" %>
<html>
<body>
<% out.println("hello world from longshuai Root"); %>
</body>
</html>
最後重啓catalina。java
catalina.sh stop catalina.sh start
再測試主機上添加www.{longshuai,xiaofang}.com的host記錄。例如在windows上,在C:\Windows\System32\drivers\etc\hosts中添加以下記錄:mysql
192.168.100.22 www.longshuai.com www.xiaofang.com
在瀏覽器中進行測試,結果以下:nginx
以下圖:git
tomcat高度模塊化,各個模塊之間有嵌套的父子關係。若是使用配置文件來描述,能夠大體簡化爲以下:github
<server>
<service>
<connector PORT />
<engine>
<host name=www.a.com appBase=/www/a >
<context path="" docBase=/www/a />
<context path="/xuexi" docBase=/www/a/xuexi />
</host>
<host>
<context />
</host>
</engine>
</service>
</server>
其中server組件是工做在後臺管理tomcat實例的組件,能夠監聽一個端口,今後端口上能夠遠程向該實例發送shutdown關閉命令。
service組件是一個邏輯組件,綁定connector和containor,有了service表示能夠向外提供服務,就像是通常的daemon類服務的service。
connector組件是服務監聽組件,用於監聽外界請求並創建TCP鏈接,而後將鏈接交給containor,以後能夠今後鏈接傳輸數據,例如接收http請求,發送http響應等。
containor是容器,在配置文件中沒有體現出來,它包含4個容器類組件:engine容器、host容器、context容器和wrapper容器。
engine容器用於從connector組件處接收已創建的TCP鏈接,還用於接收客戶端發送的http請求並分析請求,而後按照分析的結果將相關參數傳遞給匹配出的虛擬主機。engine還用於指定默認的虛擬主機。
host容器定義虛擬主機,因爲tomcat主要是做爲servlet容器的,因此爲每一個web應用程序指定了它們的根目錄appBase。
context容器對應servlet容器的處理過程。還能夠指定相關的wrapper容器類,固然通常都採用默認的標準wrapper類。
最後當請求處理完畢後,context將響應數據返回給host,再返回給engine,再返回給connector,最後返回給客戶端。
撇開tomcat做爲servlet容器的行爲。它和apache、nginx的功能大體都能對應上。例如以nginx爲例,如下是nginx提供web服務時的配置結構:
server {
listen PORT;
server_name www.a.com; # 對應於<host name=www.a.com>
location / { # 對應於context path=""
root html; # 對應於docBase
}
location /xuexi { # 對應於context path="/xuexi"
root html/xuexi;
}
}
connetcor組件相似於nginx的listen指令。host容器相似於nginx的server指令,host容器中的name屬性至關於nginx的server_name指令。engine組件則沒有對應配置項,不過在nginx一樣有engine的功能,例如默認的虛擬主機,分析URL來判斷請求交給哪一個虛擬主機處理等。context容器至關於location指令,context容器的path屬性至關於location的uri匹配路徑,docBase至關於location的中的root指令,即DocumentRoot。
tomcat做爲簡單的web服務程序大體如此,但它的核心畢竟是處理servlet和jsp,它必須得管理好每一個webapp。所以,對於tomcat來講,必需要掌握部署webapp的方式。在tomcat上部署webapp時,必需要理解context的概念,對於tomcat而言,每一個context都應該算是一個webapp,其路徑由docBase決定,該目錄存放的是歸檔的war文件或未歸檔的webapp相關文件,而host容器中的appBase則是虛擬主機整理webapp的地方,一個appBase下能夠有多個webapp,即多個context。
這兩貨雖然意義很明確,但"潛規則"很嚴重。如下面的配置爲例。
<host name=www.a.com appBase=/www/a >
<context path="" docBase=/www/a />
<context path="/xuexi" docBase=/www/a/xuexi />
</host>
appBase是虛擬主機存放webapp的目錄,它能夠是相對路徑,也能夠是絕對路徑。若是是相對路徑,則相對於$CATALINA_HOME,嚴格地說是$CATALINA_BASE。
path是URI的匹配路徑,至關於nginx的location後的路徑。tomcat要求每一個虛擬主機必須配置一個空字符串的path,該條context做爲URI沒法被明確匹配時的默認context,它至關於nginx中location / {}
的做用。
docBase則是每一個webapp的存放目錄(或者是已歸檔的war文件),它能夠是相對路徑,也能夠是絕對路徑,提供相對路徑時它相對於appBase。該目錄通常在appBase的目錄下,但並不規定必定要放在appBase下。對於web服務來講,它至關於nginx的root指令,但對於webapp來講,一個context就至關於一個webapp,而docBase正是webapp的路徑。
"潛規則"在於默認的context如何提供。有如下幾種狀況:
<context path="" docBase=webappPATH>
,此時默認context的處理路徑爲webappPATH。<context path="">
,但卻沒給定docBase屬性,此時該默認context處理路徑爲appBase/ROOT目錄,注意ROOT爲大寫。path=""
的context時,即host容器中沒有明確的path="",此時將隱式定義一個默認context,處理路徑爲appBase/ROOT目錄。context path context name 推斷出的docBase路徑
--------------------------------------------------
/foo /foo foo
/foo/bar /foo/bar foo/bar
Empty String Empty String ROOT
如下是幾個定義示例:
# 虛擬主機中沒有定義任何context,將以appBase下的ROOT做爲默認處理路徑
<Host appBase="webapps">
</Host>
# 沒有定義path=""的context,但定義了path非空的context,也將以ROOT做爲默認處理路徑
# 若是下面的Context容器中省略docBase屬性,則推斷出其docBase路徑爲appBase/xuexi
<Host appBase="webapps">
<Context path="/xuexi" docBase="webappPATH" />
</Host>
# 某個context定義了path="",該context將做爲默認context
# 但該默認context沒有定義docBase,將推斷出其docBase路徑爲appBase/ROOT
<Host appBase="webapps">
<Context path="" docBase="webappPATH" />
</Host>
# 某個context定義了path="",該context將做爲默認context
# 下面的默認context明肯定義了docBase
<Host appBase="webapps">
<Context path="" docBase="webappPATH" />
</Host>
tomcat配置文件中配置的是各個組件的屬性,全局配置文件爲$CATALINA_HOME/conf/server.xml,主要的組件有如下幾項:Server,Service,Connector,Engine,Host,Alias,Context,Valve等。配置完配置文件後須要重啓tomcat,但在啓動後必定要檢查tomcat是否啓動成功,由於即便出錯,不少時候它都不會報錯,可從監聽端口判斷。
配置方法見官方手冊,在頁面的左邊有各個組件的連接。
tomcat的配置文件都是xml文件,如下是xml文件的常見規則:
<?xml version="1.0" encoding="UTF-8"?>
。<!-- XXX -->
,這能夠是單行註釋,也能夠多行註釋,只要先後註釋符號能對應上,中間的內容都是註釋。<!-- 單行定義的方式 -->
<NAME key=value />
<!-- 多行定義的方式 -->
<NAME key=value>
</NAME>
下面個組件的配置中有些地方使用了相對於$CATALINA_BASE的相對路徑,它和$CATALINA_HOME小有區別,若是隻有一個tomcat實例,則它們是等價的,都是tomcat的安裝路徑。若是有多個tomcat實例,則$CATALINA_HOME表示的是安裝路徑,而$CATALINA_BASE表示的是各實例所在根目錄。關於tomcat多實例,見running.txt中對應的說明。
server組件定義的是一個tomcat實例。默認定義以下:
<Server port="8005" shutdown="SHUTDOWN">
</Server>
它默認監聽在8005端口以接收shutdown命令。要啓用多個tomcat實例,將它們監聽在不一樣的端口便可。這個端口的定義爲管理員提供一個關閉實例的便捷途徑,能夠直接telnet至此端口使用SHUTDOWN命令關閉此實例。不過基於安全角度的考慮,一般不容許遠程進行。
Server的相關屬性:
className
:用於實現此組件的java類的名稱,這個類必須實現接口org.apache.catalina.Server。不給定該屬性時將採用默認的標準類org.apache.catalina.core.StandardServer;address
:監聽端口綁定的地址。如不指定,則默認爲Localhost,即只能在localhost上發送SHUTDOWN命令;port
:接收shutdown指令的端口,默認僅容許經過本機訪問,默認爲8005;shutdown
:經過TCP/IP鏈接發往此Server用於實現關閉tomcat實例的命令字符串。在server組件中可嵌套一個或多個service組件。
定義了service就能提供服務了。service組件中封裝connector和containor,它同時也表示將此service中的connector和containor綁定起來,即由它們組成一個service向外提供服務。默認定義以下:
<Service name="Catalina">
</Service>
Service相關的屬性:
className
:用於實現service的類名,這個類必須實現org.apache.catalina.Service接口。不給定該屬性時將採用默認的標準類org.apache.catalina.core.StandardService。name
:此service的顯示名稱,該名稱主要用於在日誌中進行標識service。通常來講可有可無,默認爲Catalina。執行器定義tomcat各組件之間共享的線程池。在之前,每一個connector都會獨自建立本身的線程池,但如今,能夠定義一個線程池,各組件均可以共享該線程池,不過主要是爲各connector之間提供共享。注意,executor建立的是共享線程池,若是某個connector不引用executor建立的線程池,那麼該connector仍會根據本身指定的屬性建立它們本身的線程池。
鏈接器必需要實現org.apache.catalina.Executor接口。它是一個嵌套在service組件中的元素,爲了挑選所使用的connector,該元素還必須定義在connector元素以前。
默認的定義以下:
<Executor name="tomcatThreadPool" namePrefix="catalina-exec-" maxThreads="150" minSpareThreads="4"/>
其中該組件的屬性有:
className
:用於實現此組件的java類的名稱,這個類必須實現接口org.apache.catalina.Executor。不給定該屬性時將採用默認的標準類org.apache.catalina.core.StandardThreadExecutor;name
:該線程池的名稱,其餘組件須要使用該名稱引用該線程池。標準類的屬性包括:
threadPriority
:線程優先級,默認值爲5。daemon
:線程是否以daemon的方式運行,默認值爲true。namePrefix
:執行器建立每一個線程時的名稱前綴,最終線程的名稱爲:namePrefix+threadNumber。maxThreads
:線程池激活的最大線程數量。默認值爲200。minSpareThreads
:線程池中最少空閒的線程數量。默認值爲25。maxIdleTime
:在空閒線程關閉前的毫秒數。除非激活的線程數量小於或等於minSpareThreads的值,不然會有空閒線程的出現。默認值爲60000,即空閒線程須要保留1分鐘的空閒時間才被殺掉。maxQueueSize
:可執行任務的最大隊列數,達到隊列上限時的鏈接請求將被拒絕。prestartminSpareThreads
:在啓動executor時是否當即建立minSpareThreads個線程數,默認爲false,即在須要時才建立線程。例如在connector中指定所使用的線程池,方式以下:
<Connector executor="tomcatThreadPool" port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />
鏈接器用於接收客戶端發送的請求並返回響應給客戶端。一個service中能夠有多個connector。有多種connector,常見的爲http/1.1,http/2和ajp(apache jserv protocol)。在tomcat中,ajp鏈接協議類型專用於tomcat前端是apache反向代理的狀況下。
所以tomcat能夠扮演兩種角色:
Tomcat應該考慮工做情形併爲相應情形下的請求分別定義好須要的鏈接器才能正確接收來自於客戶端的請求。
此處暫先介紹HTTP/1.1鏈接器的屬性設置。ajp後文再作介紹。
HTTP鏈接器表示支持HTTP/1.1協議的組件。設置了該鏈接器就表示catalina啓用它的獨立web服務功能,固然,確定也提供它必須的servlets和jsp執行功能。在一個service中能夠配置一個或多個鏈接器,每一個鏈接器均可以將請求轉發給它們相關聯的engine以處理請求、建立響應。
若是想要配置某個web server的鏈接器,則使用AJP協議。
每一個流入的請求都須要一個獨立的線程來接收。當併發請求數量超出maxThreads指定的值時,多出的請求將被堆疊在套接字中,直到超出acceptCount指定的值。超出accpetCount的請求將以"connection refused"錯誤進行拒絕。
默認的定義以下:
<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />
HTTP鏈接器的屬性實在太多,詳細配置方法見官方手冊。一般定義HTTP鏈接器時必須定義的屬性只有"port"。
address
:指定鏈接器監聽的地址,默認爲全部地址,即0.0.0.0。maxThreads
:支持的最大併發鏈接數,默認爲200;若是引用了executor建立的共享線程池,則該屬性被忽略。acceptCount
:設置等待隊列的最大長度;一般在tomcat全部處理線程均處於繁忙狀態時,新發來的請求將被放置於等待隊列中;maxConnections
:容許創建的最大鏈接數。acceptCount和maxThreads是接受鏈接的最大線程數。存在一種狀況,maxConnections小於acceptCount時,超出maxConnections的鏈接請求將被接收,但不會與之創建鏈接。port
:監聽的端口,默認爲0,此時表示隨機選一個端口,一般都應該顯式指定監聽端口。protocol
:鏈接器使用的協議,用於處理對應的請求。默認爲HTTP/1.1,此時它會自動在基於Java NIO或APR/native鏈接器之間進行切換。定義AJP協議時一般爲AJP/1.3。redirectPort
:若是某鏈接器支持的協議是HTTP,當接收客戶端發來的HTTPS請求時,則轉發至此屬性定義的端口。connectionTimeout
:等待客戶端發送請求的超時時間,單位爲毫秒,默認爲60000,即1分鐘;注意,這時候鏈接已經創建。keepAliveTimeout
:長鏈接狀態的超時時間。超出該值時,長鏈接將關閉。enableLookups
:是否經過request.getRemoteHost()進行DNS查詢以獲取客戶端的主機名;默認爲true,應設置爲false防止反解客戶端主機;compression
:是否壓縮數據。默認爲off。設置爲on時表示只壓縮text文本,設置爲force時表示壓縮全部內容。應該在壓縮和sendfile之間作個權衡。useSendfile
:該屬性爲NIO的屬性,表示是否啓用sendfile的功能。默認爲true,啓用該屬性將會禁止compression屬性。當協議指定爲HTTP/1.1時,默認會自動在NIO/APR協議處理方式上進行按需切換,如要顯式指定協議,方式以下:
<connector port="8080" protocol="HTTP/1.1">
<connector port="8080" protocol="org.apache.coyote.http11.Http11NioProtocol">
<connector port="8080" protocol="org.apache.coyote.http11.Http11Nio2Protocol">
<connector port="8080" protocol="org.apache.coyote.http11.Http11AprProtocol">
其中NIO是C/C++的非阻塞IO複用模型在JAVA中的IO實現,NIO2即AIO是異步NIO,即異步非阻塞IO:
NioProtocol :non blocking Java NIO connector
Nio2Protocol:non blocking Java NIO2 connector
AprProtocol :the APR/native connector
它們之間的異同點以下表所示:
Java Nio Connector | Java Nio2 Connector | APR/native Connector | |
---|---|---|---|
Classname | Http11NioProtocol | Http11Nio2Protocol | Http11AprProtocol |
Tomcat Version | 6.x onwards | 8.x onwards | 5.5.x onwards |
Support Polling | YES | YES | YES |
Polling Size | maxConnections | maxConnections | maxConnections |
Read Request Headers | Non Blocking | Non Blocking | Non Blocking |
Read Request Body | Blocking | Blocking | Blocking |
Write Response Headers and Body | Blocking | Blocking | Blocking |
Wait for next Request | Non Blocking | Non Blocking | Non Blocking |
SSL Support | Java SSL or OpenSSL | Java SSL or OpenSSL | OpenSSL |
SSL Handshake | Non blocking | Non blocking | Blocking |
Max Connections | maxConnections | maxConnections | maxConnections |
下面是一個定義了多個屬性的SSL鏈接器:
<Connector port="8443" maxThreads="150" minSpareThreads="25" maxSpareThreads="75" enableLookups="false" acceptCount="100" debug="0" scheme="https" secure="true" clientAuth="false" sslProtocol="TLS" />
engine是service組件中用來分析協議的引擎機器,它從一個或多個connector上接收請求,並將請求交給對應的虛擬主機進行處理,最後返回完整的響應數據給connector,經過connector將響應數據返回給客戶端。
只有一個engine元素必須嵌套在每一個service中,且engine必須在其所須要關聯的connector以後,這樣在engine前面的connector均可以被此engine關聯,而在engine後面的connector則被忽略,由於一個service中只容許有一個engine。
定義方式大體以下:
<Engine name="Catalina" defaultHost="localhost">
</Engine>
<Engine name="Standalone" defaultHost="localhost" jvmRoute="TomcatA">
</Engine>
經常使用的engine屬性有:
className
:實現engine的類,該類必須實現org.apache.catalina.Engine接口。不給定該屬性時將採用默認的標準類org.apache.catalina.core.StandardEngine。defaultHost
:指定處理請求的默認虛擬主機。在Engine中定義的多個虛擬主機的主機名稱中至少有一個跟defaultHost定義的主機名稱同名。name
:Engine組件的名稱,用於記錄日誌和錯誤信息,可有可無的屬性,可隨意給定。jvmRoute
:在啓用session粘性時指定使用哪一種負載均衡的標識符。全部的tomcat server實例中該標識符必須惟一,它會追加在session標識符的尾部,所以能讓前端代理老是將特定的session轉發至同一個tomcat實例上。engine是容器中的頂級子容器,其內能夠嵌套一個或多個Host做爲虛擬主機,且至少一個host要和engine中的默認虛擬主機名稱對應。除了host,還能夠嵌套releam和valve組件。
host容器用來定義虛擬主機。engine從connector接收到請求進行分析後,會將相關的屬性參數傳遞給對應的(篩選方式是從請求首部的host字段和虛擬主機名稱進行匹配)虛擬host進行處理。若是沒有合適的虛擬主機,則傳遞給默認虛擬主機。所以每一個容器中必須至少定義一個虛擬主機,且必須有一個虛擬主機和engine容器中定義的默認虛擬主機名稱相同。
大體定義方式以下:
<Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true">
</Host>
經常使用屬性說明:
className
:實現host容器的類,該類必須實現org.apache.catalina.Host接口。不給定該屬性時將採用默認的標準類org.apache.catalina.core.StandardHost。name
:虛擬主機的主機名,忽略大小寫(初始化時會自動轉換爲小寫)。可使用前綴星號通配符,如"*.a.com"。使用了星號前綴的虛擬主機的匹配優先級低於精確名稱的虛擬主機。appBase
:此Host的webapps目錄,即webapp部署在此虛擬主機上時的存放目錄。包括非歸檔的web應用程序目錄和歸檔後的WAR文件的目錄。使用相對路徑時基於$CATALINA_BASE。xmlBase
:部署在此虛擬主機上的context xml目錄。startStopThreads
:啓動context容器時的並行線程數。若是使用了自動部署功能,則再次部署或更新時使用相同的線程池。autoDeploy
:在Tomcat處於運行狀態時放置於appBase目錄中的應用程序文件是否自動進行deploy或自動更新部署狀態。這等於同時開啓了deployOnStartup屬性和reload/redeploy webapp的功能。觸發自動更新時將默認重載該webapp。默認爲true。unpackWars
:在執行此webapps時是否先對歸檔格式的WAR文件解壓再運行,設置爲false時則直接執行WAR文件;默認爲true。設置爲false時會損耗性能。workDir
:該虛擬主機的工做目錄。每一個webapp都有本身的臨時IO目錄,默認該工做目錄爲$CATALINA_BASE/work。大多數時候都只需設置虛擬主機名稱name和webBase屬性便可,其他採用默認,默認時會自動部署webapp。有時候還須要管理多個站點名稱,即主機別名。可使用Alias爲Host指定的主機名定義主機別名。如:
<Host name="web.a.com" appBase="webapps" unpackWARs="true">
<Alias>www.a.com</Alias>
</Host>
自動部署指的是自動裝載webapp以提供相關webapp的服務。
connector和containor是整個tomcat的心臟,而context則是containor的心臟,更是tomcat心臟的心臟。它是真正管理servlet的地方,它的配置影響了servlet的工做方式。
一個context表明一個webapp。servlet中規定,每一個webapp都必須基於已歸檔的WAR(WEB application archive)文件或基於非歸檔相關內容所在目錄。
catalina基於對請求URI與context中定義的path進行最大匹配前綴的規則進行挑選,從中選出使用哪一個context來處理該HTTP請求。這至關於nginx的location容器,catalina的path就至關於location的path,它們的做用是相同的。
每一個context都必須在虛擬主機容器host中有一個惟一的context name。context的path不須要惟一,由於容許同一個webapp不一樣版本的共存部署。此外,必需要有一個context的path爲0長度的字符串(即<Context path="" docBase="ROOT"/>
),該context是該虛擬主機的默認webapp,用於處理全部沒法被虛擬主機中全部context path匹配的請求。
關於context name,它是從context path推斷出來的,不只如此,其他幾個屬性如context basefile name也是由此推斷出來的。規則以下:
例如:
context path context name basefile name deploy examples
-----------------------------------------------------------------
/foo /foo foo foo.xml,foo.war,foo
/foo/bar /foo/bar foo#bar foo#bar.xml,foo#bar.war,foo#bar
Empty String Empty String ROOT ROOT.xml,ROOT.war,ROOT
配置context時,強烈建議不要定義在server.xml中,由於定義conf/server.xml中時,只能經過重啓tomcat來重載生效,也就是說沒法自動部署應用程序了。雖然說官方如此推薦,但大多數人出於習慣和方便,仍是會直接寫在server.xml中,這並無什麼問題,無非是重啓一下而已。
能夠考慮定義在/META-INF/context.xml中,若是此時設置了copyXML屬性,在部署時會將此context.xml複製到$CATALINA_BASE/conf/enginename/hostname/下,並重命名爲"basefile name.xml"。也能夠直接定義在$CATALINA_BASE/conf/enginename/hostname/下的.xml文件中,該路徑的xml優先級高於/META-INF/context.xml。
還能夠定義默認的context.xml文件,包括兩種:(1)定義在$CATALINA_BASE/conf/context.xml中,該默認context對全部webapp都生效;(2)定義在$CATALINA_BASE/conf/[enginename]/[hostname]/context.xml.default中,該默認context只對該虛擬主機中的全部webapp生效。
定義方式大體以下:
<Host name="www.a.com" appBase="webapps" unpackWARs="true" autoDeploy="true">
<Context path="" docBase="ROOT"/>
<Context path="/bbs" docBase="web/bbs" reloadable="true"/>
</Host>
其中第一個context的path爲空字符串,表示它是默認的context。當瀏覽器中輸入www.a.com時,因爲沒法匹配第二個context,因此被默認即第一個context處理,當瀏覽器中輸入www.a.com/bbs時,將被第二個context處理,它將執行web/bbs所對應的webapp,並返回相關內容。
在context容器中能夠定義很是多的屬性,詳細內容見官方手冊,如下是常見的幾個屬性:
className
:實現host容器的類,該類必須實現org.apache.catalina.Context接口。不給定該屬性時將採用默認的標準類org.apache.catalina.core.StandardContext。cookies
:默認爲true,表示啓用cookie來標識session。docBase
:即DocumentRoot,是該webapp的context root,即歸檔WAR文件所在目錄或非歸檔內容所在目錄。能夠是絕對路徑,也能夠是相對於該webapp appBase的相對路徑。path
:定義webapp path。注意,當path=""時,表示默認的context;另外只有在server.xml中才須要定義該屬性,其餘全部狀況下都不能定義該屬性,由於會根據docBase和context的xml文件名推斷出path。reloadable
:是否監控/WEB-INF/class和/WEB-INF/lib兩個目錄中文件的變化,變化時將自動重載。在測試環境下該屬性很好,但在真實生產環境部署應用時不該該設置該屬性,由於監控會大幅增長負載,所以該屬性的默認值爲false。wrapperClass
:實現wrapper容器的類,wrapper用於管理該context中的servlet,該類必須實現org.apache.catalina.Wrapper接口,若是不指定該屬性則採用默認的標準類。xmlNamespaceAware
:和web.xml的解析方式有關。默認爲true,設置爲false能夠提高性能。xmlValidation
:和web.xml的解析方式有關。默認爲true,設置爲false能夠提高性能。realm定義的是一個安全上下文,就像是以哪一種方式存儲認證時的用戶和組相關的數據庫。有多種方式能夠實現數據存放:
下面是一個常見的使用UserDatabase的配置:
<Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase"/>
下面是一個使用JDBC方式獲取用戶認證信息的配置:
<Realm className="org.apache.catalina.realm.JDBCRealm" debug="99" driverName="org.gjt.mm.mysql.Driver" connectionURL="jdbc:mysql://localhost/authority" connectionName="test" connectionPassword="test" userTable="users" userNameCol="user_name" userCredCol="user_pass" userRoleTable="user_roles" roleNameCol="role_name" />
Valve中文意思是閥門,相似於過濾器,它能夠工做於Engine和Host/Context之間、Host和Context之間以及Context和Web應用程序的某資源之間。一個容器內能夠創建多個Valve,並且Valve定義的次序也決定了它們生效的次序。
有多種不一樣的Valve:
其中RemoteHostValve和RemoteAddrValve能夠分別用來實現基於主機名稱和基於IP地址的訪問控制,控制自己能夠經過allow或deny來進行定義,這有點相似於Apache的訪問控制功能。以下面的Valve實現了僅容許本機訪問/probe:
<Context privileged="true" path="/probe" docBase="probe">
<Valve className="org.apache.catalina.valves.RemoteAddrValve" allow="127\.0\.0\.1"/>
</Context>
其中相關屬性定義有:
另一個經常使用的Valve爲AccessLogValve,定義方式大體以下:
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
prefix="localhost_access_log" suffix=".txt"
pattern="%h %l %u %t "%r" %s %b" />
其中prefix和suffix表示日誌文件的前綴名稱和後綴名稱。pattern表示記錄日誌時的信息和格式。