溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

基于tomcat配置文件server.xml的示例分析

發(fā)布時間:2021-08-20 14:05:36 來源:億速云 閱讀:134 作者:小新 欄目:服務(wù)器

這篇文章主要介紹了基于tomcat配置文件server.xml的示例分析,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。

1. 入門示例:虛擬主機提供web服務(wù)

該示例通過設(shè)置虛擬主機來提供web服務(wù),因為是入門示例,所以設(shè)置極其簡單,只需修改$CATALINA_HOME/conf/server.xml文件為如下內(nèi)容即可。其中大部分都采用了默認(rèn)設(shè)置,只是在engine容器中添加了兩個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>

<!-- 從此處開始添加以下兩個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 &quot;%r&quot; %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 &quot;%r&quot; %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 &quot;%r&quot; %s %b" />
  </Host>
 </Engine>
 </Service>
</Server>

除了engine中定義的默認(rèn)localhost虛擬主機,另外布置了兩個虛擬主機www.longshuai.com和www.xiaofang.com,它們的程序目錄分別為/www/longshuai和/www/xiaofang,所以需要提前建立好這兩個目錄。另外,在context中定義了docBase,對于uri路徑/xuexi,它的文件系統(tǒng)路徑為/www/{longshuai,xiaofang}/xuexi目錄,所以也要在上面兩個程序根目錄中定義好xuexi目錄。除此之外,還分別為這3個虛擬主機定義了日志,它們的路徑為相對路徑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ū)分讀取的是哪個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

再測試主機上添加www.{longshuai,xiaofang}.com的host記錄。例如在windows上,在C:\Windows\System32\drivers\etc\hosts中添加如下記錄:

192.168.100.22 www.longshuai.com www.xiaofang.com

在瀏覽器中進行測試,結(jié)果如下:

基于tomcat配置文件server.xml的示例分析

2. tomcat體系結(jié)構(gòu)基本說明

如下圖:

基于tomcat配置文件server.xml的示例分析

tomcat高度模塊化,各個模塊之間有嵌套的父子關(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實例的組件,可以監(jiān)聽一個端口,從此端口上可以遠程向該實例發(fā)送shutdown關(guān)閉命令。

service組件是一個邏輯組件,綁定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個容器類組件:engine容器、host容器、context容器和wrapper容器。

engine容器用于從connector組件處接收已建立的TCP連接,還用于接收客戶端發(fā)送的http請求并分析請求,然后按照分析的結(jié)果將相關(guān)參數(shù)傳遞給匹配出的虛擬主機。engine還用于指定默認(rèn)的虛擬主機。

host容器定義虛擬主機,由于tomcat主要是作為servlet容器的,所以為每個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ù)時的配置結(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)配置項,不過在nginx同樣有engine的功能,例如默認(rèn)的虛擬主機,分析URL來判斷請求交給哪個虛擬主機處理等。context容器相當(dāng)于location指令,context容器的path屬性相當(dāng)于location的uri匹配路徑,docBase相當(dāng)于location的中的root指令,即DocumentRoot。

tomcat作為簡單的web服務(wù)程序大致如此,但它的核心畢竟是處理servlet和jsp,它必須得管理好每個webapp。因此,對于tomcat來說,必須要掌握部署webapp的方式。在tomcat上部署webapp時,必須要理解context的概念,對于tomcat而言,每個context都應(yīng)該算是一個webapp,其路徑由docBase決定,該目錄存放的是歸檔的war文件或未歸檔的webapp相關(guān)文件,而host容器中的appBase則是虛擬主機整理webapp的地方,一個appBase下可以有多個webapp,即多個context。

3. tomcat的appBase和docBase詳細說明

這兩貨雖然意義很明確,但"潛規(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是虛擬主機存放webapp的目錄,它可以是相對路徑,也可以是絕對路徑。如果是相對路徑,則相對于$CATALINA_HOME,嚴(yán)格地說是$CATALINA_BASE。

path是URI的匹配路徑,相當(dāng)于nginx的location后的路徑。tomcat要求每個虛擬主機必須配置一個空字符串的path,該條context作為URI無法被明確匹配時的默認(rèn)context,它相當(dāng)于nginx中l(wèi)ocation / {}的作用。

