基于tomcat配置文件server.xml詳解
1. 入門(mén)示例:虛擬主機(jī)提供web服務(wù)
該示例通過(guò)設(shè)置虛擬主機(jī)來(lái)提供web服務(wù),因?yàn)槭侨腴T(mén)示例,所以設(shè)置極其簡(jiǎn)單,只需修改$CATALINA_HOME/conf/server.xml文件為如下內(nèi)容即可。其中大部分都采用了默認(rèn)設(shè)置,只是在engine容器中添加了兩個(gè)Host容器。
<?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>
<!-- 從此處開(kāi)始添加以下兩個(gè)Host容器作為虛擬主機(jī) -->
<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中定義的默認(rèn)localhost虛擬主機(jī),另外布置了兩個(gè)虛擬主機(jī)www.longshuai.com和www.xiaofang.com,它們的程序目錄分別為/www/longshuai和/www/xiaofang,所以需要提前建立好這兩個(gè)目錄。另外,在context中定義了docBase,對(duì)于uri路徑/xuexi,它的文件系統(tǒng)路徑為/www/{longshuai,xiaofang}/xuexi目錄,所以也要在上面兩個(gè)程序根目錄中定義好xuexi目錄。除此之外,還分別為這3個(gè)虛擬主機(jī)定義了日志,它們的路徑為相對(duì)路徑logs,相對(duì)于$CATALINA_HOME。
再提供appBase目錄和docBase目錄。
mkdir -p /www/{longshuai,xiaofang}/xuexi
再提供測(cè)試用的index.jsp文件。內(nèi)容大致如下,分別復(fù)制到/www/{longshuai,xiaofang}/和/www/{longshuai,xiaofang}/xuexi/下,并將out.println的輸出內(nèi)容分別稍作修改,使能夠區(qū)分讀取的是哪個(gè)index.jsp。
<%@ page language="java" %>
<%@ page import="java.util.*" %>
<html>
<body>
<% out.println("hello world from longshuai Root"); %>
</body>
</html>
最后重啟catalina。
catalina.sh stop catalina.sh start
再測(cè)試主機(jī)上添加www.{longshuai,xiaofang}.com的host記錄。例如在windows上,在C:\Windows\System32\drivers\etc\hosts中添加如下記錄:
192.168.100.22 www.longshuai.com www.xiaofang.com
在瀏覽器中進(jìn)行測(cè)試,結(jié)果如下:

2. tomcat體系結(jié)構(gòu)基本說(shuō)明
如下圖:

