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