【第十一課】Tomcat原理解析【轉】

轉自:http://blog.csdn.net/xlgen157387web

俗話說,站在巨人的肩膀上看世界,通常學習的時候也是先總覽一下總體,而後逐個部分個個擊破,最後造成思路,瞭解具體細節,Tomcat的結構很複雜,可是 Tomcat 很是的模塊化,找到了 Tomcat最核心的模塊,問題才能夠遊刃而解,瞭解了Tomcat的總體架構對之後深刻了解Tomcat來講相當重要!面試

1、Tomcat頂層架構

先上一張Tomcat的頂層結構圖(圖A),以下:apache

Tomcat中最頂層的容器是Server,表明着整個服務器,從上圖中能夠看出,一個Server能夠包含至少一個Service,用於具體提供服務。tomcat

Service主要包含兩個部分:Connector和Container。從上圖中能夠看出 Tomcat 的心臟就是這兩個組件,他們的做用以下:服務器

  • 一、Connector用於處理鏈接相關的事情,並提供Socket與Request和Response相關的轉化; 二、Container用於封裝和管理Servlet,以及具體處理Request請求;網絡

    一個Tomcat中只有一個Server,一個Server能夠包含多個Service,一個Service只有一個Container,可是能夠有多個Connectors,這是由於一個服務能夠有多個鏈接,如同時提供Http和Https連接,也能夠提供向相同協議不一樣端口的鏈接,示意圖以下(Engine、Host、Context下邊會說到):架構

多個 Connector 和一個 Container 就造成了一個 Service,有了 Service 就能夠對外提供服務了,可是 Service 還要一個生存的環境,必需要有人可以給她生命、掌握其生死大權,那就非 Server 莫屬了!因此整個 Tomcat 的生命週期由 Server 控制。app

另外,上述的包含關係或者說是父子關係,均可以在tomcat的conf目錄下的server.xml配置文件中看出,下圖是刪除了註釋內容以後的一個完整的server.xml配置文件(Tomcat版本爲8.0)webapp

詳細的配置文件文件內容能夠到Tomcat官網查看:http://tomcat.apache.org/tomcat-8.0-doc/index.html

上邊的配置文件,還能夠經過下邊的一張結構圖更清楚的理解:

Server標籤設置的端口號爲8005,shutdown=」SHUTDOWN」 ,表示在8005端口監聽「SHUTDOWN」命令,若是接收到了就會關閉Tomcat。一個Server有一個Service,固然還能夠進行配置,一個Service有多個,Service左邊的內容都屬於Container的,Service下邊是Connector。

2、Tomcat頂層架構小結:

  • (1)Tomcat中只有一個Server,一個Server能夠有多個Service,一個Service能夠有多個Connector和一個Container;
  • (2) Server掌管着整個Tomcat的生死大權;
  • (4)Service 是對外提供服務的;
  • (5)Connector用於接受請求並將請求封裝成Request和Response來具體處理;
  • (6)Container用於封裝和管理Servlet,以及具體處理request請求;

知道了整個Tomcat頂層的分層架構和各個組件之間的關係以及做用,對於絕大多數的開發人員來講Server和Service對咱們來講確實很遠,而咱們開發中絕大部分進行配置的內容是屬於Connector和Container的,因此接下來介紹一下Connector和Container。

3、Connector和Container的微妙關係

由上述內容咱們大體能夠知道一個請求發送到Tomcat以後,首先通過Service而後會交給咱們的Connector,Connector用於接收請求並將接收的請求封裝爲Request和Response來具體處理,Request和Response封裝完以後再交由Container進行處理,Container處理完請求以後再返回給Connector,最後在由Connector經過Socket將處理的結果返回給客戶端,這樣整個請求的就處理完了!

Connector最底層使用的是Socket來進行鏈接的,Request和Response是按照HTTP協議來封裝的,因此Connector同時須要實現TCP/IP協議和HTTP協議!

Tomcat既然處理請求,那麼確定須要先接收到這個請求,接收請求這個東西咱們首先就須要看一下Connector!

4、Connector架構分析

Connector用於接受請求並將請求封裝成Request和Response,而後交給Container進行處理,Container處理完以後在交給Connector返回給客戶端。

所以,咱們能夠把Connector分爲四個方面進行理解:

  • (1)Connector如何接受請求的?

  • (2)如何將請求封裝成Request和Response的?

  • (3)封裝完以後的Request和Response如何交給Container進行處理的?

  • (4)Container處理完以後如何交給Connector並返回給客戶端的?

    首先看一下Connector的結構圖(圖B),以下所示:

Connector就是使用ProtocolHandler來處理請求的,不一樣的ProtocolHandler表明不一樣的鏈接類型,好比:Http11Protocol使用的是普通Socket來鏈接的,Http11NioProtocol使用的是NioSocket來鏈接的。

