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