走進JavaWeb技術世界5:初探Tomcat的HTTP請求過程
初探Tomcat的HTTP請求過程
前言:
1.作為Java開發人員,大多都對Tomcat不陌生,由Apache基金會提供技術支援與維護,因為其免費開源且易用,作為Web伺服器深受市場歡迎,所以有必要對其進行深入的研究,本系列皆以Tomcat 8.5為研究課題,下載地址:https://tomcat.apache.org/download-80.cgi
2.下圖為 apache-tomcat-8.5.23.zip 在windows解壓後的目錄。
下面是解壓後的一些關鍵目錄:
* /bin - 啟動和停止服務等批處理檔案. ( *.sh) 檔案 (為Unix系統)、 (*.bat) 檔案 (for Windows系統)是一個功能性的複製檔案. 自從Win32 command-line 開始是一些單一的,缺乏功能的元件, 現在有一些拓展性的功能 * /conf - 配置檔案和一些相關的DTD檔案. 最重要的是 server.xml. 它是這個容器最主要的配置檔案. * /logs - 日誌檔案會列印到這裡 * /webapps - 這裡是你的應用程式部署的地方.
3.從最本質上講,tomcat為一個servlet容器,首先研究一下Tomcat的架構,如下圖:
架構詮釋:
1.Server(伺服器)是Tomcat構成的頂級構成元素,所有一切均包含在Server中,Server的實現類StandardServer可以包含一個到多個Services,Service的實現類為StandardService呼叫了容器(Container)介面,其實是呼叫了Servlet Engine(引擎),而且StandardService類中也指明瞭該Service歸屬的Server;
2.Container: 引擎(Engine)、主機(Host)、上下文(Context)和Wraper均繼承自Container介面,所以它們都是容器。但是,它們是有父子關係的,在主機(Host)、上下文(Context)和引擎(Engine)這三類容器中,引擎是頂級容器,直接包含是主機容器,而主機容器又包含上下文容器,所以引擎、主機和上下文從大小上來說又構成父子關係,雖然它們都繼承自Container介面。
3.聯結器(Connector)將Service和Container連線起來,首先它需要註冊到一個Service,它的作用就是把來自客戶端的請求轉發到Container(容器),這就是它為什麼稱作聯結器的原因。
從功能的角度將Tomcat原始碼分成5個子模組,分別是:
Jsper模組: 這個子模組負責jsp頁面的解析、jsp屬性的驗證,同時也負責將jsp頁面動態轉換為java程式碼並編譯成class檔案。在Tomcat原始碼中,凡是屬於org.apache.jasper包及其子包中的原始碼都屬於這個子模組;
Servlet和Jsp模組: 這個子模組的原始碼屬於javax.servlet包及其子包,如我們非常熟悉的javax.servlet.Servlet介面、javax.servet.http.HttpServlet類及javax.servlet.jsp.HttpJspPage就位於這個子模組中;
Catalina模組: 這個子模組包含了所有以org.apache.catalina開頭的java原始碼。該子模組的任務是規範了Tomcat的總體架構,定義了Server、Service、Host、Connector、Context、Session及Cluster等關鍵元件及這些元件的實現,這個子模組大量運用了Composite設計模式。同時也規範了Catalina的啟動及停止等事件的執行流程。從程式碼閱讀的角度看,這個子模組應該是我們閱讀和學習的重點。
Connector模組: 如果說上面三個子模組實現了Tomcat應用伺服器的話,那麼這個子模組就是Web伺服器的實現。所謂聯結器(Connector)就是一個連線客戶和應用伺服器的橋樑,它接收使用者的請求,並把使用者請求包裝成標準的Http請求(包含協議名稱,請求頭Head,請求方法是Get還是Post等等)。同時,這個子模組還按照標準的Http協議,負責給客戶端傳送響應頁面,比如在請求頁面未發現時,connector就會給客戶端瀏覽器傳送標準的Http 404錯誤響應頁面。
Resource模組: 這個子模組包含一些資原始檔,如Server.xml及Web.xml配置檔案。嚴格說來,這個子模組不包含java原始碼,但是它還是Tomcat編譯執行所必需的。
Tomcat的組織結構
- Tomcat是一個基於元件的伺服器,它的構成元件都是可配置的,其中最外層的是Catalina servlet容器,其他元件按照一定的格式要求配置在這個頂層容器中。
Tomcat的各種元件都是在Tomcat安裝目錄下的/conf/server.xml檔案中配置的。
由Server.xml的結構看Tomcat的體系結構
1 2 3 4 5 6 7 8 9 10 11 12 |
|
實際原始碼如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
|
由上可得出Tomcat的體系結構:
圖一:Tomcat的體系結構
由上圖可看出Tomca的心臟是兩個元件:Connecter和Container。一個Container可以選擇多個Connecter,多個Connector和一個Container就形成了一個Service。Service可以對外提供服務,而Server伺服器控制整個Tomcat的生命週期。
Tomcat Server處理一個HTTP請求的過程
圖三:Tomcat Server處理一個HTTP請求的過程
Tomcat Server處理一個HTTP請求的過程
1、使用者點選網頁內容,請求被髮送到本機埠8080,被在那裡監聽的Coyote HTTP/1.1 Connector獲得。
2、Connector把該請求交給它所在的Service的Engine來處理,並等待Engine的迴應。
3、Engine獲得請求localhost/test/index.jsp,匹配所有的虛擬主機Host。
4、Engine匹配到名為localhost的Host(即使匹配不到也把請求交給該Host處理,因為該Host被定義為該Engine的預設主機),名為localhost的Host獲得請求/test/index.jsp,匹配它所擁有的所有的Context。Host匹配到路徑為/test的Context(如果匹配不到就把該請求交給路徑名為“ ”的Context去處理)。
5、path=“/test”的Context獲得請求/index.jsp,在它的mapping table中尋找出對應的Servlet。Context匹配到URL PATTERN為*.jsp的Servlet,對應於JspServlet類。
6、構造HttpServletRequest物件和HttpServletResponse物件,作為引數呼叫JspServlet的doGet()或doPost().執行業務邏輯、資料儲存等程式。
7、Context把執行完之後的HttpServletResponse物件返回給Host。
8、Host把HttpServletResponse物件返回給Engine。
9、Engine把HttpServletResponse物件返回Connector。
10、Connector把HttpServletResponse物件返回給客戶Browser。
微信公眾號【Java技術江湖】一位阿里 Java 工程師的技術小站。(關注公眾號後回覆”Java“即可領取 Java基礎、進階、專案和架構師等免費學習資料,更有資料庫、分散式、微服務等熱門技術學習視訊,內容豐富,兼顧原理和實踐,另外也將贈送作者原創的Java學習指南、Java程式設計師面試指南等乾貨資源)