走進JavaWeb技術世界5:初探Tomcat的HTTP請求過程
- 2019 年 10 月 3 日
- 筆記
初探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程式設計師面試指南等乾貨資源)