docBase則是每個webapp的存放目錄(或者是已歸檔的war文件),它可以是相對路徑,也可以是絕對路徑,提供相對路徑時它相對于appBase。該目錄一般在appBase的目錄下,但并不規(guī)定一定要放在appBase下。對于web服務(wù)來說,它相當(dāng)于nginx的root指令,但對于webapp來說,一個context就相當(dāng)于一個webapp,而docBase正是webapp的路徑。

"潛規(guī)則"在于默認(rèn)的context如何提供。有以下幾種情況:

1.明確定義了<context path="" docBase=webappPATH>,此時默認(rèn)context的處理路徑為webappPATH。

2.明確定義了<context path="">,但卻沒給定docBase屬性,此時該默認(rèn)context處理路徑為appBase/ROOT目錄,注意ROOT為大寫。

3.完全沒有定義path=""的context時,即host容器中沒有明確的path="",此時將隱式定義一個默認(rèn)context,處理路徑為appBase/ROOT目錄。

4.定義了path但沒有定義docBase屬性時,docBase將根據(jù)path推斷出它的路徑。推斷的規(guī)則如下:

context path context name 推斷出的docBase路徑
--------------------------------------------------
/foo   /foo   foo 
/foo/bar  /foo/bar  foo/bar
Empty String Empty String ROOT

以下是幾個定義示例:

# 虛擬主機中沒有定義任何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>

# 某個context定義了path="",該context將作為默認(rèn)context
# 但該默認(rèn)context沒有定義docBase,將推斷出其docBase路徑為appBase/ROOT
<Host appBase="webapps">
 <Context path="" docBase="webappPATH" />
</Host>

# 某個context定義了path="",該context將作為默認(rèn)context
# 下面的默認(rèn)context明確定義了docBase
<Host appBase="webapps">
 <Context path="" docBase="webappPATH" />
</Host>

4. tomcat配置文件server.xml詳解

tomcat配置文件中配置的是各個組件的屬性,全局配置文件為$CATALINA_HOME/conf/server.xml,主要的組件有以下幾項:Server,Service,Connector,Engine,Host,Alias,Context,Valve等。配置完配置文件后需要重啟tomcat,但在啟動后一定要檢查tomcat是否啟動成功,因為即使出錯,很多時候它都不會報錯,可從監(jiān)聽端口判斷。

配置方法見官方手冊,在頁面的左邊有各個組件的鏈接。

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.定義屬性時有兩種方式:單行定義和多行定義。例如:

<!-- 單行定義的方式 -->
<NAME key=value />

<!-- 多行定義的方式 -->
<NAME key=value>
</NAME>

下面?zhèn)€組件的配置中有些地方使用了相對于$CATALINA_BASE的相對路徑,它和$CATALINA_HOME小有區(qū)別,如果只有一個tomcat實例,則它們是等價的,都是tomcat的安裝路徑。如果有多個tomcat實例,則$CATALINA_HOME表示的是安裝路徑,而$CATALINA_BASE表示的是各實例所在根目錄。關(guān)于tomcat多實例,見running.txt中對應(yīng)的說明。

4.1 頂級元素server

server組件定義的是一個tomcat實例。默認(rèn)定義如下:

<Server port="8005" shutdown="SHUTDOWN">
</Server>

它默認(rèn)監(jiān)聽在8005端口以接收shutdown命令。要啟用多個tomcat實例,將它們監(jiān)聽在不同的端口即可。這個端口的定義為管理員提供一個關(guān)閉實例的便捷途徑,可以直接telnet至此端口使用SHUTDOWN命令關(guān)閉此實例。不過基于安全角度的考慮,通常不允許遠程進行。

Server的相關(guān)屬性:

?className:用于實現(xiàn)此組件的java類的名稱,這個類必須實現(xiàn)接口org.apache.catalina.Server。不給定該屬性時將采用默認(rèn)的標(biāo)準(zhǔn)類org.apache.catalina.core.StandardServer;

?address:監(jiān)聽端口綁定的地址。如不指定,則默認(rèn)為Localhost,即只能在localhost上發(fā)送SHUTDOWN命令;

