1. 程式人生 > >tomcat整體架構

tomcat整體架構

nta 對象 com 訪問日誌 accesslog struts2 servlet acceptor tlist

1.背景

Tomcat作為JavaWeb領域的Web容器,目前在我們淘寶也使用的也非常廣泛,現在基本上所有線上業務系統都是部署在Tomcat上。為了對平時開發的Web系統有更深入的理解以及出於好奇心對我們寫的Web系統是如何跑在Tomcat上的,於是仔細研究了下Tomcat的源碼。大家都知道Servlet規範是Java領域中為服務端編程制定的規範,對於我們開發者只是關註了Servlet規範中提供的編程組件(ServletContextListener,Filer,Servlet) 等 ,但是規範中還有一些我們經常使用的接口(ServletContext,ServletRequest,ServletResponse,FilterChain)等都是由Tomcat去實現的,並且我們開發者實現的編程組件只是被Tomcat去回調而已。所以看Tomcat源碼實現也有助於我們更好的理解Servlet規範及系統如何在容器中運行(一些開源的MVC框架如Struts2,Webx,SpringMVC本質無非就是這個)

2.Tomcat體系結構

仔細查看下圖(網絡上描述Tomcat架構比較清晰的一張圖),不難發現其中的Connecotr組件以及與Container組件是Tomcat的核心。一個Server可以有多個Service,而一個Service可以包含了多個Connector組件和一個Engine容器組件,一個Engine可以由多個虛擬主機Host組成,每一個Host下面又可以由多個Web應用Context構成,每一個的Context下面可以包含多個Wrapper(Servlet的包裝器)組成。

Tomcat將Engine,Host,Context,Wrapper統一抽象成Container。一個抽象的Container模塊可以包含各種服務。例如,Manager管理器(Session管理),Pipeline管道( 維護管道閥門Value )等。Lifecycle接口統一定義了容器的生命周期,通過事件機制實現各個容器間的內部通訊。而容器的核心接口Container的抽象實現中定義了一個Pipeline,一個Manager,一個Realm以及ClassLoader統一了具體容器的實現規範。連接器(Connector)組件的主要任務是為其所接收到的每一個請求(可以是HTTP協議,也可以AJP協議),委托給具體相關協議的解析類ProtocolHandler,構造出Request 對象和Response 對象。然後將這兩個對象傳送給容器(Container)進行處理。容器(Container)組件收到來自連接器(Connector)的Request 和Response對象後,負責調用Filter,最後調用Servlet的service 方法(進入我們開發的Web系統中)。
技術分享圖片

1.Server組件:Server是最頂級的組件,代表Tomcat的運行實例;包含Listener組件用以監聽生命周期中的各種事件;包含GlobalNamingResources組件用以集成JNDI;包含Service組件用以提供服務。

2.Service組件:Service是服務的抽象,代表請求從接受到處理的所有組件的集合;Server組件可以包含多個Service組件;包含Connector組件用以接收客戶端的信息;包含Engine組件用以處理請求;包含Executor用以提供線程池執行任務。

3.Connector組件:接收客戶端連接並接收信息報文,信息報文經由它解析後送往容器中處理;包含Mapper組件對請求地址進行路由;包含CoyoteAdaptor組件用以將Connector組件和Engine等容器組件適配起來;包含Protocol組件用以接收客戶端連接、接收客戶端信息報文、報文解析處理、對客戶端響應等整個過程。

4.Protocol組件:包含JioEndPoint組件,其中的Acceptor組件將啟動某個端口的監聽,將監聽到的請求放入線程池Executor組件,其中的Processor組件對HTTP協議解析並傳遞到Engine容器繼續處理;NIO模式下NioEndPoint多了一個Poller組件輪詢多個客戶端連接處理事件。

