1. 程式人生 > >Tomcat配置檔案解析

Tomcat配置檔案解析

Tomcat作為一個開源的輕量級web容器,使用非常廣泛; 其配置檔案一般都在 server.xml中配置;

server.xml中的每一個元素都對應tomcat的一個元件,位於 tomcat的conf目錄下面

一個完整的 server.xml(tomcat 7)

<?xml version='1.0' encoding='utf-8'?>
<!--
  Licensed to the Apache Software Foundation (ASF) under one or more
  contributor license agreements.  See the NOTICE file distributed with
  this work for additional information regarding copyright ownership.
  The ASF licenses this file to You under the Apache License, Version 2.0
  (the "License"); you may not use this file except in compliance with
  the License.  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
-->
<!-- Note:  A "Server" is not itself a "Container", so you may not
     define subcomponents such as "Valves" at this level.
     Documentation at /docs/config/server.html
 -->
<Server port="8005" shutdown="SHUTDOWN">
  <Listener className="org.apache.catalina.startup.VersionLoggerListener" />
  <!-- Security listener. Documentation at /docs/config/listeners.html
  <Listener className="org.apache.catalina.security.SecurityListener" />
  -->
  <!--APR library loader. Documentation at /docs/apr.html -->
  <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
  <!--Initialize Jasper prior to webapps are loaded. Documentation at /docs/jasper-howto.html -->
  <Listener className="org.apache.catalina.core.JasperListener" />
  <!-- Prevent memory leaks due to use of particular java/javax APIs-->
  <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
  <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
  <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />

  <!-- Global JNDI resources
       Documentation at /docs/jndi-resources-howto.html
  -->
  <GlobalNamingResources>
    <!-- Editable user database that can also be used by
         UserDatabaseRealm to authenticate users
    -->
    <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>

  <!-- A "Service" is a collection of one or more "Connectors" that share
       a single "Container" Note:  A "Service" is not itself a "Container",
       so you may not define subcomponents such as "Valves" at this level.
       Documentation at /docs/config/service.html
   -->
  <Service name="Catalina">

    <!--The connectors can use a shared executor, you can define one or more named thread pools-->
    <!--
    <Executor name="tomcatThreadPool" namePrefix="catalina-exec-"
        maxThreads="150" minSpareThreads="4"/>
    -->


    <!-- A "Connector" represents an endpoint by which requests are received
         and responses are returned. Documentation at :
         Java HTTP Connector: /docs/config/http.html (blocking & non-blocking)
         Java AJP  Connector: /docs/config/ajp.html
         APR (HTTP/AJP) Connector: /docs/apr.html
         Define a non-SSL HTTP/1.1 Connector on port 8080
    -->
    <Connector port="80" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" 
			  URIencoding= "utf-8"/>
    <!-- A "Connector" using the shared thread pool-->
    <!--
    <Connector executor="tomcatThreadPool"
               port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" />
    -->
    <!-- Define a SSL HTTP/1.1 Connector on port 8443
         This connector uses the BIO implementation that requires the JSSE
         style configuration. When using the APR/native implementation, the
         OpenSSL style configuration is required as described in the APR/native
         documentation -->
    <!--
    <Connector port="8443" protocol="org.apache.coyote.http11.Http11Protocol"
               maxThreads="150" SSLEnabled="true" scheme="https" secure="true"
               clientAuth="false" sslProtocol="TLS" />
    -->

    <!-- Define an AJP 1.3 Connector on port 8009 -->
    <Connector port="8009" protocol="AJP/1.3" redirectPort="8443"  URIencoding= "utf-8"/>


    <!-- An Engine represents the entry point (within Catalina) that processes
         every request.  The Engine implementation for Tomcat stand alone
         analyzes the HTTP headers included with the request, and passes them
         on to the appropriate Host (virtual host).
         Documentation at /docs/config/engine.html -->

    <!-- You should set jvmRoute to support load-balancing via AJP ie :
    <Engine name="Catalina" defaultHost="localhost" jvmRoute="jvm1">
    -->
    <Engine name="Catalina" defaultHost="localhost">

      <!--For clustering, please take a look at documentation at:
          /docs/cluster-howto.html  (simple how to)
          /docs/config/cluster.html (reference documentation) -->
      <!--
      <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>
      -->

      <!-- Use the LockOutRealm to prevent attempts to guess user passwords
           via a brute-force attack -->
      <Realm className="org.apache.catalina.realm.LockOutRealm">
        <!-- This Realm uses the UserDatabase configured in the global JNDI
             resources under the key "UserDatabase".  Any edits
             that are performed against this UserDatabase are immediately
             available for use by the Realm.  -->
        <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
               resourceName="UserDatabase"/>
      </Realm>

     <Host name="localhost"  appBase="webapps"
            unpackWARs="true" autoDeploy="true"
            xmlValidation="false" xmlNamespaceAware="false">
			
    <Context path="/gdda45_hdlgdx" docBase="D:\1ZX\svn\gdda45_hdlgdx"  crossContext="true" />
   
		<!-- SingleSignOn valve, share authentication between web applications
             Documentation at: /docs/config/valve.html -->
        <!--
        <Valve className="org.apache.catalina.authenticator.SingleSignOn" />
        -->

        <!-- Access log processes all example.
             Documentation at: /docs/config/valve.html
             Note: The pattern used is equivalent to using pattern="common" -->
        <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>