?port:接收shutdown指令的端口,默認(rèn)僅允許通過本機訪問,默認(rèn)為8005;

?shutdown:通過TCP/IP連接發(fā)往此Server用于實現(xiàn)關(guān)閉tomcat實例的命令字符串。

在server組件中可嵌套一個或多個service組件。

4.2 頂級元素service

定義了service就能提供服務(wù)了。service組件中封裝connector和containor,它同時也表示將此service中的connector和containor綁定起來,即由它們組成一個service向外提供服務(wù)。默認(rèn)定義如下:

<Service name="Catalina">
</Service>

Service相關(guān)的屬性:

?className:用于實現(xiàn)service的類名,這個類必須實現(xiàn)org.apache.catalina.Service接口。不給定該屬性時將采用默認(rèn)的標(biāo)準(zhǔn)類org.apache.catalina.core.StandardService。

?name:此service的顯示名稱,該名稱主要用于在日志中進行標(biāo)識service。一般來說無關(guān)緊要,默認(rèn)為Catalina。

4.3 執(zhí)行器executor

執(zhí)行器定義tomcat各組件之間共享的線程池。在以前,每個connector都會獨自創(chuàng)建自己的線程池,但現(xiàn)在,可以定義一個線程池,各組件都可以共享該線程池,不過主要是為各connector之間提供共享。注意,executor創(chuàng)建的是共享線程池,如果某個connector不引用executor創(chuàng)建的線程池,那么該connector仍會根據(jù)自己指定的屬性創(chuàng)建它們自己的線程池。

連接器必須要實現(xiàn)org.apache.catalina.Executor接口。它是一個嵌套在service組件中的元素,為了挑選所使用的connector,該元素還必須定義在connector元素之前。

默認(rèn)的定義如下:

<Executor name="tomcatThreadPool" namePrefix="catalina-exec-"
  maxThreads="150" minSpareThreads="4"/>

其中該組件的屬性有:

?className:用于實現(xiàn)此組件的java類的名稱,這個類必須實現(xiàn)接口org.apache.catalina.Executor。不給定該屬性時將采用默認(rèn)的標(biāo)準(zhǔn)類org.apache.catalina.core.StandardThreadExecutor;

?name:該線程池的名稱,其他組件需要使用該名稱引用該線程池。

標(biāo)準(zhǔn)類的屬性包括:

?threadPriority:線程優(yōu)先級,默認(rèn)值為5。

?daemon:線程是否以daemon的方式運行,默認(rèn)值為true。

?namePrefix:執(zhí)行器創(chuàng)建每個線程時的名稱前綴,最終線程的名稱為:namePrefix+threadNumber。

?maxThreads:線程池激活的最大線程數(shù)量。默認(rèn)值為200。

?minSpareThreads:線程池中最少空閑的線程數(shù)量。默認(rèn)值為25。

?maxIdleTime:在空閑線程關(guān)閉前的毫秒數(shù)。除非激活的線程數(shù)量小于或等于minSpareThreads的值,否則會有空閑線程的出現(xiàn)。默認(rèn)值為60000,即空閑線程需要保留1分鐘的空閑時間才被殺掉。

?maxQueueSize:可執(zhí)行任務(wù)的最大隊列數(shù),達到隊列上限時的連接請求將被拒絕。

?prestartminSpareThreads:在啟動executor時是否立即創(chuàng)建minSpareThreads個線程數(shù),默認(rèn)為false,即在需要時才創(chuàng)建線程。

例如在connector中指定所使用的線程池,方式如下:

<Connector executor="tomcatThreadPool"
      port="8080" protocol="HTTP/1.1"
      connectionTimeout="20000"
      redirectPort="8443" />

4.4 連接器connector

連接器用于接收客戶端發(fā)送的請求并返回響應(yīng)給客戶端。一個service中可以有多個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啟用它的獨立web服務(wù)功能,當(dāng)然,肯定也提供它必須的servlets和jsp執(zhí)行功能。在一個service中可以配置一個或多個連接器,每個連接器都可以將請求轉(zhuǎn)發(fā)給它們相關(guān)聯(lián)的engine以處理請求、創(chuàng)建響應(yīng)。

