揭開Tomcat的神祕面紗

瞭解tomcat

總所周知,我們的web應用在上線時都要將web應用打包成一個war包到tomcat的目錄下進行解壓。然後通過瀏覽器去發URL的請求。那麼請求必定是要先經過Tomcat 的。那麼Tomcat拿到請求後是如何應對的呢?

手寫 tomcat 配置文件

所有的服務器都有他自己的屬性,當然 tomcat 也不例外。無輪任何應用想要與外界通訊必須就要去管理自己的端口,所以tomcat的屬性配置文件server.xml文件誕生了。這個文件集中管理了tomcat的屬性配置。

server.xml 配置文件在 tomcat 目錄下的conf 目錄下,我們先大概瞭解一下tomcat的配置文件:

<?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" />
  <!-- 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
         Java AJP  Connector: /docs/config/ajp.html
         APR (HTTP/AJP) Connector: /docs/apr.html
         Define a non-SSL/TLS HTTP/1.1 Connector on port 8080
    -->
    <Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" />
    <!-- A "Connector" using the shared thread pool-->
    <!--
    <Connector executor="tomcatThreadPool"
               port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" />
    -->
    <!-- Define an SSL/TLS HTTP/1.1 Connector on port 8443
         This connector uses the NIO implementation. The default
         SSLImplementation will depend on the presence of the APR/native
         library and the useOpenSSL attribute of the
         AprLifecycleListener.
         Either JSSE or OpenSSL style configuration may be used regardless of
         the SSLImplementation selected. JSSE style configuration is used below.
    -->
    <!--
    <Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
               maxThreads="150" SSLEnabled="true">
        <SSLHostConfig>
            <Certificate certificateKeystoreFile="conf/localhost-rsa.jks"
                         type="RSA" />
        </SSLHostConfig>
    </Connector>
    -->
    <!-- Define an SSL/TLS HTTP/1.1 Connector on port 8443 with HTTP/2
         This connector uses the APR/native implementation which always uses
         OpenSSL for TLS.
         Either JSSE or OpenSSL style configuration may be used. OpenSSL style
         configuration is used below.
    -->
    <!--
    <Connector port="8443" protocol="org.apache.coyote.http11.Http11AprProtocol"
               maxThreads="150" SSLEnabled="true" >
        <UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol" />
        <SSLHostConfig>
            <Certificate certificateKeyFile="conf/localhost-rsa-key.pem"
                         certificateFile="conf/localhost-rsa-cert.pem"
                         certificateChainFile="conf/localhost-rsa-chain.pem"
                         type="RSA" />
        </SSLHostConfig>
    </Connector>
    -->

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


    <!-- 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">

        <!-- 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 "%r" %s %b" />

      </Host>
    </Engine>
  </Service>
</Server>

頂層元素: Server和Service標籤
是整個配置文件的根元素,可以與一組和一個相連。

所以我們可以寫出如下的一種配置結構

<server> 
 <Service>
 <Connector></Connector>
 <Connector></Connector>
 <Connector></Connector>
 <Engine></Engine>
 </Service>
</server>
<Server>

我們在 Server 標籤中 可以配置 port=”8005″ shutdown=”SHUTDOWN” shutdown屬性表示官兵Server服務,port 表示接受shutdown指令的端口號,只要將 port = “-1” 即可禁掉該端口.

<server port="8005" shutdown="SHUTDOWN"> 
 <Service>
 <Connector></Connector>
 <Connector></Connector>
 <Connector></Connector>
 <Engine></Engine>
 </Service>
</server>

Server 的主要作用是提供一個讓客戶端可以訪問 Service 的接口,同時對 service 進行維護和管理,包括Service的初始化,運行,銷燬以及找到客戶端要找的Service。

Service中有一個 name=”Catalina” 屬性,因爲tomcat可以提供多個服務,所以這個屬性是它的 標識名 .

<server port="8005" shutdown="SHUTDOWN"> 
 <Service name= "Catalina">
 <Connector></Connector>
 <Connector></Connector>
 <Connector></Connector>
 <Engine></Engine>
 </Service>
</server>

Service 的主要作用是將 Connector 和 Engine 組合在一起。 Service可有包含多個 Connector 但是只能有一個 Engine

連接器: Connector
Connector 代表了外部客戶端發送請求到特定的Service接口,同時也是從外部接受請求的特定接口。它創建Request和Response對象用於和請求端交換數據;然後分配線程讓Engine進行處理,並把 Request和Response對象 傳給Engine。

port=”8080″ protocol=”HTTP/1.1″ connectionTimeout=”20000″
redirectPort=”8443″ ;port 應該很熟悉了,8080是我們對外開放的端口,我們服務器通常開放的端口是80 而tomcat通常是不需要直接對外開放的,而是使用nginx等服務器來做代理。 protocol 屬性這裏是監聽的http請求,也可以配置AJP協議,AJP協議是負責Tomcat與Apache等集成。 connectionTimeout 連接超時的時間, redirectPort 重定向端口。

<server port="8005" shutdown="SHUTDOWN"> 
 <Service name= "Catalina">
 <Connector port="8080" protocol="HTTP/1.1"   connectionTimeout="20000"
  redirectPort="8443"></Connector>
 <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
 <Engine></Engine>
 </Service>
</server>

容器:Engine Host Context
Engine容器的功能是處理請求並返回。Engine 從一個或多個 Connector 中接收請求處理後返回給 Connector . Host Context 是 Engine 的子容器

name=”Catalina” defaultHost=”localhost” ; name屬性用於日誌和錯誤信息,整個Server應該唯一。 defaultHost 指定默認的host名字,當發往本機的host不存在時使用默認的host。並且 defaultHos 必須與 Host中的一個name屬性匹配。

<server port="8005" shutdown="SHUTDOWN"> 
 <Service name= "Catalina">
 <Connector port="8080" protocol="HTTP/1.1"   connectionTimeout="20000"
  redirectPort="8443"></Connector>
 <Connect1111111111111111111111111111or port="8009" protocol="AJP/1.3" redirectPort="8443" />
 <Engine name="Catalina" defaultHost="localhost">
 <Host></Host>
 <Context></Context>
 </Engine>
 </Service>
</server>
<Host>

Host 組件代表虛擬主機,是運行多個Web應用(一個Context代表一個web應用),並負責安裝,展開,啓動,結束每個web應用。

Host 代表一個虛擬主機,對應服務器中一個網絡實體(www.mmmnnaa.com,106.106.106.25)爲了可以使用網絡名連接Tomcat ,需要在DNS服務器上註冊。

客戶端通常使用主機名來標識他們希望連接的服務器;,將主機名包含在http請求的頭部。tomcat從中提取出主機名,尋找匹配的主機,如果沒有匹配,將請求發送到默認主機。

name=”localhost” appBase=”webapps” unpackWARs=”true” autoDeploy=”true” name屬性指定虛擬主機名,appBase指定我們的應用部署的位置 unpackWars 表示是否解壓war包 如果unpackWars = “false”,則不進行解壓,直接使用war包運行。

<server port="8005" shutdown="SHUTDOWN"> 
 <Service name= "Catalina">
 <Connector port="8080" protocol="HTTP/1.1"   connectionTimeout="20000"
  redirectPort="8443"></Connector>
 <Connect1111111111111111111111111111or port="8009" protocol="AJP/1.3" redirectPort="8443" />
 <Engine name="Catalina" defaultHost="localhost">
 <Host name="localhost"  appBase="webapps" unpackWARs="true" autoDeploy="true"></Host>
 <Context></Context>
 </Engine>
 </Service>
</server>
<Context>

未完待續。。。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章