其中ProtocolHandler由包含了三個部件:Endpoint、Processor、Adapter。

  • (1)Endpoint用來處理底層Socket的網絡鏈接,Processor用於將Endpoint接收到的Socket封裝成Request,Adapter用於將Request交給Container進行具體的處理。
  • (2)Endpoint因爲是處理底層的Socket網絡鏈接,所以Endpoint是用來實現TCP/IP協議的,而Processor用來實現HTTP協議的,Adapter將請求適配到Servlet容器進行具體的處理。
  • (3)Endpoint的抽象實現AbstractEndpoint裏面定義的Acceptor和AsyncTimeout兩個內部類和一個Handler接口。Acceptor用於監聽請求,AsyncTimeout用於檢查異步Request的超時,Handler用於處理接收到的Socket,在內部調用Processor進行處理。
  • 至此,咱們應該很輕鬆的回答(1)(2)(3)的問題了,可是(4)仍是不知道,那麼咱們就來看一下Container是如何進行處理的以及處理完以後是如何將處理完的結果返回給Connector的?

5、Container架構分析

Container用於封裝和管理Servlet,以及具體處理Request請求,在Connector內部包含了4個子容器,結構圖以下(圖C):

4個子容器的做用分別是:

  • (1)Engine:引擎,用來管理多個站點,一個Service最多隻能有一個Engine;
  • (2)Host:表明一個站點,也能夠叫虛擬主機,經過配置Host就能夠添加站點;
  • (3)Context:表明一個應用程序,對應着平時開發的一套程序,或者一個WEB-INF目錄以及下面的web.xml文件;
  • (4)Wrapper:每一Wrapper封裝着一個Servlet;
  • 下面找一個Tomcat的文件目錄對照一下,以下圖所示:

Context和Host的區別是Context表示一個應用,咱們的Tomcat中默認的配置下webapps下的每個文件夾目錄都是一個Context,其中ROOT目錄中存放着主應用,其餘目錄存放着子應用,而整個webapps就是一個Host站點。

咱們訪問應用Context的時候,若是是ROOT下的則直接使用域名就能夠訪問,例如:www.ledouit.com,若是是Host(webapps)下的其餘應用,則可使用www.ledouit.com/docs進行訪問,固然默認指定的根應用(ROOT)是能夠進行設定的,只不過Host站點下默認的主營用是ROOT目錄下的。

看到這裏咱們知道Container是什麼,可是仍是不知道Container是如何進行處理的以及處理完以後是如何將處理完的結果返回給Connector的?別急!下邊就開始探討一下Container是如何進行處理的!

6、Container如何處理請求的

Container處理請求是使用Pipeline-Value管道來處理的!

Pipeline-Value是責任鏈模式,責任鏈模式是指在一個請求處理的過程當中有不少處理者依次對請求進行處理,每一個處理者負責作本身相應的處理,處理完以後將處理後的請求返回,再讓下一個處理着繼續處理。

可是!Pipeline-Value使用的責任鏈模式和普通的責任鏈模式有些不一樣!區別主要有如下兩點:

(1)每一個Pipeline都有特定的Value,並且是在管道的最後一個執行,這個Value叫作BaseValue,BaseValue是不可刪除的;

(2)在上層容器的管道的BaseValue中會調用下層容器的管道。

咱們知道Container包含四個子容器,而這四個子容器對應的BaseValue分別在:StandardEngineValue、StandardHostValue、StandardContextValue、StandardWrapperValue。

Pipeline的處理流程圖以下(圖D):

(1)Connector在接收到請求後會首先調用最頂層容器的Pipeline來處理,這裏的最頂層容器的Pipeline就是EnginePipeline(Engine的管道);

(2)在Engine的管道中依次會執行EngineValue一、EngineValue2等等,最後會執行StandardEngineValue,在StandardEngineValue中會調用Host管道,而後再依次執行Host的HostValue一、HostValue2等,最後在執行StandardHostValue,而後再依次調用Context的管道和Wrapper的管道,最後執行到StandardWrapperValue。

(3)當執行到StandardWrapperValue的時候,會在StandardWrapperValue中建立FilterChain,並調用其doFilter方法來處理請求,這個FilterChain包含着咱們配置的與請求相匹配的Filter和Servlet,其doFilter方法會依次調用全部的Filter的doFilter方法和Servlet的service方法,這樣請求就獲得了處理!

(4)當全部的Pipeline-Value都執行完以後,而且處理完了具體的請求,這個時候就能夠將返回的結果交給Connector了,Connector在經過Socket的方式將結果返回給客戶端。

總結

至此,咱們已經對Tomcat的總體架構有了大體的瞭解,從圖A、B、C、D能夠看出來每個組件的基本要素和做用。咱們在腦海裏應該有一個大概的輪廓了!若是你面試的時候,讓你簡單的聊一下Tomcat,上面的內容你能脫口而出嗎?當你可以脫口而出的時候,這位面試官必定會對你另眼相看的!

相關文章
相關標籤/搜索