一,Tomcat頂層架構
可以看到一個Server可以有多個Service,一個Service可以有多個Connector和一個Container,這兩部分是tomcat的核心。
1,Connector用於處理連接相關額事情,並提供Socket與Reponse相關的轉化
2,Container用於封裝和管理Servlet,以及具體處理Request請求
多個Connector可以提供多個鏈接,例如同時提供http和https鏈接,亦可以提供相同協議不同端口的鏈接,示意如圖:
多個Connector和一個Container就形成了一個Service,但是還需要一個環境來管理整個多個Service(但是一般也就只有一個Service,就是常見得Catalina),這個就必須是Server了,具體可以看
server.xml文件配置:
上面的配置用這張圖更加清楚的理解:
下面來解析一下這個配置文件:
可以看到Server標籤port設置爲8005,shutdown="SHUTDOWN",表示8005端口監聽到SHUTDOWN命令就關閉Tomcat服務。
Resource內配置 pathname="conf/tomcat-users.xml" 指定manageUI登錄的用戶以及其他的全局配置。
這個Server裏只有一個Service名爲Catalina,Catalina支持兩個連接,分別是端口爲8080的http連接和端口爲8009的AJP連接,
Catalina這個服務裏有一個站點名字叫localhoust,站點下的應用羣爲appBase="webapps",支持自動部署autoDeploy="true",
並設置了站點內應用打印的日誌名稱及日誌格式。
二,Connector和Container架構分析
Connector用於接收請求並將請求封裝成Request和Response,然後交給Container處理,處理之後在交給Connector返回給客戶端。
可以分爲四步:
1,Connector如何接受請求的?
2,如何將接受的請求封裝成Request和Response的?
3,封裝完成後的Request和Reponse是如何交給Container的?
4,Container處理完成後如何交給Connector並返回給客戶端的?
Connector結構圖:
Connector使用ProtocoHandler處理請求,不同的ProtocoHandler代表不同的類型,比如:Http11Protocol使用普通的Socke
t來連接,Http11NioProtocol使用NioSocket連接。
三個組件Endpoint用來處理底層Socket連接,Process用來將EndPoint接受到的Socket封裝成Request,Adapetr將Request
交給Container進行具體的處理。
EndPoint底層處理Socket網絡連接,所以EndPoint是用來實現TCP/IP協議的,而Processor是用來實現HTTP協議的,
Adapetr將請求是配到Servlet容器進行具體處理。AsyncTimeout用來監聽請求是否超時。
現在1,2,3前三步已經處理完了就剩最後一步Container如何處理請求了
Container結構圖:
四個子容器分別是:
1,Engine:引擎管理多個站點(Host),一個Service一個Engine
2,Host:代表一個站點,在server.xml配置Host可添加站點
3,Context:代表一個應該用程序,就是我們平時開發的程序,或一個WEB-INF目錄及web.xml文件
4,Wrapper:每個Wrapper封裝這一個Servlet
以上幾個容器和Tomcat目錄對應如下:
Context和Host的區別就是Context代表一個應用,我們的Tomcat默認webapps下的每一個文件夾都是一個Context,其中Root下放着主應用,
其他的目錄都存放着子應用。而整個webapps就是一個Host站點。
訪問應用時如果放在了Root下可以直接Host的name屬性加Connector的端口就行,如果是自己建的就加上Context名稱就行了。
Container如何處理請求的?
使用了Pipeline-Valve管道來處理,其中用到了責任鏈模式,每一個處理者負責做自己的處理,處理完後將處理結果返回,
再交給下個處理者繼續處理,如圖:
(1)Connector在接收到請求後會首先調用最頂層容器的Pipeline來處理,這裏的最頂層容器的Pipeline就是EnginePipeline(Engine的管道);
(2)在Engine的管道中依次會執行EngineValve1、EngineValve2等等,最後會執行StandardEngineValve,在StandardEngineValve中會調用Host管道,然後再依次執行Host的HostValve1、HostValve2等,最後在執行StandardHostValve,然後再依次調用Context的管道和Wrapper的管道,最後執行到StandardWrapperValve。
(3)當執行到StandardWrapperValve的時候,會在StandardWrapperValve中創建FilterChain,並調用其doFilter方法來處理請求,這個FilterChain包含着我們配置的與請求相匹配的Filter和Servlet,其doFilter方法會依次調用所有的Filter的doFilter方法和Servlet的service方法,這樣請求就得到了處理!
(4)當所有的Pipeline-Valve都執行完之後,並且處理完了具體的請求,這個時候就可以將返回的結果交給Connector了,Connector在通過Socket的方式將結果返回給客戶端。
https://mp.weixin.qq.com/s/D-lmaFwJBsiWIPmFIcfJnQ