整體的結構大致如下

<?xml version='1.0' encoding='utf-8'?>
<Server  >
<Listener className=".." />

    <Service>
        <Connector />
            <Engine>
                 <Host>
                     <Context />
                  </Host>       

            </Engine>
        

    </Service>

</Server>

頂層節點 Server,Service

  Server是整個配置的根元素, 表示一個tomcat容器, 必須是最外部的節點,一個Server可以有一個或多個Service節點

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

port屬性表示Server接收shutdown指令的埠號,設為-1可以禁掉該埠。

Server的主要任務,就是提供一個介面讓客戶端能夠訪問到這個Service集合,同時維護它所包含的所有的Service的宣告週期,包括如何初始化、如何結束服務、如何找到客戶端要訪問的Service。

 

<Service>元素則代表一個Engine元素以及一組與之相連的Connector元素。

Service的作用,是在Connector和Engine外面包了一層,把它們組裝在一起,對外提供服務。一個Service可以包含多個Connector,但是隻能包含一個Engine;其中Connector的作用是從客戶端接收請求,Engine的作用是處理接收進來的請求。

 

聯結器節點 : Connector

代表外部發送的請求的配置資訊,以及客戶端接收的配置資訊,即外部客戶端傳送請求到特定Service的介面;同時也是外部客戶端從特定Service接收響應的介面。

Connector的主要功能,是接收連線請求,建立Request和Response物件用於和請求端交換資料;然後分配執行緒讓Engine來處理這個請求,並把產生的Request和Response物件傳給Engine。

通過配置Connector,可以控制請求Service的協議及埠號。

 <Connector port="80" protocol="HTTP/1.1" connectionTimeout="20000"  redirectPort="8443"  URIencoding= "utf-8"/>

通過配置這個Connector,客戶端可以通過80埠號使用http協議訪問Tomcat。其中,protocol屬性規定了請求的協議,port規定了請求的埠號,redirectPort表示當強制要求https而請求是http時,重定向至埠號為8443的Connector,connectionTimeout表示連線的超時時間,URIencoding= "utf-8" 設定編碼格式。

 <Connector port="8009" protocol="AJP/1.3" redirectPort="8443"  URIencoding= "utf-8"/>

通過配置這個Connector,客戶端可以通過8009埠號使用AJP協議訪問Tomcat。AJP協議負責和其他的HTTP伺服器(如Apache)建立連線;在把Tomcat與其他HTTP伺服器整合時,就需要用到這個聯結器。之所以使用Tomcat和其他伺服器整合,是因為Tomcat可以用作Servlet/JSP容器,但是對靜態資源的處理速度較慢,不如Apache和IIS等HTTP伺服器;因此常常將Tomcat與Apache等整合,前者作Servlet容器,後者處理靜態資源,而AJP協議便負責Tomcat和Apache的連線

容器 Engine,Host,Context

容器能夠對聯結器接接收的請求進行接收並處理,  Engine,Host,Context 都是容器,他們是父子的關係,一個Engine元件可以處理Service中的所有請求,一個Host元件可以處理髮向一個特定虛擬主機的所有請求,一個Context元件可以處理一個特定Web應用的所有請求。

