1. 整體架構(gòu)簡析#
如果將Tomca它的結(jié)構(gòu)高度抽象的話,那么Tomcat其實(shí)可以看成只是有連接器(Connector)和容器(Container)兩個(gè)組件構(gòu)成。其中Connector組件負(fù)責(zé)在服務(wù)器端處理客戶端連接,包括接收客戶端連接、接收客戶端的消息報(bào)文以及消息報(bào)文的解析等工作,而Container組件則負(fù)責(zé)對(duì)客戶端的請(qǐng)求進(jìn)行邏輯處理,并把結(jié)果返回給客戶端。Container組件其實(shí)可以再細(xì)分,分成Engine組件、Host組件、Context組件和WrApper組件。
從Tomcat服務(wù)器配置文件server.xml的內(nèi)容格式看,它所描述的Tomcat也符合上圖的層級(jí)結(jié)構(gòu),以下便是server.xml簡潔的配置節(jié)點(diǎn),所以從server.xml文件也能看出Tomcat的大體結(jié)構(gòu):
<? xml version='1.0' encoding='utf-8'? >
<Server>
<Listener/>
<GlobalNamingResources>
<Resource/>
</GlobalNamingResources>
<Service>
<Executor/>
<Connector/>
<Engine>
<Cluster/>
<Realm/>
<Host>
<Context/>
</Host>
</Engine>
</Service>
</Server>
2. Server組件#
Server是最頂級(jí)的組件,它代表Tomcat的運(yùn)行實(shí)例,在一個(gè)JVM中只會(huì)包含一個(gè)Server。在Server的整個(gè)生命周期中,不同階段會(huì)有不同的事情要完成。為了方便擴(kuò)展,它引入了監(jiān)聽器方式,所以它也包含了Listener組件。另外,為了方便在Tomcat中集成JNDI,引入了GlobalNamingResources組件。同時(shí),還包含了Service核心組件。
<? xml version='1.0' encoding='utf-8'? >
<Server>
<!-- 配置一個(gè)或多個(gè)Listener -->
<Listener/>
<!-- 配置JNDI資源 -->
<GlobalNamingResources>
<Resource/>
</GlobalNamingResources>
<!--配置一個(gè)或多個(gè)Service-->
<!--注意一個(gè)Tomcat實(shí)例中可以配置多個(gè)Service,這些Service通過監(jiān)聽不同的端口來區(qū)分-->
<Service>
...
</Service>
</Server>
Server組件在Tomcat中的實(shí)現(xiàn)類是StandardServer,除了表示Service的一個(gè)對(duì)象數(shù)組外,主要是一些關(guān)于Tomcat的屬性,比如port,address等。
3. Service組件#
Service組件是連接器(Connector)和容器(Container)的組合。一個(gè)Tomcat實(shí)例中可以有多個(gè)Service組件,它們彼此獨(dú)立。StandardService是Service組件的實(shí)現(xiàn)類。如果上面的Server組件代表Tomcat服務(wù)器實(shí)例的話,那么Service組件就是這個(gè)服務(wù)器上面對(duì)外提供的一個(gè)個(gè)具體的服務(wù)。這個(gè)服務(wù)監(jiān)聽著不同的端口,你要訪問哪些服務(wù)必須指定這些服務(wù)對(duì)應(yīng)的端口。這樣一類比的話就和具體的硬件服務(wù)器很像。
public class StandardService extends LifecycleMBeanBase implements Service
{
private Server server = null;
protected Connector connectors[] = new Connector[0];
private Engine engine =null;
protected final Mapper mapper = new Mapper();
}
server表示其所屬Server,Engine作為處理該service中Connector的容器。Mapper可以看作是映射器,要來處理請(qǐng)求地址到處理該請(qǐng)求的容器及Servlet的映射。
另外,service組件還有一個(gè)Executor組件,這個(gè)線程池組件可以讓多個(gè)連接器組件共享,而不是每個(gè)連接器組件都使用自己的線程池。
4. Connector組件#
表示Tomcat中的連接器,其主要作用是監(jiān)聽并轉(zhuǎn)化Socket請(qǐng)求,并交由Container處理。其實(shí)就是對(duì)不同協(xié)議及協(xié)議處理器進(jìn)行的封裝。下面是我們需要關(guān)注的幾個(gè)屬性域:
public class Connector extends LifecycleMBeanBase
{
protected Service service = null;
protected final ProtocolHandler protocolHandler;
}
不同的協(xié)議會(huì)對(duì)應(yīng)不同的Connector,目前Tomcat支持HTTP(HTTPS)和AJP兩種協(xié)議的Connector。另外同一種協(xié)議的內(nèi)部也會(huì)根據(jù)網(wǎng)絡(luò)IO方式的不同分為阻塞IO和非阻塞IO。下面以HTTP協(xié)議為例子簡單介紹:
- Http11Protocol組件,是HTTP協(xié)議1.1版本的抽象,它包含接收客戶端連接、接收客戶端消息報(bào)文、報(bào)文解析處理、對(duì)客戶端響應(yīng)等整個(gè)過程。它主要包含JIoEndpoint組件和Http11Processor組件。啟動(dòng)時(shí),JIoEndpoint組件內(nèi)部的Acceptor組件將啟動(dòng)某個(gè)端口的監(jiān)聽,一個(gè)請(qǐng)求到來后將被扔進(jìn)線程池Executor,線程池進(jìn)行任務(wù)處理,處理過程中將通過Http11Processor組件對(duì)HTTP協(xié)議解析并傳遞到Engine容器繼續(xù)理。
- Mapper組件,客戶端請(qǐng)求的路由導(dǎo)航組件,通過它能對(duì)一個(gè)完整的請(qǐng)求地址進(jìn)行路由,通俗地說,就是它能通過請(qǐng)求地址找到對(duì)應(yīng)的Servlet。
- CoyoteAdaptor組件,一個(gè)將Connector和Container適配起來的適配器。
如上圖所示,在非阻塞I/O方式下,Connector的結(jié)構(gòu)類似阻塞模式,Http11Protocol組件改成Http11NioProtocol組件,JIoEndpoint組件改成NioEndpoint, Http11Processor組件改成Http11NioProcessor組件,這些類似的組件的功能也都類似。唯獨(dú)多了一個(gè)Poller組件,它的職責(zé)是在非阻塞I/O方式下輪詢多個(gè)客戶端連接,不斷檢測、處理各種事件,例如不斷檢測各個(gè)連接是否有可讀,對(duì)于可讀的客戶端連接則嘗試進(jìn)行讀取并解析消息報(bào)文。
5. Engine組件#
Tomcat內(nèi)部有4個(gè)級(jí)別的容器,分別是Engine、Host、Context和Wrapper。Engine代表全局Servlet引擎,每個(gè)Service組件只能包含一個(gè)Engine容器組件,但Engine組件可以包含若干Host容器組件。除了Host之外,它還包含如下組件。
- Listener組件:可以在Tomcat生命周期中完成某些Engine容器相關(guān)工作的監(jiān)聽器。
- AccessLog組件:客戶端的訪問日志,所有客戶端訪問都會(huì)被記錄。
- Cluster組件:它提供集群功能,可以將Engine容器需要共享的數(shù)據(jù)同步到集群中的其他Tomcat實(shí)例上。
- Pipeline組件:Engine容器對(duì)請(qǐng)求進(jìn)行處理的管道。
- Realm組件:提供了Engine容器級(jí)別的用戶-密碼-權(quán)限的數(shù)據(jù)對(duì)象,
6. Host組件#
Tomcat中Host組件代表虛擬主機(jī),這些虛擬主機(jī)可以存放多個(gè)Web應(yīng)用的抽象(Context容器)。除了Context組件之外,它還包含如下組件。
- Listener組件:可以在Tomcat生命周期中完成某些Host容器相關(guān)工作的監(jiān)聽器。
- AccessLog組件:客戶端的訪問日志,對(duì)該虛擬主機(jī)上所有Web應(yīng)用的訪問都會(huì)被記錄。
- Cluster組件:它提供集群功能,可以將Host容器需要共享的數(shù)據(jù)同步到集群中的其他Tomcat實(shí)例 上。
- Pipeline組件:Host容器對(duì)請(qǐng)求進(jìn)行處理的管道。
- Realm組件:提供了Host容器級(jí)別的用戶-密碼-權(quán)限的數(shù)據(jù)對(duì)象,配合資源認(rèn)證模塊使用。
7. Context組件#
Context組件是Web應(yīng)用的抽象,我們開發(fā)的Web應(yīng)用部署到Tomcat后運(yùn)行時(shí)就會(huì)轉(zhuǎn)化成Context對(duì)象。它包含了各種靜態(tài)資源、若干Servlet(Wrapper容器)以及各種其他動(dòng)態(tài)資源。它主要包括如下組件。
- Listener組件:可以在Tomcat生命周期中完成某些Context容器相關(guān)工作的監(jiān)聽器。
- Filter組件:過濾器組件,提供統(tǒng)一的業(yè)務(wù)邏輯處理。
- AccessLog組件:客戶端的訪問日志,對(duì)該Web應(yīng)用的訪問都會(huì)被記錄。
- Pipeline組件:Context容器對(duì)請(qǐng)求進(jìn)行處理的管道。
- Realm組件:提供了Context容器級(jí)別的用戶-密碼-權(quán)限的數(shù)據(jù)對(duì)象,配合資源認(rèn)證模塊使用。
- Loader組件:Web應(yīng)用加載器,用于加載Web應(yīng)用的資源,它要保證不同Web應(yīng)用之間的資源隔離
- Manager組件:會(huì)話管理器,用于管理對(duì)應(yīng)Web容器的會(huì)話,包括維護(hù)會(huì)話的生成、更新和銷毀。
- NamingResource組件:命名資源,它負(fù)責(zé)將Tomcat配置文件的server.xml和Web應(yīng)用的context.xml資源和屬性映射到內(nèi)存中。
- Mapper組件:Servlet映射器,它屬于Context內(nèi)部的路由映射器,只負(fù)責(zé)該Context容器的路由導(dǎo)航.
- Wrapper組件:Context的子容器。
8. Wrapper組件#
Wrapper容器是Tomcat中4個(gè)級(jí)別的容器中最小的,與之相對(duì)應(yīng)的是Servlet,一個(gè)Wrapper對(duì)應(yīng)一個(gè)Servlet。它包含如下組件。
- Servlet組件:Servlet即Web應(yīng)用開發(fā)常用的Servlet,我們會(huì)在Servlet中編寫好請(qǐng)求的邏輯處理。
- ServletPool組件:Servlet對(duì)象池,當(dāng)Web應(yīng)用的Servlet實(shí)現(xiàn)了SingleThreadModel接口時(shí)則會(huì)在Wrapper中產(chǎn)生一個(gè)Servlet對(duì)象池。線程執(zhí)行時(shí),需先從對(duì)象池中獲取到一個(gè)Servlet對(duì)象,ServletPool組件能保證Servlet對(duì)象的線程安全。
- Pipeline組件:Wrapper容器對(duì)請(qǐng)求進(jìn)行處理的管道。