如果想要配置某個web server的連接器,則使用AJP協(xié)議。

每個流入的請求都需要一個獨立的線程來接收。當(dāng)并發(fā)請求數(shù)量超出maxThreads指定的值時,多出的請求將被堆疊在套接字中,直到超出acceptCount指定的值。超出accpetCount的請求將以"connection refused"錯誤進行拒絕。

默認(rèn)的定義如下:

<Connector port="8080" protocol="HTTP/1.1"
      connectionTimeout="20000"
      redirectPort="8443" />

HTTP連接器的屬性實在太多,詳細配置方法見官方手冊。通常定義HTTP連接器時必須定義的屬性只有"port"。

?address:指定連接器監(jiān)聽的地址,默認(rèn)為所有地址,即0.0.0.0。

?maxThreads:支持的最大并發(fā)連接數(shù),默認(rèn)為200;如果引用了executor創(chuàng)建的共享線程池,則該屬性被忽略。

?acceptCount:設(shè)置等待隊列的最大長度;通常在tomcat所有處理線程均處于繁忙狀態(tài)時,新發(fā)來的請求將被放置于等待隊列中;

?maxConnections:允許建立的最大連接數(shù)。acceptCount和maxThreads是接受連接的最大線程數(shù)。存在一種情況,maxConnections小于acceptCount時,超出maxConnections的連接請求將被接收,但不會與之建立連接。

?port:監(jiān)聽的端口,默認(rèn)為0,此時表示隨機選一個端口,通常都應(yīng)該顯式指定監(jiān)聽端口。

?protocol:連接器使用的協(xié)議,用于處理對應(yīng)的請求。默認(rèn)為HTTP/1.1,此時它會自動在基于Java NIO或APR/native連接器之間進行切換。定義AJP協(xié)議時通常為AJP/1.3。

?redirectPort:如果某連接器支持的協(xié)議是HTTP,當(dāng)接收客戶端發(fā)來的HTTPS請求時,則轉(zhuǎn)發(fā)至此屬性定義的端口。

?connectionTimeout:等待客戶端發(fā)送請求的超時時間,單位為毫秒,默認(rèn)為60000,即1分鐘;注意,這時候連接已經(jīng)建立。

?keepAliveTimeout:長連接狀態(tài)的超時時間。超出該值時,長連接將關(guān)閉。

?enableLookups:是否通過request.getRemoteHost()進行DNS查詢以獲取客戶端的主機名;默認(rèn)為true,應(yīng)設(shè)置為false防止反解客戶端主機;

?compression:是否壓縮數(shù)據(jù)。默認(rèn)為off。設(shè)置為on時表示只壓縮text文本,設(shè)置為force時表示壓縮所有內(nèi)容。應(yīng)該在壓縮和sendfile之間做個權(quán)衡。

?useSendfile:該屬性為NIO的屬性,表示是否啟用sendfile的功能。默認(rèn)為true,啟用該屬性將會禁止compression屬性。

當(dāng)協(xié)議指定為HTTP/1.1時,默認(rèn)會自動在NIO/APR協(xié)議處理方式上進行按需切換,如要顯式指定協(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實現(xiàn),NIO2即AIO是異步NIO,即異步非阻塞IO:

NioProtocol :non blocking Java NIO connector
Nio2Protocol:non blocking Java NIO2 connector
AprProtocol :the APR/native connector

它們之間的異同點如下表所示:


Java Nio ConnectorJava Nio2 ConnectorAPR/native Connector
ClassnameHttp11NioProtocolHttp11Nio2ProtocolHttp11AprProtocol
Tomcat Version6.x onwards8.x onwards5.5.x onwards
Support PollingYESYESYES
Polling SizemaxConnectionsmaxConnectionsmaxConnections
Read Request HeadersNon BlockingNon BlockingNon Blocking
Read Request BodyBlockingBlockingBlocking
Write Response Headers and BodyBlockingBlockingBlocking
Wait for next RequestNon BlockingNon BlockingNon Blocking
SSL SupportJava SSL or OpenSSLJava SSL or OpenSSLOpenSSL
SSL HandshakeNon blockingNon blockingBlocking
Max ConnectionsmaxConnectionsmaxConnectionsmaxConnections

下面是一個定義了多個屬性的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é)議的引擎機器,它從一個或多個connector上接收請求,并將請求交給對應(yīng)的虛擬主機進行處理,最后返回完整的響應(yīng)數(shù)據(jù)給connector,通過connector將響應(yīng)數(shù)據(jù)返回給客戶端。

