tomcat的啟動流程及原理

參考自:https://blog.csdn.net/sunyunjie361/article/details/58588033

組件介紹:

Tomcat 最重要的是兩個組件是:Connector(連接器) 和 Container(容器/集裝箱),Connector 組件是可以被替換,這樣可以提供給服務器設計者更多的選擇,因為這個組件是如此重要,不僅跟服務器的設計的本身,而且和不同的應用場景也十分相關,所以一個 Container 可以選擇對應多個 Connector。

多個 Connector 和一個 Container 就組成一個 Service,有了 Service 就可以對外提供服務了,但是 Service 還要一個生存的環境, Server 就提供了這樣一個環境。所以整個 Tomcat 的生命周期由 Server 控制。

tomcat核心組件.JPG

下面來一層層的看,首先是Server,什么是server呢?

Server

Server 要完成的任務很簡單,就是要能夠提供一個接口讓其它程序能夠訪問到 Service 集合,同時要維護它所包含的所有 Service 的生命周期,包括如何初始化如何結束服務如何找到別人要訪問的 Service。還有一些次要的任務,如記錄Service運行日志,維護Session等等。Server包含的組件結構如下:

tomcat-Server.png

Service

Service 是在 Connector 和 Container 外面多包一層,把它們組裝在一起,向外面提供服務,一個 Service 可以設置多個 Connector,但是只能有一個 Container 容器。當然Service不僅僅包含這兩個組件, Service 接口的方法列表如下:


tomcat-Service方法.png

Container

Container本意是集裝箱的意思,是一個接口,定義了下屬的各種容器,重要的是Wrapper、Host、Engine、Context等


tomcat-container結構.png
tomcat-container類圖.png

Engine(引擎)

負責處理來自相關聯的service的所有請求,處理后,將結果返回給service,而connector是作為service與engine的中間媒介出現的。
一個engine下可以配置一個默認主機,每個虛擬主機都有一個域名。當engine獲得一個請求時,它把該請求匹配到虛擬主機(host)上,然后把請求交給該主機來處理。
Engine有一個默認主機,當請求無法匹配到任何一個虛擬主機時,將交給默認host來處理。Engine以線程的方式啟動Host。

Host

代表一個虛擬主機,每個虛擬主機和某個網絡域名(Domain Name)相匹配。
每個虛擬主機下都可以部署一個或多個web應用,每個web應用對應于一個context,有一個context path。
當Host獲得一個請求時,將把該請求匹配到某個Context上,然后把該請求交給該Context來處理匹配的方法是“最長匹配”,所以一個path==””的Context將成為該Host的默認Context所有無法和其它Context的路徑名匹配的請求都將最終和該默認Context匹配。

Context

一個Context對應于一個Web應用,一個Web應用由一個或者多個Servlet組成Context在創建的時候將根據配置文件$CATALINA_HOME/conf/web.xml$ WEBAPP_HOME/WEB-INF/web.xml載入Servlet類。當Context獲得請求時,將在自己的映射表(mapping table)中尋找相匹配的Servlet類,如果找到,則執行該類,獲得請求的回應,并返回。

Wrapper

Wrapper 代表一個 Servlet,它負責管理一個 Servlet,包括的 Servlet 的裝載、初始化、執行以及資源回收。Wrapper 是最底層的容器,它沒有子容器了,所以調用它的 addChild 將會報錯。
Wrapper 的實現類是 StandardWrapper,StandardWrapper 還實現了擁有一個 Servlet 初始化信息的 ServletConfig,由此看出 StandardWrapper 將直接和 Servlet 的各種信息打交道。

Connector

Connector將在某個指定的端口上來監聽客戶的請求,把從socket傳遞過來的數據,封裝成Request,傳遞給Engine來處理,并從Engine處獲得響應并返回給客戶。

Tomcat通常會用到兩種Connector:

  1. Http Connector 在端口8080處偵聽來自客戶browser的http請求。 AJP Connector
  2. 在端口8009處偵聽來自其它WebServer(Apache)的servlet/jsp代理請求。

Lifecycle

現實生活中大部分的事物都有生命周期,就像人的生老病死一樣。

在編程中也有很多對象是具有生命周期的,從初始化、運行、回收等 會經歷幾個不同的階段。 在tomcat中容器相關的好多組建都實現了Lifecycle接口,當tomcat啟動時,其依賴的下層組件會全部進行初始化。 并且可以對每個組件生命周期中的事件添加監聽器

例如當服務器啟動的時候,tomcat需要去調用servlet的init方法和初始化容器等一系列操作,而停止的時候,也需要調用servlet的destory方法。而這些都是通過org.apache.catalina.Lifecycle接口來實現的。由這個類來制定各個組件生命周期的規范。


Lifecycle類圖.png
tomcat生命周期類分析.png

LifecycleListener

在Lifecycle的介紹中提到,Lifecycle會對每個組件生命周期中的事件添加監聽器,也就是addLifecycleListener(LifecycleListener listener)方法,而LifecycleListener就是上面提到的監聽器。