tomcat高度模塊化,各個(gè)模塊之間有嵌套的父子關(guān)系。如果使用配置文件來(lái)描述,可以大致簡(jiǎn)化為如下:
<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組件是工作在后臺(tái)管理tomcat實(shí)例的組件,可以監(jiān)聽(tīng)一個(gè)端口,從此端口上可以遠(yuǎn)程向該實(shí)例發(fā)送shutdown關(guān)閉命令。
service組件是一個(gè)邏輯組件,綁定connector和containor,有了service表示可以向外提供服務(wù),就像是一般的daemon類(lèi)服務(wù)的service。
connector組件是服務(wù)監(jiān)聽(tīng)組件,用于監(jiān)聽(tīng)外界請(qǐng)求并建立TCP連接,然后將連接交給containor,之后可以從此連接傳輸數(shù)據(jù),例如接收http請(qǐng)求,發(fā)送http響應(yīng)等。
containor是容器,在配置文件中沒(méi)有體現(xiàn)出來(lái),它包含4個(gè)容器類(lèi)組件:engine容器、host容器、context容器和wrapper容器。
engine容器用于從connector組件處接收已建立的TCP連接,還用于接收客戶(hù)端發(fā)送的http請(qǐng)求并分析請(qǐng)求,然后按照分析的結(jié)果將相關(guān)參數(shù)傳遞給匹配出的虛擬主機(jī)。engine還用于指定默認(rèn)的虛擬主機(jī)。
host容器定義虛擬主機(jī),由于tomcat主要是作為servlet容器的,所以為每個(gè)web應(yīng)用程序指定了它們的根目錄appBase。
context容器對(duì)應(yīng)servlet容器的處理過(guò)程。還可以指定相關(guān)的wrapper容器類(lèi),當(dāng)然一般都采用默認(rèn)的標(biāo)準(zhǔn)wrapper類(lèi)。
最后當(dāng)請(qǐng)求處理完畢后,context將響應(yīng)數(shù)據(jù)返回給host,再返回給engine,再返回給connector,最后返回給客戶(hù)端。
撇開(kāi)tomcat作為servlet容器的行為。它和apache、nginx的功能大致都能對(duì)應(yīng)上。例如以nginx為例,以下是nginx提供web服務(wù)時(shí)的配置結(jié)構(gòu):
server {
listen PORT;
server_name www.a.com; # 對(duì)應(yīng)于<host name=www.a.com>
location / { # 對(duì)應(yīng)于context path=""
root html; # 對(duì)應(yīng)于docBase
}
location /xuexi { # 對(duì)應(yīng)于context path="/xuexi"
root html/xuexi;
}
}
connetcor組件類(lèi)似于nginx的listen指令。host容器類(lèi)似于nginx的server指令,host容器中的name屬性相當(dāng)于nginx的server_name指令。engine組件則沒(méi)有對(duì)應(yīng)配置項(xiàng),不過(guò)在nginx同樣有engine的功能,例如默認(rèn)的虛擬主機(jī),分析URL來(lái)判斷請(qǐng)求交給哪個(gè)虛擬主機(jī)處理等。context容器相當(dāng)于location指令,context容器的path屬性相當(dāng)于location的uri匹配路徑,docBase相當(dāng)于location的中的root指令,即DocumentRoot。
tomcat作為簡(jiǎn)單的web服務(wù)程序大致如此,但它的核心畢竟是處理servlet和jsp,它必須得管理好每個(gè)webapp。因此,對(duì)于tomcat來(lái)說(shuō),必須要掌握部署webapp的方式。在tomcat上部署webapp時(shí),必須要理解context的概念,對(duì)于tomcat而言,每個(gè)context都應(yīng)該算是一個(gè)webapp,其路徑由docBase決定,該目錄存放的是歸檔的war文件或未歸檔的webapp相關(guān)文件,而host容器中的appBase則是虛擬主機(jī)整理webapp的地方,一個(gè)appBase下可以有多個(gè)webapp,即多個(gè)context。
3. tomcat的appBase和docBase詳細(xì)說(shuō)明
這兩貨雖然意義很明確,但"潛規(guī)則"很?chē)?yán)重。以下面的配置為例。
<host name=www.a.com appBase=/www/a > <context path="" docBase=/www/a /> <context path="/xuexi" docBase=/www/a/xuexi /> </host>
appBase是虛擬主機(jī)存放webapp的目錄,它可以是相對(duì)路徑,也可以是絕對(duì)路徑。如果是相對(duì)路徑,則相對(duì)于$CATALINA_HOME,嚴(yán)格地說(shuō)是$CATALINA_BASE。
path是URI的匹配路徑,相當(dāng)于nginx的location后的路徑。tomcat要求每個(gè)虛擬主機(jī)必須配置一個(gè)空字符串的path,該條context作為URI無(wú)法被明確匹配時(shí)的默認(rèn)context,它相當(dāng)于nginx中l(wèi)ocation / {}的作用。
docBase則是每個(gè)webapp的存放目錄(或者是已歸檔的war文件),它可以是相對(duì)路徑,也可以是絕對(duì)路徑,提供相對(duì)路徑時(shí)它相對(duì)于appBase。該目錄一般在appBase的目錄下,但并不規(guī)定一定要放在appBase下。對(duì)于web服務(wù)來(lái)說(shuō),它相當(dāng)于nginx的root指令,但對(duì)于webapp來(lái)說(shuō),一個(gè)context就相當(dāng)于一個(gè)webapp,而docBase正是webapp的路徑。
"潛規(guī)則"在于默認(rèn)的context如何提供。有以下幾種情況:
1.明確定義了<context path="" docBase=webappPATH>,此時(shí)默認(rèn)context的處理路徑為webappPATH。
2.明確定義了<context path="">,但卻沒(méi)給定docBase屬性,此時(shí)該默認(rèn)context處理路徑為appBase/ROOT目錄,注意ROOT為大寫(xiě)。
3.完全沒(méi)有定義path=""的context時(shí),即host容器中沒(méi)有明確的path="",此時(shí)將隱式定義一個(gè)默認(rèn)context,處理路徑為appBase/ROOT目錄。
4.定義了path但沒(méi)有定義docBase屬性時(shí),docBase將根據(jù)path推斷出它的路徑。推斷的規(guī)則如下:
context path context name 推斷出的docBase路徑 -------------------------------------------------- /foo /foo foo /foo/bar /foo/bar foo/bar Empty String Empty String ROOT
以下是幾個(gè)定義示例:
# 虛擬主機(jī)中沒(méi)有定義任何context,將以appBase下的ROOT作為默認(rèn)處理路徑 <Host appBase="webapps"> </Host> # 沒(méi)有定義path=""的context,但定義了path非空的context,也將以ROOT作為默認(rèn)處理路徑 # 如果下面的Context容器中省略docBase屬性,則推斷出其docBase路徑為appBase/xuexi <Host appBase="webapps"> <Context path="/xuexi" docBase="webappPATH" /> </Host> # 某個(gè)context定義了path="",該context將作為默認(rèn)context # 但該默認(rèn)context沒(méi)有定義docBase,將推斷出其docBase路徑為appBase/ROOT <Host appBase="webapps"> <Context path="" docBase="webappPATH" /> </Host> # 某個(gè)context定義了path="",該context將作為默認(rèn)context # 下面的默認(rèn)context明確定義了docBase <Host appBase="webapps"> <Context path="" docBase="webappPATH" /> </Host>
4. tomcat配置文件server.xml詳解
tomcat配置文件中配置的是各個(gè)組件的屬性,全局配置文件為$CATALINA_HOME/conf/server.xml,主要的組件有以下幾項(xiàng):Server,Service,Connector,Engine,Host,Alias,Context,Valve等。配置完配置文件后需要重啟tomcat,但在啟動(dòng)后一定要檢查tomcat是否啟動(dòng)成功,因?yàn)榧词钩鲥e(cuò),很多時(shí)候它都不會(huì)報(bào)錯(cuò),可從監(jiān)聽(tīng)端口判斷。
配置方法見(jiàn)官方手冊(cè),在頁(yè)面的左邊有各個(gè)組件的鏈接。
tomcat的配置文件都是xml文件,以下是xml文件的常見(jiàn)規(guī)則:
1.文件第一行設(shè)置xml標(biāo)識(shí),表示該文件是xml格式的文件。例如<?xml version="1.0" encoding="UTF-8"?>。
2.xml文件的注釋方法為<!-- XXX -->,這可以是單行注釋?zhuān)部梢远嘈凶⑨專(zhuān)灰昂笞⑨尫?hào)能對(duì)應(yīng)上,中間的內(nèi)容都是注釋。
3.定義屬性時(shí)有兩種方式:?jiǎn)涡卸x和多行定義。例如:
<!-- 單行定義的方式 --> <NAME key=value /> <!-- 多行定義的方式 --> <NAME key=value> </NAME>
下面?zhèn)€組件的配置中有些地方使用了相對(duì)于$CATALINA_BASE的相對(duì)路徑,它和$CATALINA_HOME小有區(qū)別,如果只有一個(gè)tomcat實(shí)例,則它們是等價(jià)的,都是tomcat的安裝路徑。如果有多個(gè)tomcat實(shí)例,則$CATALINA_HOME表示的是安裝路徑,而$CATALINA_BASE表示的是各實(shí)例所在根目錄。關(guān)于tomcat多實(shí)例,見(jiàn)running.txt中對(duì)應(yīng)的說(shuō)明。
4.1 頂級(jí)元素server
server組件定義的是一個(gè)tomcat實(shí)例。默認(rèn)定義如下:
<Server port="8005" shutdown="SHUTDOWN"> </Server>
它默認(rèn)監(jiān)聽(tīng)在8005端口以接收shutdown命令。要啟用多個(gè)tomcat實(shí)例,將它們監(jiān)聽(tīng)在不同的端口即可。這個(gè)端口的定義為管理員提供一個(gè)關(guān)閉實(shí)例的便捷途徑,可以直接telnet至此端口使用SHUTDOWN命令關(guān)閉此實(shí)例。不過(guò)基于安全角度的考慮,通常不允許遠(yuǎn)程進(jìn)行。
Server的相關(guān)屬性:
•className:用于實(shí)現(xiàn)此組件的java類(lèi)的名稱(chēng),這個(gè)類(lèi)必須實(shí)現(xiàn)接口org.apache.catalina.Server。不給定該屬性時(shí)將采用默認(rèn)的標(biāo)準(zhǔn)類(lèi)org.apache.catalina.core.StandardServer;
•address:監(jiān)聽(tīng)端口綁定的地址。如不指定,則默認(rèn)為L(zhǎng)ocalhost,即只能在localhost上發(fā)送SHUTDOWN命令;
•port:接收shutdown指令的端口,默認(rèn)僅允許通過(guò)本機(jī)訪問(wèn),默認(rèn)為8005;
•shutdown:通過(guò)TCP/IP連接發(fā)往此Server用于實(shí)現(xiàn)關(guān)閉tomcat實(shí)例的命令字符串。
在server組件中可嵌套一個(gè)或多個(gè)service組件。
4.2 頂級(jí)元素service
定義了service就能提供服務(wù)了。service組件中封裝connector和containor,它同時(shí)也表示將此service中的connector和containor綁定起來(lái),即由它們組成一個(gè)service向外提供服務(wù)。默認(rèn)定義如下:
<Service name="Catalina"> </Service>
Service相關(guān)的屬性:
•className:用于實(shí)現(xiàn)service的類(lèi)名,這個(gè)類(lèi)必須實(shí)現(xiàn)org.apache.catalina.Service接口。不給定該屬性時(shí)將采用默認(rèn)的標(biāo)準(zhǔn)類(lèi)org.apache.catalina.core.StandardService。
•name:此service的顯示名稱(chēng),該名稱(chēng)主要用于在日志中進(jìn)行標(biāo)識(shí)service。一般來(lái)說(shuō)無(wú)關(guān)緊要,默認(rèn)為Catalina。
4.3 執(zhí)行器executor
執(zhí)行器定義tomcat各組件之間共享的線程池。在以前,每個(gè)connector都會(huì)獨(dú)自創(chuàng)建自己的線程池,但現(xiàn)在,可以定義一個(gè)線程池,各組件都可以共享該線程池,不過(guò)主要是為各connector之間提供共享。注意,executor創(chuàng)建的是共享線程池,如果某個(gè)connector不引用executor創(chuàng)建的線程池,那么該connector仍會(huì)根據(jù)自己指定的屬性創(chuàng)建它們自己的線程池。
連接器必須要實(shí)現(xiàn)org.apache.catalina.Executor接口。它是一個(gè)嵌套在service組件中的元素,為了挑選所使用的connector,該元素還必須定義在connector元素之前。
默認(rèn)的定義如下:
<Executor name="tomcatThreadPool" namePrefix="catalina-exec-" maxThreads="150" minSpareThreads="4"/>
其中該組件的屬性有:
•className:用于實(shí)現(xiàn)此組件的java類(lèi)的名稱(chēng),這個(gè)類(lèi)必須實(shí)現(xiàn)接口org.apache.catalina.Executor。不給定該屬性時(shí)將采用默認(rèn)的標(biāo)準(zhǔn)類(lèi)org.apache.catalina.core.StandardThreadExecutor;
•name:該線程池的名稱(chēng),其他組件需要使用該名稱(chēng)引用該線程池。
標(biāo)準(zhǔn)類(lèi)的屬性包括:
•threadPriority:線程優(yōu)先級(jí),默認(rèn)值為5。
•daemon:線程是否以daemon的方式運(yùn)行,默認(rèn)值為true。
•namePrefix:執(zhí)行器創(chuàng)建每個(gè)線程時(shí)的名稱(chēng)前綴,最終線程的名稱(chēng)為:namePrefix+threadNumber。
•maxThreads:線程池激活的最大線程數(shù)量。默認(rèn)值為200。
•minSpareThreads:線程池中最少空閑的線程數(shù)量。默認(rèn)值為25。
•maxIdleTime:在空閑線程關(guān)閉前的毫秒數(shù)。除非激活的線程數(shù)量小于或等于minSpareThreads的值,否則會(huì)有空閑線程的出現(xiàn)。默認(rèn)值為60000,即空閑線程需要保留1分鐘的空閑時(shí)間才被殺掉。
•maxQueueSize:可執(zhí)行任務(wù)的最大隊(duì)列數(shù),達(dá)到隊(duì)列上限時(shí)的連接請(qǐng)求將被拒絕。
•prestartminSpareThreads:在啟動(dòng)executor時(shí)是否立即創(chuàng)建minSpareThreads個(gè)線程數(shù),默認(rèn)為false,即在需要時(shí)才創(chuàng)建線程。
例如在connector中指定所使用的線程池,方式如下:
<Connector executor="tomcatThreadPool"
port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
4.4 連接器connector
連接器用于接收客戶(hù)端發(fā)送的請(qǐng)求并返回響應(yīng)給客戶(hù)端。一個(gè)service中可以有多個(gè)connector。有多種connector,常見(jiàn)的為http/1.1,http/2和ajp(apache jserv protocol)。在tomcat中,ajp連接協(xié)議類(lèi)型專(zhuān)用于tomcat前端是apache反向代理的情況下。
因此tomcat可以扮演兩種角色:
1.Tomcat僅作為應(yīng)用程序服務(wù)器:請(qǐng)求來(lái)自于前端的web服務(wù)器,這可能是Apache, IIS, Nginx等;
2.Tomcat既作為web服務(wù)器,也作為應(yīng)用程序服務(wù)器:請(qǐng)求來(lái)自于瀏覽器。
Tomcat應(yīng)該考慮工作情形并為相應(yīng)情形下的請(qǐng)求分別定義好需要的連接器才能正確接收來(lái)自于客戶(hù)端的請(qǐng)求。
此處暫先介紹HTTP/1.1連接器的屬性設(shè)置。ajp后文再做介紹。
HTTP連接器表示支持HTTP/1.1協(xié)議的組件。設(shè)置了該連接器就表示catalina啟用它的獨(dú)立web服務(wù)功能,當(dāng)然,肯定也提供它必須的servlets和jsp執(zhí)行功能。在一個(gè)service中可以配置一個(gè)或多個(gè)連接器,每個(gè)連接器都可以將請(qǐng)求轉(zhuǎn)發(fā)給它們相關(guān)聯(lián)的engine以處理請(qǐng)求、創(chuàng)建響應(yīng)。
如果想要配置某個(gè)web server的連接器,則使用AJP協(xié)議。
每個(gè)流入的請(qǐng)求都需要一個(gè)獨(dú)立的線程來(lái)接收。當(dāng)并發(fā)請(qǐng)求數(shù)量超出maxThreads指定的值時(shí),多出的請(qǐng)求將被堆疊在套接字中,直到超出acceptCount指定的值。超出accpetCount的請(qǐng)求將以"connection refused"錯(cuò)誤進(jìn)行拒絕。
默認(rèn)的定義如下:
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
HTTP連接器的屬性實(shí)在太多,詳細(xì)配置方法見(jiàn)官方手冊(cè)。通常定義HTTP連接器時(shí)必須定義的屬性只有"port"。
•address:指定連接器監(jiān)聽(tīng)的地址,默認(rèn)為所有地址,即0.0.0.0。
•maxThreads:支持的最大并發(fā)連接數(shù),默認(rèn)為200;如果引用了executor創(chuàng)建的共享線程池,則該屬性被忽略。
•acceptCount:設(shè)置等待隊(duì)列的最大長(zhǎng)度;通常在tomcat所有處理線程均處于繁忙狀態(tài)時(shí),新發(fā)來(lái)的請(qǐng)求將被放置于等待隊(duì)列中;
•maxConnections:允許建立的最大連接數(shù)。acceptCount和maxThreads是接受連接的最大線程數(shù)。存在一種情況,maxConnections小于acceptCount時(shí),超出maxConnections的連接請(qǐng)求將被接收,但不會(huì)與之建立連接。
•port:監(jiān)聽(tīng)的端口,默認(rèn)為0,此時(shí)表示隨機(jī)選一個(gè)端口,通常都應(yīng)該顯式指定監(jiān)聽(tīng)端口。
•protocol:連接器使用的協(xié)議,用于處理對(duì)應(yīng)的請(qǐng)求。默認(rèn)為HTTP/1.1,此時(shí)它會(huì)自動(dòng)在基于Java NIO或APR/native連接器之間進(jìn)行切換。定義AJP協(xié)議時(shí)通常為AJP/1.3。
•redirectPort:如果某連接器支持的協(xié)議是HTTP,當(dāng)接收客戶(hù)端發(fā)來(lái)的HTTPS請(qǐng)求時(shí),則轉(zhuǎn)發(fā)至此屬性定義的端口。
•connectionTimeout:等待客戶(hù)端發(fā)送請(qǐng)求的超時(shí)時(shí)間,單位為毫秒,默認(rèn)為60000,即1分鐘;注意,這時(shí)候連接已經(jīng)建立。
•keepAliveTimeout:長(zhǎng)連接狀態(tài)的超時(shí)時(shí)間。超出該值時(shí),長(zhǎng)連接將關(guān)閉。
•enableLookups:是否通過(guò)request.getRemoteHost()進(jìn)行DNS查詢(xún)以獲取客戶(hù)端的主機(jī)名;默認(rèn)為true,應(yīng)設(shè)置為false防止反解客戶(hù)端主機(jī);
•compression:是否壓縮數(shù)據(jù)。默認(rèn)為off。設(shè)置為on時(shí)表示只壓縮text文本,設(shè)置為force時(shí)表示壓縮所有內(nèi)容。應(yīng)該在壓縮和sendfile之間做個(gè)權(quán)衡。
•useSendfile:該屬性為NIO的屬性,表示是否啟用sendfile的功能。默認(rèn)為true,啟用該屬性將會(huì)禁止compression屬性。
當(dāng)協(xié)議指定為HTTP/1.1時(shí),默認(rèn)會(huì)自動(dòng)在NIO/APR協(xié)議處理方式上進(jìn)行按需切換,如要顯式指定協(xié)議,方式如下:
<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復(fù)用模型在JAVA中的IO實(shí)現(xiàn),NIO2即AIO是異步NIO,即異步非阻塞IO:
NioProtocol :non blocking Java NIO connector Nio2Protocol:non blocking Java NIO2 connector AprProtocol :the APR/native connector
它們之間的異同點(diǎn)如下表所示:
| 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 |
下面是一個(gè)定義了多個(gè)屬性的SSL連接器:
<Connector port="8443" maxThreads="150" minSpareThreads="25" maxSpareThreads="75" enableLookups="false" acceptCount="100" debug="0" scheme="https" secure="true" clientAuth="false" sslProtocol="TLS" />
4.5 容器類(lèi)engine
engine是service組件中用來(lái)分析協(xié)議的引擎機(jī)器,它從一個(gè)或多個(gè)connector上接收請(qǐng)求,并將請(qǐng)求交給對(duì)應(yīng)的虛擬主機(jī)進(jìn)行處理,最后返回完整的響應(yīng)數(shù)據(jù)給connector,通過(guò)connector將響應(yīng)數(shù)據(jù)返回給客戶(hù)端。
只有一個(gè)engine元素必須嵌套在每個(gè)service中,且engine必須在其所需要關(guān)聯(lián)的connector之后,這樣在engine前面的connector都可以被此engine關(guān)聯(lián),而在engine后面的connector則被忽略,因?yàn)橐粋€(gè)service中只允許有一個(gè)engine。
定義方式大致如下:
<Engine name="Catalina" defaultHost="localhost"> </Engine> <Engine name="Standalone" defaultHost="localhost" jvmRoute="TomcatA"> </Engine>
常用的engine屬性有:
•className:實(shí)現(xiàn)engine的類(lèi),該類(lèi)必須實(shí)現(xiàn)org.apache.catalina.Engine接口。不給定該屬性時(shí)將采用默認(rèn)的標(biāo)準(zhǔn)類(lèi)org.apache.catalina.core.StandardEngine。
•defaultHost:指定處理請(qǐng)求的默認(rèn)虛擬主機(jī)。在Engine中定義的多個(gè)虛擬主機(jī)的主機(jī)名稱(chēng)中至少有一個(gè)跟defaultHost定義的主機(jī)名稱(chēng)同名。
•name:Engine組件的名稱(chēng),用于記錄日志和錯(cuò)誤信息,無(wú)關(guān)緊要的屬性,可隨意給定。
•jvmRoute:在啟用session粘性時(shí)指定使用哪種負(fù)載均衡的標(biāo)識(shí)符。所有的tomcat server實(shí)例中該標(biāo)識(shí)符必須唯一,它會(huì)追加在session標(biāo)識(shí)符的尾部,因此能讓前端代理總是將特定的session轉(zhuǎn)發(fā)至同一個(gè)tomcat實(shí)例上。
注意,jvmRoute同樣可以使用jvmRoute的系統(tǒng)屬性來(lái)設(shè)置。如果此處設(shè)置了jvmRoute,則覆蓋jvmRoute系統(tǒng)屬性。關(guān)于jvmRoute的使用,在后面tomcat ajp負(fù)載均衡的文章中介紹。
engine是容器中的頂級(jí)子容器,其內(nèi)可以嵌套一個(gè)或多個(gè)Host作為虛擬主機(jī),且至少一個(gè)host要和engine中的默認(rèn)虛擬主機(jī)名稱(chēng)對(duì)應(yīng)。除了host,還可以嵌套releam和valve組件。
4.6 容器類(lèi)host
host容器用來(lái)定義虛擬主機(jī)。engine從connector接收到請(qǐng)求進(jìn)行分析后,會(huì)將相關(guān)的屬性參數(shù)傳遞給對(duì)應(yīng)的(篩選方式是從請(qǐng)求首部的host字段和虛擬主機(jī)名稱(chēng)進(jìn)行匹配)虛擬host進(jìn)行處理。如果沒(méi)有合適的虛擬主機(jī),則傳遞給默認(rèn)虛擬主機(jī)。因此每個(gè)容器中必須至少定義一個(gè)虛擬主機(jī),且必須有一個(gè)虛擬主機(jī)和engine容器中定義的默認(rèn)虛擬主機(jī)名稱(chēng)相同。
大致定義方式如下:
<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true">
</Host>
常用屬性說(shuō)明:
•className:實(shí)現(xiàn)host容器的類(lèi),該類(lèi)必須實(shí)現(xiàn)org.apache.catalina.Host接口。不給定該屬性時(shí)將采用默認(rèn)的標(biāo)準(zhǔn)類(lèi)org.apache.catalina.core.StandardHost。
•name:虛擬主機(jī)的主機(jī)名,忽略大小寫(xiě)(初始化時(shí)會(huì)自動(dòng)轉(zhuǎn)換為小寫(xiě))??梢允褂们熬Y星號(hào)通配符,如"*.a.com"。使用了星號(hào)前綴的虛擬主機(jī)的匹配優(yōu)先級(jí)低于精確名稱(chēng)的虛擬主機(jī)。
•appBase:此Host的webapps目錄,即webapp部署在此虛擬主機(jī)上時(shí)的存放目錄。包括非歸檔的web應(yīng)用程序目錄和歸檔后的WAR文件的目錄。使用相對(duì)路徑時(shí)基于$CATALINA_BASE。
•xmlBase:部署在此虛擬主機(jī)上的context xml目錄。
•startStopThreads:?jiǎn)?dòng)context容器時(shí)的并行線程數(shù)。如果使用了自動(dòng)部署功能,則再次部署或更新時(shí)使用相同的線程池。
•autoDeploy:在Tomcat處于運(yùn)行狀態(tài)時(shí)放置于appBase目錄中的應(yīng)用程序文件是否自動(dòng)進(jìn)行deploy或自動(dòng)更新部署狀態(tài)。這等于同時(shí)開(kāi)啟了deployOnStartup屬性和reload/redeploy webapp的功能。觸發(fā)自動(dòng)更新時(shí)將默認(rèn)重載該webapp。默認(rèn)為true。
•unpackWars:在執(zhí)行此webapps時(shí)是否先對(duì)歸檔格式的WAR文件解壓再運(yùn)行,設(shè)置為false時(shí)則直接執(zhí)行WAR文件;默認(rèn)為true。設(shè)置為false時(shí)會(huì)損耗性能。
•workDir:該虛擬主機(jī)的工作目錄。每個(gè)webapp都有自己的臨時(shí)IO目錄,默認(rèn)該工作目錄為$CATALINA_BASE/work。
大多數(shù)時(shí)候都只需設(shè)置虛擬主機(jī)名稱(chēng)name和webBase屬性即可,其余采用默認(rèn),默認(rèn)時(shí)會(huì)自動(dòng)部署webapp。有時(shí)候還需要管理多個(gè)站點(diǎn)名稱(chēng),即主機(jī)別名??梢允褂肁lias為Host指定的主機(jī)名定義主機(jī)別名。如:
<Host name="web.a.com" appBase="webapps" unpackWARs="true"> <Alias>www.a.com</Alias> </Host>
自動(dòng)部署指的是自動(dòng)裝載webapp以提供相關(guān)webapp的服務(wù)。
4.7 容器類(lèi)context
connector和containor是整個(gè)tomcat的心臟,而context則是containor的心臟,更是tomcat心臟的心臟。它是真正管理servlet的地方,它的配置影響了servlet的工作方式。
一個(gè)context代表一個(gè)webapp。servlet中規(guī)定,每個(gè)webapp都必須基于已歸檔的WAR(WEB application archive)文件或基于非歸檔相關(guān)內(nèi)容所在目錄。
catalina基于對(duì)請(qǐng)求URI與context中定義的path進(jìn)行最大匹配前綴的規(guī)則進(jìn)行挑選,從中選出使用哪個(gè)context來(lái)處理該HTTP請(qǐng)求。這相當(dāng)于nginx的location容器,catalina的path就相當(dāng)于location的path,它們的作用是相同的。
每個(gè)context都必須在虛擬主機(jī)容器host中有一個(gè)唯一的context name。context的path不需要唯一,因?yàn)樵试S同一個(gè)webapp不同版本的共存部署。此外,必須要有一個(gè)context的path為0長(zhǎng)度的字符串(即<Context path="" docBase="ROOT"/>),該context是該虛擬主機(jī)的默認(rèn)webapp,用于處理所有無(wú)法被虛擬主機(jī)中所有context path匹配的請(qǐng)求。
關(guān)于context name,它是從context path推斷出來(lái)的,不僅如此,其余幾個(gè)屬性如context basefile name也是由此推斷出來(lái)的。規(guī)則如下:
•如果path不為空,則context name等于context path,basefile name取path中去除前綴"/"后的路徑,且所有"/"替換為"#"。
•如果path為空,則context name也為空,而basefile為ROOT(注意是大寫(xiě))。
例如:
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時(shí),強(qiáng)烈建議不要定義在server.xml中,因?yàn)槎xconf/server.xml中時(shí),只能通過(guò)重啟tomcat來(lái)重載生效,也就是說(shuō)無(wú)法自動(dòng)部署應(yīng)用程序了。雖說(shuō)官方如此推薦,但大多數(shù)人出于習(xí)慣和方便,還是會(huì)直接寫(xiě)在server.xml中,這并沒(méi)有什么問(wèn)題,無(wú)非是重啟一下而已。
可以考慮定義在/META-INF/context.xml中,如果此時(shí)設(shè)置了copyXML屬性,在部署時(shí)會(huì)將此context.xml復(fù)制到$CATALINA_BASE/conf/enginename/hostname/下,并重命名為"basefile name.xml"。也可以直接定義在$CATALINA_BASE/conf/enginename/hostname/下的.xml文件中,該路徑的xml優(yōu)先級(jí)高于/META-INF/context.xml。
還可以定義默認(rèn)的context.xml文件,包括兩種:(1)定義在$CATALINA_BASE/conf/context.xml中,該默認(rèn)context對(duì)所有webapp都生效;(2)定義在$CATALINA_BASE/conf/[enginename]/[hostname]/context.xml.default中,該默認(rèn)context只對(duì)該虛擬主機(jī)中的所有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>
其中第一個(gè)context的path為空字符串,表示它是默認(rèn)的context。當(dāng)瀏覽器中輸入www.a.com時(shí),由于無(wú)法匹配第二個(gè)context,所以被默認(rèn)即第一個(gè)context處理,當(dāng)瀏覽器中輸入www.a.com/bbs時(shí),將被第二個(gè)context處理,它將執(zhí)行web/bbs所對(duì)應(yīng)的webapp,并返回相關(guān)內(nèi)容。
在context容器中可以定義非常多的屬性,詳細(xì)內(nèi)容見(jiàn)官方手冊(cè),以下是常見(jiàn)的幾個(gè)屬性:
•className:實(shí)現(xiàn)host容器的類(lèi),該類(lèi)必須實(shí)現(xiàn)org.apache.catalina.Context接口。不給定該屬性時(shí)將采用默認(rèn)的標(biāo)準(zhǔn)類(lèi)org.apache.catalina.core.StandardContext。
•cookies:默認(rèn)為true,表示啟用cookie來(lái)標(biāo)識(shí)session。
•docBase:即DocumentRoot,是該webapp的context root,即歸檔WAR文件所在目錄或非歸檔內(nèi)容所在目錄??梢允墙^對(duì)路徑,也可以是相對(duì)于該webapp appBase的相對(duì)路徑。
•path:定義webapp path。注意,當(dāng)path=""時(shí),表示默認(rèn)的context;另外只有在server.xml中才需要定義該屬性,其他所有情況下都不能定義該屬性,因?yàn)闀?huì)根據(jù)docBase和context的xml文件名推斷出path。
•reloadable:是否監(jiān)控/WEB-INF/class和/WEB-INF/lib兩個(gè)目錄中文件的變化,變化時(shí)將自動(dòng)重載。在測(cè)試環(huán)境下該屬性很好,但在真實(shí)生產(chǎn)環(huán)境部署應(yīng)用時(shí)不應(yīng)該設(shè)置該屬性,因?yàn)楸O(jiān)控會(huì)大幅增加負(fù)載,因此該屬性的默認(rèn)值為false。
•wrapperClass:實(shí)現(xiàn)wrapper容器的類(lèi),wrapper用于管理該context中的servlet,該類(lèi)必須實(shí)現(xiàn)org.apache.catalina.Wrapper接口,如果不指定該屬性則采用默認(rèn)的標(biāo)準(zhǔn)類(lèi)。
•xmlNamespaceAware:和web.xml的解析方式有關(guān)。默認(rèn)為true,設(shè)置為false可以提升性能。
•xmlValidation:和web.xml的解析方式有關(guān)。默認(rèn)為true,設(shè)置為false可以提升性能。
4.8 被嵌套類(lèi)realm
realm定義的是一個(gè)安全上下文,就像是以哪種方式存儲(chǔ)認(rèn)證時(shí)的用戶(hù)和組相關(guān)的數(shù)據(jù)庫(kù)。有多種方式可以實(shí)現(xiàn)數(shù)據(jù)存放:
•JAASRealm:基于Java Authintication and Authorization Service實(shí)現(xiàn)用戶(hù)認(rèn)證;
•JDBCRealm:通過(guò)JDBC訪問(wèn)某關(guān)系型數(shù)據(jù)庫(kù)表實(shí)現(xiàn)用戶(hù)認(rèn)證;
•JNDIRealm:基于JNDI使用目錄服務(wù)實(shí)現(xiàn)認(rèn)證信息的獲??;
•MemoryRealm:查找tomcat-user.xml文件實(shí)現(xiàn)用戶(hù)信息的獲??;
•UserDatabaseRealm:基于UserDatabase文件(通常是tomcat-user.xml)實(shí)現(xiàn)用戶(hù)認(rèn)證,它實(shí)現(xiàn)是一個(gè)完全可更新和持久有效的MemoryRealm,因此能夠跟標(biāo)準(zhǔn)的MemoryRealm兼容;它通過(guò)JNDI實(shí)現(xiàn);
下面是一個(gè)常見(jiàn)的使用UserDatabase的配置:
<Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase"/>
下面是一個(gè)使用JDBC方式獲取用戶(hù)認(rèn)證信息的配置:
<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" />
4.9 被嵌套類(lèi)valve
Valve中文意思是閥門(mén),類(lèi)似于過(guò)濾器,它可以工作于Engine和Host/Context之間、Host和Context之間以及Context和Web應(yīng)用程序的某資源之間。一個(gè)容器內(nèi)可以建立多個(gè)Valve,而且Valve定義的次序也決定了它們生效的次序。
有多種不同的Valve:
•AccessLogValve:訪問(wèn)日志Valve;
•ExtendedAccessValve:擴(kuò)展功能的訪問(wèn)日志Valve;
•JDBCAccessLogValve:通過(guò)JDBC將訪問(wèn)日志信息發(fā)送到數(shù)據(jù)庫(kù)中;
•RequestDumperValve:請(qǐng)求轉(zhuǎn)儲(chǔ)Valve;
•RemoteAddrValve:基于遠(yuǎn)程地址的訪問(wèn)控制;
•RemoteHostValve:基于遠(yuǎn)程主機(jī)名稱(chēng)的訪問(wèn)控制;
•SemaphoreValve:用于控制Tomcat主機(jī)上任何容器上的并發(fā)訪問(wèn)數(shù)量;
•JvmRouteBinderValve:在配置多個(gè)Tomcat為以Apache通過(guò)mod_proxy或mod_jk作為前端的集群架構(gòu)中,當(dāng)期望停止某節(jié)點(diǎn)時(shí),可以通過(guò)此Valve將用記請(qǐng)求定向至備用節(jié)點(diǎn);使用此Valve,必須使用JvmRouteSessionIDBinderListener;
•ReplicationValve:專(zhuān)用于Tomcat集群架構(gòu)中,可以在某個(gè)請(qǐng)求的session信息發(fā)生更改時(shí)觸發(fā)session數(shù)據(jù)在各節(jié)點(diǎn)間進(jìn)行復(fù)制;
•SingleSignOn:將兩個(gè)或多個(gè)需要對(duì)用戶(hù)進(jìn)行認(rèn)證webapp在認(rèn)證用戶(hù)時(shí)連接在一起,即一次認(rèn)證即可訪問(wèn)所有連接在一起的webapp;
•ClusterSingleSingOn:對(duì)SingleSignOn的擴(kuò)展,專(zhuān)用于Tomcat集群當(dāng)中,需要結(jié)合ClusterSingleSignOnListener進(jìn)行工作;
其中RemoteHostValve和RemoteAddrValve可以分別用來(lái)實(shí)現(xiàn)基于主機(jī)名稱(chēng)和基于IP地址的訪問(wèn)控制,控制本身可以通過(guò)allow或deny來(lái)進(jìn)行定義,這有點(diǎn)類(lèi)似于Apache的訪問(wèn)控制功能。如下面的Valve實(shí)現(xiàn)了僅允許本機(jī)訪問(wèn)/probe:
<Context privileged="true" path="/probe" docBase="probe"> <Valve className="org.apache.catalina.valves.RemoteAddrValve" allow="127\.0\.0\.1"/> </Context>
其中相關(guān)屬性定義有:
•className:在對(duì)應(yīng)位置的后綴上加上".valves.RemoteHostValve"或".valves.RemoteAddrValve";
•allow:以逗號(hào)分開(kāi)的允許訪問(wèn)的IP地址列表,支持正則,點(diǎn)號(hào)“.”用于IP地址時(shí)需要轉(zhuǎn)義;僅定義allow項(xiàng)時(shí),非明確allow的地址均被deny;
•deny: 以逗號(hào)分開(kāi)的禁止訪問(wèn)的IP地址列表,支持正則;使用方式同allow;僅定義deny項(xiàng)時(shí),非明確deny的地址均被allow;
另外一個(gè)常用的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表示日志文件的前綴名稱(chēng)和后綴名稱(chēng)。pattern表示記錄日志時(shí)的信息和格式。
以上這篇基于tomcat配置文件server.xml詳解就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
親測(cè)有效解決Tomcat啟動(dòng)提示錯(cuò)誤:At?least?one?JAR?was?scanned?for?T
這篇文章主要介紹了Tomcat啟動(dòng)提示錯(cuò)誤:At?least?one?JAR?was?scanned?for?TLDs?yet?contained?no?TLDs的問(wèn)題及解決方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-05-05
解決運(yùn)行Tomcat之后仍然出現(xiàn)404的問(wèn)題
這篇文章主要介紹了解決運(yùn)行Tomcat之后仍然出現(xiàn)404的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-11-11
Tomcat服務(wù)器的配置與啟動(dòng)全過(guò)程
這篇文章主要介紹了Tomcat服務(wù)器的配置與啟動(dòng)全過(guò)程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-03-03
eclipse啟動(dòng)tomcat無(wú)法訪問(wèn)的解決
這篇文章主要介紹了eclipse啟動(dòng)tomcat無(wú)法訪問(wèn)的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-11-11
Tomcat中連接器(Connector)的實(shí)現(xiàn)
Tomcat中的連接器負(fù)責(zé)處理客戶(hù)端通信,支持HTTP、HTTPS和AJP協(xié)議,通過(guò)配置連接器,可以滿(mǎn)足不同的部署需求,包括端口、協(xié)議和SSL參數(shù),正確配置連接器是確保Tomcat服務(wù)器高效運(yùn)行和安全的關(guān)鍵2024-11-11