Engine

Engine元件在Service元件中有且只有一個;Engine是Service元件中的請求處理元件。Engine元件從一個或多個Connector中接收請求並處理,並將完成的響應返回給Connector,最終傳遞給客戶端。

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

name屬性用於日誌和錯誤資訊,在整個Server中應該唯一。defaultHost屬性指定了預設的host名稱,當發往本機的請求指定的host名稱不存在時,一律使用defaultHost指定的host進行處理;因此,defaultHost的值,必須與Engine中的一個Host元件的name屬性值匹配。

Host

Host是Engine的子容器。Engine元件中可以內嵌1個或多個Host元件,每個Host元件代表Engine中的一個虛擬主機。Host元件至少有一個,且其中一個的name必須與Engine元件的defaultHost屬性相匹配。

Host虛擬主機的作用,是執行多個Web應用(一個Context代表一個Web應用),並負責安裝、展開、啟動和結束每個Web應用。

Host元件代表的虛擬主機,對應了伺服器中一個網路名實體(如”www.test.com”,或IP地址”116.25.25.25”);為了使使用者可以通過網路名連線Tomcat伺服器,這個名字應該在DNS伺服器上註冊。

客戶端通常使用主機名來標識它們希望連線的伺服器;該主機名也會包含在HTTP請求頭中。Tomcat從HTTP頭中提取出主機名,尋找名稱匹配的主機。如果沒有匹配,請求將傳送至預設主機。因此預設主機不需要是在DNS伺服器中註冊的網路名,因為任何與所有Host名稱不匹配的請求,都會路由至預設主機。

 <Host name="localhost"  appBase="webapps"
            unpackWARs="true" autoDeploy="true"
            xmlValidation="false" xmlNamespaceAware="false">

name屬性指定虛擬主機的主機名,一個Engine中有且僅有一個Host元件的name屬性與Engine元件的defaultHost屬性相匹配;一般情況下,主機名需要是在DNS伺服器中註冊的網路名,但是Engine指定的defaultHost不需要,原因在前面已經說明。

unpackWARs指定了是否將代表Web應用的WAR檔案解壓;如果為true,通過解壓後的檔案結構執行該Web應用,如果為false,直接使用WAR檔案執行Web應用。

Host的autoDeploy和appBase屬性,與Host內Web應用的自動部署有關;此外,本例中沒有出現的xmlBase和deployOnStartup屬性,也與Web應用的自動部署有關;

Context

(1)Context的作用

Context元素代表在特定虛擬主機上執行的一個Web應用。每個Web應用基於WAR檔案,或WAR檔案解壓後對應的目錄

Context是Host的子容器,每個Host中可以定義任意多的Context元素。

 <Context path="/gdda45_hdlgdx" docBase="D:\1ZX\svn\gdda45_hdlgdx"  crossContext="true" />
   

(2)Web應用自動部署

Host的配置

要開啟Web應用的自動部署,需要配置所在的虛擬主機;配置的方式就是前面提到的Host元素的deployOnStartup和autoDeploy屬性。如果deployOnStartup和autoDeploy設定為true,則tomcat啟動自動部署:當檢測到新的Web應用或Web應用的更新時,會觸發應用的部署(或重新部署)。二者的主要區別在於,deployOnStartup為true時,Tomcat在啟動時檢查Web應用,且檢測到的所有Web應用視作新應用;autoDeploy為true時,Tomcat在執行時定期檢查新的Web應用或Web應用的更新。除此之外,二者的處理相似。

通過配置deployOnStartup和autoDeploy可以開啟虛擬主機自動部署Web應用;實際上,自動部署依賴於檢查是否有新的或更改過的Web應用,而Host元素的appBase和xmlBase設定了檢查Web應用更新的目錄。

其中,appBase屬性指定Web應用所在的目錄,預設值是webapps,這是一個相對路徑,代表Tomcat根目錄下webapps資料夾。

xmlBase屬性指定Web應用的XML配置檔案所在的目錄,預設值為conf/<engine_name>/<host_name>

檢查Web應用更新

一個Web應用可能包括以下檔案:XML配置檔案,WAR包,以及一個應用目錄(該目錄包含Web應用的檔案結構);其中XML配置檔案位於xmlBase指定的目錄,WAR包和應用目錄位於appBase指定的目錄。