LifecycleEvent

顧名思義,就是當有監聽事件發生的時候,LifecycleEvent會存儲時間類型和數據

/**
* Construct a new LifecycleEvent with the specified      parameters.
*
* @param lifecycle Component on which this event occurred
* @param type Event type (required)
* @param data Event data (if any)
*/
public LifecycleEvent(Lifecycle lifecycle, String type, Object data) {
   super(lifecycle);
   this.type = type;
   this.data = data;
}

tomcat 的啟動過程

tomcat的啟動的起點是Server.start()方法,在這里它會依次啟動ContainerConnector相關組件,最后到達EndPoint(Tomcat啟動的Socket管理者),完成整個啟動過程。如下圖是個簡易過程:

tomcat啟動流程.JPG

具體實現過程

StartFirst

/**
 * Start the server.
 *
 * @throws LifecycleException Start error
 */
public void start() throws LifecycleException {
    getServer();
    getConnector();
    server.start();
}

server啟動之前需要準備好Server和Connector,server的默認實現是StandardServer, start()方法在其父類LifecycleBase中


tomcat-LifecycleBase的start方法.png

注:LifecycleBase還是StandardService, StandardEngine, StandardHost, StandardContext等的父類,所以當調用這些類的start()方法時其實都是調用此處的start()方法,而最重要的是在start()方法中會調用startInternal()startInternal()在LifecycleBase中是抽象方法,具體實現由各個實現類自己定義。

startServer

啟動server其實就是啟動service容器,靠StandardService中的startInternal()實現方法,參考代碼如下:


tomcat-啟動service容器.png

startService

啟動service其實就是啟動engine容器和connector容器,是在StandardEngine中實現的。參考代碼如下:


tomcat-engine和connector容器準備.png

啟動Engine

啟動engine其實就是啟動host容器(多線程),是在StandardHost中實現,參考代碼如下:


tomcat-host容器準備.png

啟動Host

啟動Host的方式和上圖一樣,都是以線程的方式啟動子Container,這里Host的children為Context

啟動Context(上下文)

啟動Wrapper

tomcat-啟動Wrapper.png

loadServlet(加載servlet):

loadServlet1.png

loadServlet2.png

loadServlet3.png

它基本上描述了對 Servlet 的操作,當裝載了 Servlet 后就會調用 Servlet 的init 方法,同時會傳一個 StandardWrapperFacade對象給 Servlet,這個對象包裝了 StandardWrapper,ServletConfig 與它們的關系圖如下:

tomcat-ServletConfig類關系.png

啟動Connector

Tomcat的Connector是Coyote connector的一種實現,這是tomcat的官方解釋:The Coyote HTTP/1.1 Connector element represents a Connector component that supports the HTTP/1.1 protocol. It enables Catalina to function as a stand-alone web server, in addition to its ability to execute servlets and JSP pages.
Tomcat8之后默認使用nio作為接受請求策略,默認在Service啟動的時候進行初始化,當然也可以單獨啟動,在默認的構造函數中會初始化ProtocolHandler

tomcat-connector構造.png

tomcat中支持兩種協議的連接器:HTTP/1.1與AJP/1.3

HTTP/1.1協議負責建立HTTP連接,web應用通過瀏覽器訪問tomcat服務器用的就是這個連接器,默認監聽的是8080端口;

AJP/1.3協議負責和其他HTTP服務器建立連接,監聽的是8009端口,比如tomcat和apache或者iis集成時需要用到這個連接器。


配置協議連機器.png

Connector的啟動其實就是ProtocolHandler的啟動,如下圖:

connector啟動.png

ProtocolHandler的類結構如下圖:


ProtocolHandler的類結構.png

ConnectorstartInternal方法調用了ProtocolHandlestart方法,這個start方法就在AbstractProtocol中,如下圖:

ProtocolHandle-start.png

EndPoint啟動

EndPoint是tomcat啟動的終點,EndPoint是Tomcat啟動的Socket管理者(注:通過類圖可以看出AbstractEndpoint已經脫離了Lifecycle和LifecycleListener體系,所以它只是一個簡簡單單的Socket管理者),因為是由他直接啟動默認的Nio,在啟動的時候先看看類結構圖:

EndPoint類關系.png

EndPoint能做什么呢?來看一下他的方法:

EndPoint的方法.png

createAcceptorcreateExecutor等方法都是在初始化EndPoint很重要方法,因為在接收請求的時候,通過Acceptor的接收,經過重重模塊,才能一路到達Servlet
那么EndPoint的啟動,如下圖:
tomcat-Endpoint啟動.png

在這個地方會啟動很多的線程,這些線程大多是用于tomcat接收請求的作用。關于tomcat的接收請求流程,后續會繼續積累。

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,835評論 6 534
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,676評論 3 419
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,730評論 0 380
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,118評論 1 314
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,873評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,266評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,330評論 3 443
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,482評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,036評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,846評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,025評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,575評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,279評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,684評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,953評論 1 289
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,751評論 3 394
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,016評論 2 375

推薦閱讀更多精彩內容