只有一個engine元素必須嵌套在每個service中,且engine必須在其所需要關(guān)聯(lián)的connector之后,這樣在engine前面的connector都可以被此engine關(guān)聯(lián),而在engine后面的connector則被忽略,因為一個service中只允許有一個engine。

定義方式大致如下:

<Engine name="Catalina" defaultHost="localhost">
</Engine>

<Engine name="Standalone" defaultHost="localhost" jvmRoute="TomcatA">
</Engine>

常用的engine屬性有:

?className:實現(xiàn)engine的類,該類必須實現(xiàn)org.apache.catalina.Engine接口。不給定該屬性時將采用默認(rèn)的標(biāo)準(zhǔn)類org.apache.catalina.core.StandardEngine。

?defaultHost:指定處理請求的默認(rèn)虛擬主機。在Engine中定義的多個虛擬主機的主機名稱中至少有一個跟defaultHost定義的主機名稱同名。

?name:Engine組件的名稱,用于記錄日志和錯誤信息,無關(guān)緊要的屬性,可隨意給定。

?jvmRoute:在啟用session粘性時指定使用哪種負(fù)載均衡的標(biāo)識符。所有的tomcat server實例中該標(biāo)識符必須唯一,它會追加在session標(biāo)識符的尾部,因此能讓前端代理總是將特定的session轉(zhuǎn)發(fā)至同一個tomcat實例上。

注意,jvmRoute同樣可以使用jvmRoute的系統(tǒng)屬性來設(shè)置。如果此處設(shè)置了jvmRoute,則覆蓋jvmRoute系統(tǒng)屬性。關(guān)于jvmRoute的使用,在后面tomcat ajp負(fù)載均衡的文章中介紹。

engine是容器中的頂級子容器,其內(nèi)可以嵌套一個或多個Host作為虛擬主機,且至少一個host要和engine中的默認(rèn)虛擬主機名稱對應(yīng)。除了host,還可以嵌套releam和valve組件。

4.6 容器類host

host容器用來定義虛擬主機。engine從connector接收到請求進行分析后,會將相關(guān)的屬性參數(shù)傳遞給對應(yīng)的(篩選方式是從請求首部的host字段和虛擬主機名稱進行匹配)虛擬host進行處理。如果沒有合適的虛擬主機,則傳遞給默認(rèn)虛擬主機。因此每個容器中必須至少定義一個虛擬主機,且必須有一個虛擬主機和engine容器中定義的默認(rèn)虛擬主機名稱相同。

大致定義方式如下:

<Host name="localhost" appBase="webapps"
      unpackWARs="true" autoDeploy="true">
</Host>

常用屬性說明:

?className:實現(xiàn)host容器的類,該類必須實現(xiàn)org.apache.catalina.Host接口。不給定該屬性時將采用默認(rèn)的標(biāo)準(zhǔn)類org.apache.catalina.core.StandardHost。

?name:虛擬主機的主機名,忽略大小寫(初始化時會自動轉(zhuǎn)換為小寫)。可以使用前綴星號通配符,如"*.a.com"。使用了星號前綴的虛擬主機的匹配優(yōu)先級低于精確名稱的虛擬主機。

?appBase:此Host的webapps目錄,即webapp部署在此虛擬主機上時的存放目錄。包括非歸檔的web應(yīng)用程序目錄和歸檔后的WAR文件的目錄。使用相對路徑時基于$CATALINA_BASE。

?xmlBase:部署在此虛擬主機上的context xml目錄。

?startStopThreads:啟動context容器時的并行線程數(shù)。如果使用了自動部署功能,則再次部署或更新時使用相同的線程池。

