1. 程式人生 > 其它 >Tomcat總體架構和啟動流程

Tomcat總體架構和啟動流程

Tomcat大家都知道,這個沒什麼好描述的,我們先看Tomcat的總體架構

1、總體架構

架構一步一步增加元件,先來個最原始的

===

Server:Tomcat的整體服務,負責接收和處理請求。其擁有生命週期start開啟和stop關閉方法。

但是很明顯,所有操作放到Server裡面來是不可能的,我們繼續往下擴充套件

===

除開Server還加入了Connector、Container。

Connector聯結器:使用Socket來接收請求的到來,並對請求進行響應。

Container容器:用來接收具體的請求,進行處理。

引入後流程就是這樣了,Connector接受請求後讓Container進行處理,然後再返回給使用者

但是這個也有問題,缺少請求之間的對映規則。

===

一個Server下多個Service,一個Service下維護多個Connector和Container,那麼此時每個Connector只能給指定的Container處理請求。

這裡Container意為容器,我們更改其名稱為Engine引擎。

下面我們再將Engine往下細分。

===

這裡新加入 了 Context。

Context:代表一個Web應用,那麼我們肯定可以有多個的Context

然後我們再往下細化。

5

這裡我們需要將域名抽象為虛擬主機,所以定義了Host。

再細分

===

我們一個Wrapper則為一個Servlet。

我們上面將Container去掉了,其實我們這裡可以把Engine、Host、Context、Wrapper都堪稱Container的子類。

===

圖裡面元件都同屬於同一個生命週期類Lifecycle。

2、啟動流程與原始碼解析

Tomcat啟動流程分為兩大步:load和start

啟動類名為:BootStrap,在我們tomcat的bin中startup命令中,其實就是啟動的BootStrap這個類的main方法。

位置:org.apache.catalina.startup.Bootstrap#main

首先是建立BootStra例項,然後呼叫init方法,並將例項賦值給daemon。

然後進入到下面的方法中,首先是進入deamon(bootstrap)的load方法中。

然後我們進入Bootstrap的load方法中去:

注意這裡會去呼叫catalinaDaemon的load方法,這裡是catalinaDaemon為Catalina(org.apache.catalina.startup.Catalina)。

注意在我們Catalina的load方法中。會去獲取到Server,此Server為StandardServer,然後去呼叫其init方法。

注意此處叨到達了我們生命週期父類的init方法中,因為我們的StandardServer並未實現init方法,而是使用initInternal方法,所以我們進入StandardServer的initInternal方法。

注意在StandardServer中,它要開始去呼叫獲取到的多個Service,並挨個初始化,注意我們前面架構圖中說了,一個Server是多個Service的。

這裡只有一個Service,其為StandardService,這裡和Server一樣,會去呼叫生命週期父類的init方法,然後我們進入StandardService的initInternal方法。

這裡首先是初始化Engine,其為StandardEngine,裡面沒有其他操作,這裡就不列出來。

然後就是初始化Executor執行緒池。

然後初始化Connector聯結器。注意這裡面還有其它初始化的操作,進入其中init方法。

注意這裡的protocolHandler是協議處理器,當前這個類的名稱叫做Http11NioProtocol,其代表HTTP1.1,NIO代表執行模式,還有bio,nio,nio2,apr這幾種模式。

進入Http11NioProtocol的父類的init方法中。

EndPoint為NioEndPoint,其是實現了IO多路複用的元件,其這裡不過多解釋。

至此BootStrap的load方法結束,我們繼續看它的start方法。

其進如Catania的start方法中。

其Catania中進入StandardServer的start方法中,其父類會呼叫StandardServer的startInternal方法。

可以看到這裡面會去執行StandardService的start方法。

依次執行StandardEngine、Executor、Connector的start方法。

然後我們看Connector的startInternal方法。

在進入NioEndPoint父類AbstractEndpoint中start方法,再進入其NioEndPoint的startInternal方法。最後總體架構中所有元件已經完成初始化。

其實這裡面還應該有HOST、Wrapper等的初始化操作的,其存在於start方法當中,這個比較複雜後續寫上記錄。

最後附上時序圖: