1. 程式人生 > >【Tomcat】Tomcat原理與系統架構

【Tomcat】Tomcat原理與系統架構

[Toc] ## 版本: https://archive.apache.org/dist/tomcat/tomcat-8/v8.5.50/ ## 一,目錄說明 ![image-20201223212212784](https://typora-files.oss-cn-beijing.aliyuncs.com/file/image-20201223212212784.png) - bin/ bin目錄下關注兩個檔案:啟動和停止的指令碼檔案 啟動:`startup.bat`(win),`startup.sh`(Linux & Mac) 停止:`shutdown.bat`(win),`shutdown.sh`(Linux & Mac) - conf/ 配置檔案存放的目錄 `logging.properties`:日誌的配置 `server.xml`:伺服器配置檔案,例如埠的指定 `tomcat-users.xml`:定義了tomcat的角色以及角色擁有的功能 `web.xml`:全域性配置,很熟悉,我們java web工程也有自己的web.xml,這個是Tomcat級別的,自己的web.xml如果和它重複那麼自己的會覆蓋Tomcat的。 - lib/ 存放jar包 tomcat本身也是基於java開發的,它的執行也依賴於一些基礎的jar包 - logs/ 存放日誌 - temp/ 臨時目錄 - webapps/ 預設釋出專案的目錄 當我們釋出一個專案時,需要把我們專案的jar包(如釋出jar包,它會解壓出來)或者檔案存放在該目錄 - work/ jsp編譯執行存放過程檔案的目錄 ## 二,瀏覽器訪問伺服器的流程 **Http請求的處理過程:** ![image-20201223213708344](https://typora-files.oss-cn-beijing.aliyuncs.com/file/image-20201223213708344.png) http請求只是定義了資料的組織格式(通訊格式),是一個應用層協議,資料傳輸依靠的是TCP/IP協議。 1. 使用者發起請求(url地址、點選、搜尋等)動作被**瀏覽器**捕獲 2. **瀏覽器**傳送TCP連線請求,到伺服器(socket處理) 3. **伺服器**接收請求並建立連線(三次握手) 4. 連線上之後,**瀏覽器**生成Http協議格式(比如說定義請求頭裡放xxxx,請求體裡放xxxxx)的資料包 5. **瀏覽器**傳送請求資料包(也是依靠TCP協議) 6. **伺服器**解析Http格式的資料包 7. **伺服器**執行請求完成業務邏輯 8. **伺服器**生成Http協議格式的資料包 9. **伺服器**傳送響應資料包(同樣依靠TCP協議) 10. **瀏覽器**解析Http格式的資料包 11. **瀏覽器**呈現靜態資料給使用者 傳輸的形式: ![image-20201223214317941](https://typora-files.oss-cn-beijing.aliyuncs.com/file/image-20201223214317941.png) ## 三,Tomcat系統總體架構 ### 3.1 Tomcat請求的大致流程 **Tomcat是一個Http伺服器(因為它能夠接收處理Http請求)** 我們使⽤瀏覽器向某⼀個⽹站發起請求,發出的是Http請求,那麼在遠端,Http伺服器接收到這個請求之後,會調⽤具體的程式(Java類)進⾏處理,往往不同的請求由不同的Java類完成處理。 ![image-20201223221200909](https://typora-files.oss-cn-beijing.aliyuncs.com/file/image-20201223221200909.png) **大致流程:**與上圖不同,增加了Servlet容器解耦 ![image-20201223221419723](https://typora-files.oss-cn-beijing.aliyuncs.com/file/image-20201223221419723.png) HTTP 伺服器接收到請求之後把請求交給Servlet容器來處理,Servlet 容器通過Servlet接⼝調⽤業務類。**Servlet接⼝和Servlet容器這⼀整套內容叫作Servlet規範。** > 注意:Tomcat既按照Servlet規範的要求去實現了Servlet容器,同時它也具有HTTP伺服器的功能。 > > Tomcat的兩個重要身份 > > 1)http伺服器 > > 2)Tomcat是⼀個Servlet容器 ### 3.2 Servlet容器處理請求流程 當⽤戶請求某個URL資源時 1. HTTP伺服器會把請求資訊封裝成Request物件,然後轉換為**ServletRequest**物件 2. 進⼀步去調⽤Servlet容器中某個具體的**Servlet** 3. 在 2中,Servlet容器拿到請求後,根據URL和Servlet的對映關係,找到相應的Servlet 4. 如果Servlet還沒有被載入,就⽤反射機制建立這個Servlet,並調⽤Servlet的init⽅法來完成初始化(反射) 5. 接著調⽤這個具體Servlet的service⽅法來處理請求,請求處理結果使⽤ServletResponse物件封裝 6. 把ServletResponse物件返回給HTTP伺服器,HTTP伺服器會把響應傳送給客戶端 ![image-20201223222637232](https://typora-files.oss-cn-beijing.aliyuncs.com/file/image-20201223222637232.png) ### 3.3 Tomcat系統總體架構 從上可以看出,Tomcat兩個重要的功能: 1. 和客戶端瀏覽器進⾏互動,進⾏socket通訊,將位元組流和Request/Response等物件進⾏轉換 2. Servlet容器處理業務邏輯 Tomcat 設計了兩個核⼼元件**聯結器(Connector)**和**容器(Container)**來完成 Tomcat 的兩⼤核⼼功能: - **聯結器**,負責對外交流: 處理Socket連線,負責⽹絡位元組流與Request和Response物件的轉化; - **容器**,負責內部處理:載入和管理Servlet,以及具體處理Request請求; ![image-20201223222843720](https://typora-files.oss-cn-beijing.aliyuncs.com/file/image-20201223222843720.png) ## 四,Tomcat聯結器元件Coyote ### 4.1 簡介 Coyote 是Tomcat 中聯結器的元件名稱 , 是對外的接⼝。客戶端通過Coyote與伺服器建⽴連線、傳送請求並接受響應 。 1. Coyote 封裝了底層的⽹絡通訊(Socket 請求及響應處理) 2. Coyote 使**Catalina 容器(容器元件的名稱)**與具體的請求協議及IO操作⽅式完全解耦 3. Coyote 將Socket 輸⼊轉換**封裝為 Request 物件**,進⼀步封裝後(**再次封裝為ServletRequest**)交由Catalina 容器進⾏處理,處理請求完成後, Catalina 通過Coyote 提供的Response 物件將結果寫⼊輸出流 4. Coyote 負責的是具體**協議(應⽤層)**和**IO(傳輸層)**相關內容 ![image-20201223224257261](https://typora-files.oss-cn-beijing.aliyuncs.com/file/image-20201223224257261.png) **Tomcat Coyote支援的IO模型與協議:** ![image-20201223224941404](https://typora-files.oss-cn-beijing.aliyuncs.com/file/image-20201223224941404.png) 應用層預設協議:HTTP/1.1 傳輸層預設IO模型:NIO > 在 8.0 之前 ,Tomcat 預設採⽤的I/O⽅式為 BIO(同步阻塞IO),之後改為 NIO。 無論 NIO、NIO2 還是 APR, 在效能⽅⾯均優於以往的BIO。 如果採⽤APR, 甚⾄可以達到 Apache HTTP Server 的影響效能。 ### 4.2 Coyote內部元件以及流程 ![image-20201223230210550](https://typora-files.oss-cn-beijing.aliyuncs.com/file/image-20201223230210550.png) | 元件 | 作用描述 | | ------------------- | ------------------------------------------------------------ | | **EndPoint** | EndPoint 是 Coyote 通訊端點,即**通訊監聽的接⼝**,是**具體Socket接收和傳送處理器**,是**對傳輸層的抽象**,因此EndPoint⽤來**實現TCP/IP協議**的 | | **Processor** | Processor 是Coyote 協議處理接⼝ ,如果說EndPoint是⽤來實現TCP/IP協議的,那麼Processor**⽤來實現HTTP協議**,Processor接收來⾃EndPoint的 Socket,讀取位元組流**解析成Tomcat Request和Response物件**,並**通過 Adapter將其提交到容器**處理,Processor是**對應⽤層協議的抽象** | | **ProtocolHandler** | Coyote 協議接⼝, 通過Endpoint 和 Processor , 實現針對具體協議的處 理能⼒。Tomcat 按照協議和I/O 提供了6個實現類 : **AjpNioProtocol** , **AjpAprProtocol**, **AjpNio2Protocol** , **Http11NioProtocol** , **Http11Nio2Protocol** ,**Http11AprProtocol** | | **Adapter** | 由於協議不同,客戶端發過來的請求資訊也不盡相同,Tomcat定義了⾃⼰的 Request類來封裝這些請求資訊。ProtocolHandler接⼝負責解析請求並⽣成 Tomcat Request類。但是這個Request物件不是標準的ServletRequest,不能⽤Tomcat Request作為引數來調⽤容器。Tomcat設計者的解決⽅案是引⼊CoyoteAdapter,這是**介面卡模式的經典運⽤**,聯結器調⽤ CoyoteAdapter的Sevice⽅法,傳⼊的是Tomcat Request物件, CoyoteAdapter負責**將Tomcat Request轉成ServletRequest**,**再調⽤容器** | ## 五,Tomcat Servlet 容器 Catalina ### 5.1 Tomcat模組分層結構圖及Catalina位置 Tomcat是⼀個由⼀系列可配置(conf/server.xml)的元件構成的Web容器,⽽Catalina是Tomcat的servlet容器。 **Tomcat本質上就是⼀款Servlet容器**, 因為**Catalina才是Tomcat的核⼼** , **其他模組都是為Catalina 提供⽀撐的**。 ⽐如 : - 通過 Coyote 模組提供連結通訊 - Jasper 模組提供 JSP 引擎 - Naming 提供JNDI 服務 - Juli 提供⽇志服務。 **模組分層結構圖:** ![image-20201223235736095](https://typora-files.oss-cn-beijing.aliyuncs.com/file/image-20201223235736095.png) ### 5.2 Servlet容器Catalina結構 **也可以這麼說:Tomcat就是一個Catalina的例項,因為Catalina是Tomcat的核心。** Tomcat/Catalina例項: ![image-20201224001249519](https://typora-files.oss-cn-beijing.aliyuncs.com/file/image-20201224001249519.png) Tomcat 啟動的時候會初始化這個例項,Catalina 例項通過載入server.xml完成其他例項的建立,建立並管理⼀個Server,Server建立並管理多個服務, 每個服務⼜可以有多個Connector和⼀個Container。 - ⼀個Catalina例項(容器) - ⼀個**Server**例項(容器) - 多個**Service**例項(容器) **對應關係:每⼀個Service例項下可以有多個Connector例項和⼀個Container例項** - **Catalina** 負責解析Tomcat的配置⽂件(server.xml) , 以此來建立伺服器Server元件並進⾏管理 - **Server** 伺服器表示整個Catalina Servlet容器以及其它元件,負責組裝並啟動Servlet引擎、Tomcat聯結器。Server通過實現`Lifecycle`接⼝,提供了⼀種優雅的啟動和關閉整個系統的⽅式 - **Service** 服務是Server內部的元件,⼀個Server包含多個Service。它將若⼲個Connector元件繫結到⼀個 Container - **Container** 容器,負責處理⽤戶的servlet請求,並返回物件給web⽤戶的模組 ### 5.2 Container元件的具體結構 ![image-20201224002346585](https://typora-files.oss-cn-beijing.aliyuncs.com/file/image-20201224002346585.png) Container元件下有⼏種具體的元件,分別是**Engine**、**Host**、**Context**和**Wrapper**。這4種元件(容器) 是⽗⼦關係。Tomcat通過⼀種分層的架構,使得Servlet容器具有很好的靈活性。 - **Engine** 表示整個Catalina的Servlet引擎,⽤來管理多個虛擬站點,⼀個Service最多隻能有⼀個Engine, 但是⼀個引擎可包含多個Host - **Host** 代表⼀個虛擬主機,或者說⼀個站點,可以給Tomcat配置多個虛擬主機地址,⽽⼀個虛擬主機下 可包含多個Context - **Context** 表示⼀個Web應⽤程式, ⼀個Web應⽤可包含多個Wrapper - **Wrapper** 表示⼀個Servlet,Wrapper 作為容器中的最底層,不能包含⼦容器 **上述元件的配置其實就體現在conf/server.xml中。** ![image-20201224002723935](https://typora-files.oss-cn-beijing.aliyuncs.com/file/image-20201224002723