?autoDeploy:在Tomcat處于運行狀態(tài)時放置于appBase目錄中的應(yīng)用程序文件是否自動進行deploy或自動更新部署狀態(tài)。這等于同時開啟了deployOnStartup屬性和reload/redeploy webapp的功能。觸發(fā)自動更新時將默認(rèn)重載該webapp。默認(rèn)為true。

?unpackWars:在執(zhí)行此webapps時是否先對歸檔格式的WAR文件解壓再運行,設(shè)置為false時則直接執(zhí)行WAR文件;默認(rèn)為true。設(shè)置為false時會損耗性能。

?workDir:該虛擬主機的工作目錄。每個webapp都有自己的臨時IO目錄,默認(rèn)該工作目錄為$CATALINA_BASE/work。

大多數(shù)時候都只需設(shè)置虛擬主機名稱name和webBase屬性即可,其余采用默認(rèn),默認(rèn)時會自動部署webapp。有時候還需要管理多個站點名稱,即主機別名??梢允褂肁lias為Host指定的主機名定義主機別名。如:

<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是整個tomcat的心臟,而context則是containor的心臟,更是tomcat心臟的心臟。它是真正管理servlet的地方,它的配置影響了servlet的工作方式。

一個context代表一個webapp。servlet中規(guī)定,每個webapp都必須基于已歸檔的WAR(WEB application archive)文件或基于非歸檔相關(guān)內(nèi)容所在目錄。

catalina基于對請求URI與context中定義的path進行最大匹配前綴的規(guī)則進行挑選,從中選出使用哪個context來處理該HTTP請求。這相當(dāng)于nginx的location容器,catalina的path就相當(dāng)于location的path,它們的作用是相同的。

每個context都必須在虛擬主機容器host中有一個唯一的context name。context的path不需要唯一,因為允許同一個webapp不同版本的共存部署。此外,必須要有一個context的path為0長度的字符串(即<Context path="" docBase="ROOT"/>),該context是該虛擬主機的默認(rèn)webapp,用于處理所有無法被虛擬主機中所有context path匹配的請求。

關(guān)于context name,它是從context path推斷出來的,不僅如此,其余幾個屬性如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時,強烈建議不要定義在server.xml中,因為定義conf/server.xml中時,只能通過重啟tomcat來重載生效,也就是說無法自動部署應(yīng)用程序了。雖說官方如此推薦,但大多數(shù)人出于習(xí)慣和方便,還是會直接寫在server.xml中,這并沒有什么問題,無非是重啟一下而已。

可以考慮定義在/META-INF/context.xml中,如果此時設(shè)置了copyXML屬性,在部署時會將此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只對該虛擬主機中的所有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為空字符串,表示它是默認(rèn)的context。當(dāng)瀏覽器中輸入www.a.com時,由于無法匹配第二個context,所以被默認(rèn)即第一個context處理,當(dāng)瀏覽器中輸入www.a.com/bbs時,將被第二個context處理,它將執(zhí)行web/bbs所對應(yīng)的webapp,并返回相關(guān)內(nèi)容。

在context容器中可以定義非常多的屬性,詳細內(nèi)容見官方手冊,以下是常見的幾個屬性:

