1. 程式人生 > >Tomcat處理一個HTTP請求的過程

Tomcat處理一個HTTP請求的過程

一、Tomcat的組成

(1)Server
伺服器元素代表整個catalina servlet容器。是單例模式。

(2)Service
Service是這樣一個集合:它由一個或者多個Connector組成,以及一個Engine,負責處理所有Connector所獲得的客戶請求。

(3)Connector

一個Connector將在某個指定埠上偵聽客戶請求,並將獲得的請求交給Engine來處理,從Engine處獲得迴應並返回客戶。TOMCAT有兩個典型的Connector,一個直接偵聽來自browser的http請求,一個偵聽來自其它WebServer的請求

Coyote Http/1.1 Connector 在埠8080處偵聽來自客戶browser的http請求
Coyote JK2 Connector 在埠8009處偵聽來自其它WebServer(Apache)的servlet/jsp代理請求

(4) Engine
  Engine下可以配置多個虛擬主機Virtual Host,每個虛擬主機都有一個域名,當Engine獲得一個請求時,它把該請求匹配到某個Host上,然後把該請求交給該Host來處理,Engine有一個預設虛擬主機,當請求無法匹配到任何一個Host上的時候,將交給該預設Host來處理

(5)Host
  代表一個Virtual Host,虛擬主機,每個虛擬主機和某個網路域名Domain Name相匹配,每個虛擬主機下都可以部署(deploy)一個或者多個Web App,每個Web App對應於一個Context,有一個Context path,當Host獲得一個請求時,將把該請求匹配到某個Context上,然後把該請求交給該Context來處理,匹配的方法是“最長匹配”,所以一個path==""的Context將成為該Host的預設Context,所有無法和其它Context的路徑名匹配的請求都將最終和該預設Context匹配

(6)Context
一個Context對應於一個Web Application,一個Web Application由一個或者多個Servlet組成,Context在建立的時候將根據配置檔案$CATALINA_HOME/conf/web.xml和$WEBAPP_HOME/WEB-INF/web.xml載入Servlet類,當Context獲得請求時,將在自己的對映表(mapping table)中尋找相匹配的Servlet類,如果找到,則執行該類,獲得請求的迴應,並返回。

二、Tomcat的http請求處理

(1)browser 請求url被髮送到本機埠預設為80,被在那裡偵聽的Coyote HTTP/1.1 Connector獲得 

(2) Connector把該請求交給它所在的Service的Engine來處理,並等待來自Engine的迴應 
(3) Engine獲得請求url,匹配它所擁有的所有虛擬主機Host 
(4) Engine匹配到名為severName的Host(即使匹配不到也把請求交給localhost Host處理,因為該Host被定義為該Engine的預設主機) 
(5) Host獲得請求url,匹配它所擁有的所有Context 
(6) Host匹配到路徑字首相同的Context(如果匹配不到就把該請求交給路徑名為”“的Context去處理) 
(7)Context獲得請求url,在它的mapping table中尋找對應的servlet 
(8) Context匹配到URL PATTERN為*.jsp的servlet,對應於JspServlet類 
(9) 構造HttpServletRequest物件和HttpServletResponse物件,作為引數呼叫Servlet的doGet或doPost方法 
(10)Context把執行完了之後的HttpServletResponse物件返回給Host 
(11)Host把HttpServletResponse物件返回給Engine 
(12)Engine把HttpServletResponse物件返回給Connector 
(13)Connector把HttpServletResponse物件返回給客戶browser

三、tomcat處理一個請求的詳細流程

  protocolHandler負責生成endpoint和Http11ConnectionHandler,endpoint的acceptor執行緒負責處理連線請求,收到連線請求後交給worker執行緒處理。work執行緒呼叫Http11ConnectionHandler,Http11ConnectionHandler維護一個Http11Processor池,在構造Http11Processor時將生成org.apache.coyote.Request和org.apache.coyote.Response物件。

  Http11Processor使用InternalInputBuffer類來解析http協議,並將解析後的資料(請求頭,分割行等)封裝到org.apache.coyote.Request和org.apache.coyote.Response物件中,之後將此兩物件傳給CoyoteAdapter.service(request, response)在該方法內部實現了org.apache.coyote.Request --> org.apache.catalina.connector.Request,

org.apache.coyote.Response --> org.apache.catalina.connector.Response的轉換。

  接下來請求進入pipeline,pipeline中value的執行(呼叫value的invoke方法)順序如下: 
StandardEngineValve --> StandardHostValve --> StandardContextValve --> StandardWrapperValve --> ApplicationFilterChain.doFilter --> Servlet(HttpServlet).service 
(由StandardWrapper建立的單例項——多執行緒共用),invoke方法的引數即為org.apache.catalina.connector.Request/Response。 
  如果是jsp則繼續-->JspServletWrapper.service-->Compiler(如果沒有被編譯的話) --> 裝載具體編譯後的servlet class file-->交給具體servlet的service方法 --> 通過out.write寫入html頁面,事實上這個out是response.getWriter,所以也就將結果寫入了response。