Tomcat 或者 Jetty 就是一個“HTTP 服務器 + Servlet 容器”,我們也叫它們 Web 容器。
Spring 框架就是對 Servlet 的封裝,Spring 應用本身就是一個 Servlet,而 Servlet 容器是管理和運行 Servlet 的。
Servlet 接口和 Servlet 容器這一整套規范叫作 Servlet 規范。Tomcat 和 Jetty 都按照 Servlet 規范的要求實現了 Servlet 容器。
Servlet 容器工作流程:
當客戶請求某個資源時,HTTP 服務器會用一個 ServletRequest 對象把客戶的請求信息封裝起來,然后調用 Servlet 容器的 service 方法,Servlet 容器拿到請求后,根據請求的 URL 和 Servlet 的映射關系,找到相應的 Servlet,如果 Servlet 還沒有被加載,就用反射機制創建這個 Servlet,并調用 Servlet 的 init 方法來完成初始化,接著調用 Servlet 的 service 方法來處理請求,把 ServletResponse 對象返回給 HTTP 服務器,HTTP 服務器會把響應發送給客戶端。
Servlet 規范提供了兩種擴展機制:Filter和Listener。
- Filter 是干預過程的,它是過程的一部分,是基于過程行為的。
- Listener 是基于狀態的,任何行為改變同一個狀態,觸發的事件是一致。
一、Tomcat系統架構
Tomcat 要實現 2 個核心功能:
- 處理 Socket 連接,負責網絡字節流與 Request 和 Response 對象的轉化。
- 加載和管理 Servlet,以及具體處理 Request 請求。
因此 Tomcat 設計了兩個核心組件連接器(Connector)和容器(Container)來分別做這兩件事情。連接器負責對外交流,容器負責內部處理。
1,連接器
連接器需要完成 3 個高內聚的功能:
- 網絡通信。
- 應用層協議解析。
- Tomcat Request/Response 與 ServletRequest/ServletResponse 的轉化。
因此 Tomcat 的設計者設計了 3 個組件來實現這 3 個功能,分別是 EndPoint、Processor 和 Adapter。
Endpoint 和 Processor 放在一起抽象成了 ProtocolHandler 組件,連接器用 ProtocolHandler 來處理網絡連接和應用層協議。
EndPoint 是一個接口,它的抽象實現類 AbstractEndpoint 里面定義了兩個內部類:Acceptor 和 SocketProcessor。其中 Acceptor 用于監聽 Socket 連接請求。SocketProcessor 用于處理接收到的 Socket 請求。
EndPoint 接收到 Socket 連接后,生成一個 SocketProcessor 任務提交到線程池去處理,SocketProcessor 的 Run 方法會調用 Processor 組件去解析應用層協議,Processor 通過解析生成 Request 對象后,會調用 Adapter 的 Service 方法。
2,容器
Tomcat 設計了 4 種容器,分別是 Engine、Host、Context 和 WrApper。這 4 種容器不是平行關系,而是父子關系。
Context 表示一個 Web 應用程序;Wrapper 表示一個 Servlet,一個 Web 應用程序中可能會有多個 Servlet;Host 代表的是一個虛擬主機,或者說一個站點,可以給 Tomcat 配置多個虛擬主機地址,而一個虛擬主機下可以部署多個 Web 應用程序;Engine 表示引擎,用來管理多個虛擬站點,一個 Service 最多只能有一個 Engine。
請求定位 Servlet 的過程:Tomcat 會創建一個 Service 組件和一個 Engine 容器組件,在 Engine 容器下創建兩個 Host 子容器,在每個 Host 容器下創建兩個 Context 子容器。由于一個 Web 應用通常有多個 Servlet,Tomcat 還會在每個 Context 容器里創建多個 Wrapper 子容器。
每一個容器都有一個 Pipeline 對象。
3,一個請求在 Tomcat 中流轉的過程:
4,startup.sh 啟動 tomcat 的過程: