重溫web服務器--細說Tomcat服務器

  從大學開始接觸java web的開發時就開始使用tomcat部署web項目,對它的理解僅僅停留在"這是個開源免費的servlet容器"的階段,後來也接觸了一些tomcat的體系,原理等方面的知識,也是半知半解,最近又開始看這方面的東西,截止到寫這篇博文,我也不沒有徹底理解它,但一些比較基礎的東西總算有些眉目了,讀源碼不易,且行且珍惜,這裏寫篇筆記整理下.html

Tomcat體系結構

  先盜張圖:java

    

  能夠看到,Tomcat有一個最頂層的容器,也就是server容器,它最大,在server容器中,能夠有多個service,由service來提供服務,因此service不能沒有,至少得有一個.web

  在service中,主要包含兩個組件,Connector和Container.Container上圖中沒有標出,其實就是包含了Engine的部分.apache

  Tomcat能夠提供多種協議的請求,http協議就是其中一種,這裏以http請求爲例,一個http請求發到服務器時,由Connector來接收並進行轉換,Connector就是用來處理鏈接相關工做的組件,好比能夠進行Socket與request,response之間的轉換,container是一個包含了servlet等衆多資源的庫,它接受Connector傳過來的request請求,解析出請求的資源,返回給Container,因此Connector和Container一個主外一個主內,兩人共同創建起美滿的家庭.瀏覽器

  固然上述比喻是不嚴謹的,由於一個Service中只有一個Container,但卻能夠有多個Connector,下面一段代碼來自Tomcat目錄下conf下的server.xml:tomcat

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

  能夠看到,默認的Tomcat服務配置文件有兩個Connector,一個負責監聽8080端口,一個負責監聽8009端口,前者咱們很熟悉了,它用來監聽來自於瀏覽器的http請求,而後會new出一個線程來把請求傳給Engine,然後者則是用來監聽其餘類型的servlet/jsp請求,叫AJP協議(我也沒據說過).服務器

Container體系結構

  繼續盜圖,Container的體系結構:網絡

    

  Container是tomcat中容器的接口,咱們最熟悉的Servlet就封裝在Container的子接口Wrapper中.看一下Server.xml中的配置:mvc

<Service name="Catalina">
    <Engine name="Catalina" defaultHost="localhost">
      <Realm className="org.apache.catalina.realm.LockOutRealm">
        <Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase"/>
      </Realm>
      <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>

  Container有四個子容器,根據圖示以及xml配置就能夠看出來他們是逐層包含的關係.app

  每一個service中只有一個Engine,Engine中能夠由多個Host,每一個Host能夠有多個Context,每一個Context中能夠有多個Wrapper,而每個Wrapper裏面就封裝着一個Servlet.

  下面分別簡單總結幾個容器:

  Engine:顧名思義,引擎,它用來管理多個站點,也就是Host.

  Host:表示一個站點,也能夠叫作虛擬主機,在上面xml配置中,能夠看到Tomcat默認配置了一個名爲localhost的虛擬主機,咱們部署,運行項目時,就默認進入這個站點,Tomcat回去webapps目錄下去定位請求的web項目資源.

  Context:意思是上下文,它表示一個應用程序,也就是咱們開發的一個web項目,一個web項目就能夠理解爲一個Context.

  Wrapper:每一個Wrapper封裝一個servlet.

  默認配置下的webapps下的每一目錄都是一個應用,其中有一個ROOT目錄表明主應用,整個webapps表示一個站點(Host),當咱們檢測tomcat是否啓動成功時通常都會打開http://localhost:8080/,這時候若是出現tomcat的官方站點就表示啓動成功,其實這時候訪問的就是ROOT應用下的資源,主應用就是直接使用域名訪問就能夠,假設webapps下還有一個helloword目錄,若是你想訪問helloword目錄下的資源,就須要輸入http://localhost:8080/helloword/.

conf目錄下的配置文件server.xml  

<Server port="8005" shutdown="SHUTDOWN">
  <Service name="Catalina">
    <Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" />
    <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 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>

  在server.xml 中首先配置了一個server,在8005端口監聽關閉命令"shutdown".

  Server裏定義了一個名爲Catania的Service,Service裏定義了兩個Connector,一個是HTTP協議,一個是AJP協議,此外還定義了一個名爲Catalina的Engine,Engine裏定義了一個名爲localhost的Host.

  Host中name屬性表示域名,因此這個默認Host能夠用localhost來訪問,appBase屬性指定了站點的位置,這裏就是webapps目錄,這裏還有不少屬性,詳細介紹,能夠參考這篇博文:http://www.blogjava.net/baoyaer/articles/107278.html

 Container體系結構

  沒盜到圖,本身畫一張:

  Connector是用來接收請求並把請求封裝成Request和Response來進行具體的業務處理的,底層使用的Socket鏈接.

  Connector實現了TCP/IP協議和HTTP協議,他會把Request和Response按照HTTP協議來進行封裝,封裝完以後交給Container來進行處理,待Container處理完以後,再返回回來,Connector使用Socket將返回結果返回給瀏覽器,完成整個處理請求.

  下面簡單介紹Connector中的幾個重要組件

  ProtocolHandler:處理不一樣鏈接類型的請求,好比普通Socket請求和NioSocket請求.

  Endpoint:處理底層Socket的網絡鏈接.實現的是TCP/IP協議.

  Processor:將Endpoint接收到的Socket請求封裝成Request,實現的HTTP協議.

  Adapter: 將Request請求適配給Container來處理.

  


 

  整個Tomcat服務器其實就是java編寫的一個應用,我嘗試着讀了一些源碼,但資歷尚淺,讀的很艱難,一些代碼上的實現方式和原理也不懂,只能大概理解一些類的功能,因此這裏只是簡單總結一些比較膚淺的知識,之後,有決心和毅力再去研讀.共勉.

參考資料:

  <看透Spring mvc源碼>第七章:Tomcat分析 

相關文章
相關標籤/搜索