手寫一個簡化版Tomcat

Tomcat作為Web伺服器深受市場歡迎,有必要對其進行深入的研究。我們經常會把寫好的程式碼打包放在Tomcat裡並啟動就可以用了,但很想知道Web容器Tomcat是如何工作的?它是如何處理我們傳入http請求的?又是如何響應的?

一、Tomcat工作原理

啟動Tomcat時雙擊的startup。bat檔案的主要作用是找到catalina。bat,並且把引數傳遞給它,而catalina。bat中有這樣一段話:

手寫一個簡化版Tomcat

Bootstrap。class是整個tomcat 的入口,我們在Tomcat原始碼裡找到這個類,其中就有我們經常使用的main方法:

手寫一個簡化版Tomcat

這個類有兩個作用 :1。初始化一個守護程序變數、載入類和相應引數。2。解析命令,並執行。

原始碼不過多贅述,我們在這裡只需要把握整體架構,有興趣的同學可以自己研究下原始碼。Tomcat的server。xml配置檔案中可以對應構架圖中位置,多層的表示可以配置多個:

手寫一個簡化版Tomcat

即一個由 Server->Service->Engine->Host->Context 組成的結構,從裡層向外層分別是:

Server:伺服器Tomcat的頂級元素,它包含了所有東西。

Service:一組 Engine(引擎) 的集合,包括執行緒池 Executor 和聯結器 Connector 的定義。

Engine(引擎):一個 Engine代表一個完整的 Servlet 引擎,它接收來自Connector的請求,並決定傳給哪個Host來處理。

Container(容器):Host、Context、Engine和Wraper都繼承自Container介面,它們都是容器。

Connector(聯結器):將Service和Container連線起來,註冊到一個Service,把來自客戶端的請求轉發到Container。

Host:即虛擬主機,所謂的”一個虛擬主機”可簡單理解為”一個網站”。

Context(上下文 ): 即 Web 應用程式,一個 Context 即對於一個 Web 應用程式。Context容器直接管理Servlet的執行,Servlet會被其給包裝成一個StandardWrapper類去執行。Wrapper負責管理一個Servlet的裝載、初始化、執行以及資源回收,它是最底層容器。

比如現在有以下網址,根據“/”切割的連結就會定位到具體的處理邏輯上,且每個容器都有過濾功能。

手寫一個簡化版Tomcat

二、梳理自己的tomcat實現思路

本文實現效果比較簡單,僅供新手參考,大神勿噴。當我們瀏覽器訪問對應地址時:

手寫一個簡化版Tomcat

實現以上效果整體思路如下:

1。ServerSocket佔用8080埠,用while(true)迴圈等待使用者發請求。

2。拿到瀏覽器的請求,解析並返回URL地址,用I/O輸入流讀取本地磁碟上相應檔案。

3。讀取檔案,不存在構建響應報文頭、HTML正文內容,存在則寫到瀏覽器端。

三、實現自己的Tomcat

工程檔案結構和pom。xml檔案:

手寫一個簡化版Tomcat

1。HttpServer核心處理類,用於接受使用者請求,傳遞HTTP請求頭資訊,關閉容器:

手寫一個簡化版Tomcat

2。建立Request類,獲取HTTP的請求頭所有資訊並擷取URL地址返回:

手寫一個簡化版Tomcat

3。建立Response類,響應請求讀取檔案並寫回到瀏覽器

手寫一個簡化版Tomcat

到這裡本文的示例程式碼就編寫完成了。

四、讀者可以自己做的最佳化,擴充套件的點

1。在WEB_INF資料夾下讀取web。xml解析,透過請求名找到對應的類名,透過類名建立物件,用反射來初始化配置資訊,如welcome頁面,Servlet、servlet-mapping,filter,listener,啟動載入級別等。

2。抽象Servlet類來轉碼處理請求和響應的業務。發過來的請求會有很多,也就意味著我們應該會有很多的Servlet,例如:RegisterServlet、LoginServlet等等還有很多其他的訪問。可以用到類似於工廠模式的方法處理,隨時產生很多的Servlet,來滿足不同的功能性的請求。

3。使用多執行緒技術。本文的程式碼是死迴圈,且只能有一個連結,而現實中的情況是往往會有很多很多的客戶端發請求,可以把每個瀏覽器的通訊封裝到一個執行緒當中。

需要原始碼的在評論中回覆“要”,小編私信給你發。

還能做什麼擴充套件,實現什麼功能,也可以在評論中與小編探討。