Tomcat按照如下的順序進行掃描,來檢查應用更新:

A、掃描虛擬主機指定的xmlBase下的XML配置檔案

B、掃描虛擬主機指定的appBase下的WAR檔案

C、掃描虛擬主機指定的appBase下的應用目錄

<Context>元素的配置

Context元素最重要的屬性是docBase和path,此外reloadable屬性也比較常用。

docBase指定了該Web應用使用的WAR包路徑,或應用目錄。需要注意的是,在自動部署場景下(配置檔案位於xmlBase中),docBase不在appBase目錄中,才需要指定;如果docBase指定的WAR包或應用目錄就在docBase中,則不需要指定,因為Tomcat會自動掃描appBase中的WAR包和應用目錄,指定了反而會造成問題。

path指定了訪問該Web應用的上下文路徑,當請求到來時,Tomcat根據Web應用的 path屬性與URI的匹配程度來選擇Web應用處理相應請求。例如,Web應用app1的path屬性是”/app1”,Web應用app2的path屬性是”/app2”,那麼請求/app1/index.html會交由app1來處理;而請求/app2/index.html會交由app2來處理。如果一個Context元素的path屬性為””,那麼這個Context是虛擬主機的預設Web應用;當請求的uri與所有的path都不匹配時,使用該預設Web應用來處理。但是,需要注意的是,在自動部署場景下(配置檔案位於xmlBase中),不能指定path屬性,path屬性由配置檔案的檔名、WAR檔案的檔名或應用目錄的名稱自動推匯出來。如掃描Web應用時,發現了xmlBase目錄下的app1.xml,或appBase目錄下的app1.WAR或app1應用目錄,則該Web應用的path屬性是”app1”。如果名稱不是app1而是ROOT,則該Web應用是虛擬主機預設的Web應用,此時path屬性推導為””。

reloadable屬性指示tomcat是否在執行時監控在WEB-INF/classes和WEB-INF/lib目錄下class檔案的改動。如果值為true,那麼當class檔案改動時,會觸發Web應用的重新載入。在開發環境下,reloadable設定為true便於除錯;但是在生產環境中設定為true會給伺服器帶來效能壓力,因此reloadable引數的預設值為false。

 <Context path="/gdda45_hdlgdx" docBase="D:\1ZX\svn\gdda45_hdlgdx"  crossContext="true"  reloadable="true" />

在開發環境下,設定reloadable設定為true,便於開發除錯。

最典型的自動部署,就是當我們安裝完Tomcat後,webapps目錄下有如下資料夾:

當我們啟動Tomcat後,可以使用http://localhost:8080/來訪問Tomcat,其實訪問的就是ROOT對應的Web應用;我們也可以通過http://localhost:8080/docs來訪問docs應用,同理我們可以訪問examples/host-manager/manager這幾個Web應用。

(3)server.xml中靜態部署Web應用

除了自動部署,我們也可以在server.xml中通過<context>元素靜態部署Web應用。靜態部署與自動部署是可以共存的。在實際應用中,並不推薦使用靜態部署,因為server.xml 是不可動態重載入的資源,伺服器一旦啟動了以後,要修改這個檔案,就得重啟伺服器才能重新載入。而自動部署可以在Tomcat執行時通過定期的掃描來實現,不需要重啟伺服器。

server.xml中使用Context元素配置Web應用,Context元素應該位於Host元素中。

 <Context path="/gdda45_hdlgdx" docBase="D:\1ZX\svn\gdda45_hdlgdx"  crossContext="true"  reloadable="true" />

docBase:靜態部署時,docBase可以在appBase目錄下,也可以不在;本例中,docBase不在appBase目錄下。

path:靜態部署時,可以顯式指定path屬性,但是仍然受到了嚴格的限制:只有當自動部署完全關閉(deployOnStartup和autoDeploy都為false)或docBase不在appBase中時,才可以設定path屬性。在本例中,docBase不在appBase中,因此path屬性可以設定。

reloadable屬性的用法與自動部署時相同。

Listener

  <Listener className="org.apache.catalina.startup.VersionLoggerListener" />
  <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
  <Listener className="org.apache.catalina.core.JasperListener" />
   <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
  <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
  <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />

Listener(即監聽器)定義的元件,可以在特定事件發生時執行特定的操作;被監聽的事件通常是Tomcat的啟動和停止。

監聽器可以在Server、Engine、Host或Context中,本例中的監聽器都是在Server中。實際上,本例中定義的6個監聽器,都只能存在於Server元件中。監聽器不允許內嵌其他元件。

監聽器需要配置的最重要的屬性是className,該屬性規定了監聽器的具體實現類,該類必須實現了org.apache.catalina.LifecycleListener介面。

下面依次介紹例子中配置的監聽器:

  • VersionLoggerListener:當Tomcat啟動時,該監聽器記錄Tomcat、Java和作業系統的資訊。該監聽器必須是配置的第一個監聽器。
  • AprLifecycleListener:Tomcat啟動時,檢查APR庫,如果存在則載入。APR,即Apache Portable Runtime,是Apache可移植執行庫,可以實現高可擴充套件性、高效能,以及與本地伺服器技術更好的整合。 對應的是 bin/tcnative-1.dll ,
  • JasperListener:在Web應用啟動之前初始化Jasper,Jasper是JSP引擎,把JVM不認識的JSP檔案解析成java檔案,然後編譯成class檔案供JVM使用。
  • JreMemoryLeakPreventionListener:與類載入器導致的記憶體洩露有關。
  • GlobalResourcesLifecycleListener:通過該監聽器,初始化< GlobalNamingResources>標籤中定義的全域性JNDI資源;如果沒有該監聽器,任何全域性資源都不能使用。< GlobalNamingResources>將在後文介紹。
  • ThreadLocalLeakPreventionListener:當Web應用因thread-local導致的記憶體洩露而要停止時,該監聽器會觸發執行緒池中執行緒的更新。當執行緒執行完任務被收回執行緒池時,活躍執行緒會一個一個的更新。只有當Web應用(即Context元素)的renewThreadsWhenStoppingContext屬性設定為true時,該監聽器才有效。

GlobalNamingResources

  <GlobalNamingResources>
    <!-- Editable user database that can also be used by
         UserDatabaseRealm to authenticate users
    -->
    <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>

GlobalNamingResources元素定義了全域性資源,通過配置可以看出,該配置是通過讀取 conf/tomcat-users.xml實現的。

核心元件的關係

Server元素在最頂層,代表整個Tomcat容器;一個Server元素中可以有一個或多個Service元素。

Service在Connector和Engine外面包了一層,把它們組裝在一起,對外提供服務。一個Service可以包含多個Connector,但是隻能包含一個Engine;Connector接收請求,Engine處理請求。

Engine、Host和Context都是容器,且 Engine包含Host,Host包含Context。每個Host元件代表Engine中的一個虛擬主機;每個Context元件代表在特定Host上執行的一個Web應用。

請求處理

當請求被髮送到Tomcat所在的主機時,如何確定最終哪個Web應用來處理該請求呢?

(1)根據協議和埠號選定Service和Engine

Service中的Connector元件可以接收特定埠的請求,因此,當Tomcat啟動時,Service元件就會監聽特定的埠。在第一部分的例子中,Catalina這個Service監聽了8080埠(基於HTTP協議)和8009埠(基於AJP協議)。當請求進來時,Tomcat便可以根據協議和埠號選定處理請求的Service;Service一旦選定,Engine也就確定。

通過在Server中配置多個Service,可以實現通過不同的埠號來訪問同一臺機器上部署的不同應用。

(2)根據域名或IP地址選定Host

Service確定後,Tomcat在Service中尋找名稱與域名/IP地址匹配的Host處理該請求。如果沒有找到,則使用Engine中指定的defaultHost來處理該請求。在第一部分的例子中,由於只有一個Host(name屬性為localhost),因此該Service/Engine的所有請求都交給該Host處理。

(3)根據URI選定Context/Web應用

這一點在Context一節有詳細的說明:Tomcat根據應用的 path屬性與URI的匹配程度來選擇Web應用處理相應請求,這裡不再贅述。

(4)舉例

以請求http://localhost:80/gdda45_hdlgdx/index.html為例,首先通過協議和埠號(http和8080)選定Service;然後通過主機名(localhost)選定Host;然後通過uri(/gdda45_hdlgdx/index.html)選定Web應用。