Engine組件:代表全局Servlet引擎;每個Service組件只能包含一個Engine容器組件;包含Listener組件用以在生命周期中對Engine相關的事件進行監聽;包含AccessLog組件以記錄訪問日誌;包含Cluster組件以提供集群功能,將需要共享的數據同步到集群中的其他Tomcat實例中;包含Pipeline組件用以處理請求;包含Realm組件用以提供安全權限功能。

5.Host組件:代表虛擬主機;一個Engine組件可以包含若幹個Host容器組件;包含Listener組件用以在生命周期中對Host相關的事件進行監聽;包含AccessLog組件以記錄訪問日誌;包含Cluster組件以提供集群功能,將需要共享的數據同步到集群中的其他Tomcat實例中;包含Pipeline組件用以處理請求;包含Realm組件用以提供安全權限功能。

6.Context組件:是Web應用的抽象,Web應用部署到Tomcat後運行時就會轉化成Context對象;包含了各種靜態資源、若幹Servlet(Wrapper容器)以及各種其他動態資源;

  包含Listener組件用以在生命周期中對Context相關的事件進行監聽;

  包含AccessLog組件以記錄訪問日誌;

  包含Pipeline組件用以處理請求;

  包含Realm組件用以提供安全權限功能;

  包含Loader組件用以加載Web應用的資源,保證不同Web應用之間的資源隔離;

  包含Manager組件用以管理Web容器的會話,包括維護會話的生成、更新和銷毀;

  包含NamingResource組件將Tomcat配置文件的server.xml和Web應用的context.xml資源和屬性映射到內存中;

7.Mapper組件用以作為路由映射Servlet。

8.Wrapper組件:對應的是Servlet;包含Web應用開發常用的Servlet組件;包含ServletPool組件用以存放Servlet對象,當Web應用的Servlet實現了SingleThreadModel接口時則會再Wrapper中產生一個Servlet對象池,線程執行時,需先從對象池中獲取到一個Servlet對象,ServletPool組件能保證Servlet對象的線程安全;包含Pipeline組件用以處理請求。

我們從功能的角度將Tomcat源代碼分成5個子模塊,它們分別是:

  1. Jsper子模塊:這個子模塊負責jsp頁面的解析、jsp屬性的驗證,同時也負責將jsp頁面動態轉換為java代碼並編譯成class文件。在Tomcat源代碼中,凡是屬於org.apache.jasper包及其子包中的源代碼都屬於這個子模塊;
  2. Servlet和Jsp規範的實現模塊:這個子模塊的源代碼屬於javax.servlet包及其子包,如我們非常熟悉的javax.servlet.Servlet接口、javax.servet.http.HttpServlet類及javax.servlet.jsp.HttpJspPage就位於這個子模塊中;
  3. Catalina子模塊:這個子模塊包含了所有以org.apache.catalina開頭的java源代碼。該子模塊的任務是規範了Tomcat的總體架構,定義了Server、Service、Host、Connector、Context、Session及Cluster等關鍵組件及這些組件的實現,這個子模塊大量運用了Composite設計模式。同時也規範了Catalina的啟動及停止等事件的執行流程。從代碼閱讀的角度看,這個子模塊應該是我們閱讀和學習的重點。
  4. Connectors子模塊:如果說上面三個子模塊實現了Tomcat應用服務器的話,那麽這個子模塊就是Web服務器的實現。所謂連接器(Connector)就是一個連接客戶和應用服務器的橋梁,它接收用戶的請求,並把用戶請求包裝成標準的Http請求(包含協議名稱,請求頭Head,請求方法是Get還是Post等等)。同時,這個子模塊還按照標準的Http協議,負責給客戶端發送響應頁面,比如在請求頁面未發現時,connector就會給客戶端瀏覽器發送標準的Http 404錯誤響應頁面。
  5. Resource子模塊:這個子模塊包含一些資源文件,如Server.xml及Web.xml配置文件。嚴格說來,這個子模塊不包含java源代碼,但是它還是Tomcat編譯運行所必需的。

tomcat整體架構