?className:實現(xiàn)host容器的類,該類必須實現(xiàn)org.apache.catalina.Context接口。不給定該屬性時將采用默認(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=""時,表示默認(rèn)的context;另外只有在server.xml中才需要定義該屬性,其他所有情況下都不能定義該屬性,因為會根據(jù)docBase和context的xml文件名推斷出path。

?reloadable:是否監(jiān)控/WEB-INF/class和/WEB-INF/lib兩個目錄中文件的變化,變化時將自動重載。在測試環(huán)境下該屬性很好,但在真實生產(chǎn)環(huán)境部署應(yīng)用時不應(yīng)該設(shè)置該屬性,因為監(jiān)控會大幅增加負(fù)載,因此該屬性的默認(rèn)值為false。

?wrapperClass:實現(xiàn)wrapper容器的類,wrapper用于管理該context中的servlet,該類必須實現(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定義的是一個安全上下文,就像是以哪種方式存儲認(rèn)證時的用戶和組相關(guān)的數(shù)據(jù)庫。有多種方式可以實現(xiàn)數(shù)據(jù)存放:

?JAASRealm:基于Java Authintication and Authorization Service實現(xiàn)用戶認(rèn)證;

?JDBCRealm:通過JDBC訪問某關(guān)系型數(shù)據(jù)庫表實現(xiàn)用戶認(rèn)證;

?JNDIRealm:基于JNDI使用目錄服務(wù)實現(xiàn)認(rèn)證信息的獲??;

?MemoryRealm:查找tomcat-user.xml文件實現(xiàn)用戶信息的獲??;

?UserDatabaseRealm:基于UserDatabase文件(通常是tomcat-user.xml)實現(xiàn)用戶認(rèn)證,它實現(xiàn)是一個完全可更新和持久有效的MemoryRealm,因此能夠跟標(biāo)準(zhǔn)的MemoryRealm兼容;它通過JNDI實現(xiàn);

下面是一個常見的使用UserDatabase的配置:

<Realm className="org.apache.catalina.realm.UserDatabaseRealm"
 resourceName="UserDatabase"/>

下面是一個使用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)用程序的某資源之間。一個容器內(nèi)可以建立多個Valve,而且Valve定義的次序也決定了它們生效的次序。

有多種不同的Valve:

?AccessLogValve:訪問日志Valve;

?ExtendedAccessValve:擴展功能的訪問日志Valve;

?JDBCAccessLogValve:通過JDBC將訪問日志信息發(fā)送到數(shù)據(jù)庫中;

?RequestDumperValve:請求轉(zhuǎn)儲Valve;

?RemoteAddrValve:基于遠程地址的訪問控制;

?RemoteHostValve:基于遠程主機名稱的訪問控制;

?SemaphoreValve:用于控制Tomcat主機上任何容器上的并發(fā)訪問數(shù)量;

?JvmRouteBinderValve:在配置多個Tomcat為以Apache通過mod_proxy或mod_jk作為前端的集群架構(gòu)中,當(dāng)期望停止某節(jié)點時,可以通過此Valve將用記請求定向至備用節(jié)點;使用此Valve,必須使用JvmRouteSessionIDBinderListener;

?ReplicationValve:專用于Tomcat集群架構(gòu)中,可以在某個請求的session信息發(fā)生更改時觸發(fā)session數(shù)據(jù)在各節(jié)點間進行復(fù)制;

?SingleSignOn:將兩個或多個需要對用戶進行認(rèn)證webapp在認(rèn)證用戶時連接在一起,即一次認(rèn)證即可訪問所有連接在一起的webapp;

?ClusterSingleSingOn:對SingleSignOn的擴展,專用于Tomcat集群當(dāng)中,需要結(jié)合ClusterSingleSignOnListener進行工作;

其中RemoteHostValve和RemoteAddrValve可以分別用來實現(xiàn)基于主機名稱和基于IP地址的訪問控制,控制本身可以通過allow或deny來進行定義,這有點類似于Apache的訪問控制功能。如下面的Valve實現(xià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:在對應(yīng)位置的后綴上加上".valves.RemoteHostValve"或".valves.RemoteAddrValve";

?allow:以逗號分開的允許訪問的IP地址列表,支持正則,點號“.”用于IP地址時需要轉(zhuǎn)義;僅定義allow項時,非明確allow的地址均被deny;

?deny: 以逗號分開的禁止訪問的IP地址列表,支持正則;使用方式同allow;僅定義deny項時,非明確deny的地址均被allow;

另外一個常用的Valve為AccessLogValve,定義方式大致如下:

<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
        prefix="localhost_access_log" suffix=".txt"
        pattern="%h %l %u %t &quot;%r&quot; %s %b" />

其中prefix和suffix表示日志文件的前綴名稱和后綴名稱。pattern表示記錄日志時的信息和格式。

感謝你能夠認(rèn)真閱讀完這篇文章,希望小編分享的“基于tomcat配置文件server.xml的示例分析”這篇文章對大家有幫助,同時也希望大家多多支持億速云,關(guān)注億速云行業(yè)資訊頻道,更多相關(guān)知識等著你來學(xué)習(xí)!

向AI問一下細節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI