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






