牛逼!硬核圖解 Tomcat 整體架構(gòu)
來自:rhsphere

總體架構(gòu)
處理 socket 連接,負(fù)責(zé)將網(wǎng)絡(luò)字節(jié)流與 Request 和 Response 對象的轉(zhuǎn)化;
加載和管理 Servlet,以及具體處理 Request 請求;
Tomcat 支持的 io 模型有 NIO、NIO2、APR,Tomcat 支持的應(yīng)用層協(xié)議有 http1.1 ajp http2.0。
Tomcat 最頂層是 server,一個 server 有多個 service,一個 service 有多個連接器和一個容器,連接器和容器之間通過 ServletRequest 和 ServletResponse 通信。

通過組合模式、模板方法、觀察者模式和骨架抽象類,tomcat 定義了基類 LifeCycleBean 實現(xiàn) LifeCycle 接口,把公共的邏輯,生命周期狀態(tài)轉(zhuǎn)變和維護、生命事件的觸發(fā)和監(jiān)聽器的添加刪除,子類負(fù)責(zé)實現(xiàn)自己的 init、stop 和 start 等方法。
tomcat 自定義了監(jiān)聽器; @WebListener 注解,定義自己的監(jiān)聽器;
StandardServer、StandardService 等是 Server 和 Service 組件的具體實現(xiàn)類,它們都繼承了 LifecycleBase。
StandardEngine、StandardHost、StandardContext 和 StandardWrapper 是相應(yīng)容器組件的具體實現(xiàn)類,因為它們都是容器,所以繼承了 ContainerBase 抽象基類,而 ContainerBase 實現(xiàn)了 Container 接口,也繼承了 LifecycleBase 類,它們的生命周期管理接口和功能接口是分開的。
連接器 Connector
監(jiān)聽網(wǎng)絡(luò)端口; 接受網(wǎng)絡(luò)請求; 讀取網(wǎng)絡(luò)字節(jié)流; 根據(jù)應(yīng)用層協(xié)議解析字節(jié)流,生成統(tǒng)一的 tomcat request 和 tomcat response 對象; 將 tomcat request 對象轉(zhuǎn)成 servletRequest; 調(diào)用 servlet 容器,得到 servletResponse; 將 servletResponse 轉(zhuǎn)成 tomcat response; 將 tomcat response 轉(zhuǎn)成網(wǎng)絡(luò)字節(jié)流; 將響應(yīng)字節(jié)流寫回給瀏覽器;
網(wǎng)絡(luò)通信; 應(yīng)用層協(xié)議解析; tomcat request/response 與 servlet request/response 的轉(zhuǎn)換;
組件通過接口交互,好處是封裝變化。Endpoint 負(fù)責(zé)提供字節(jié)流給 Processor,Processor 負(fù)責(zé)提供 tomcat request 對象給 Adapter,Adapter負(fù)責(zé)提供 Servlet Request 給容器。
其中 Endpoint 和 Processor 抽象組裝在一起形成了 ProtocolHandler 組件。

ProtocolHandler
Endpoint
接口,抽象實現(xiàn)類是 AbstractEndpoint,具體子類在 NioEndpoint 和 Nio2Endpoint,其中兩個重要組件:Acceptor 和 SocketProcessor。
Acceptor 用于監(jiān)聽 Socket 連接請求,SocketProcessor 用于處理收到的 Socket 請求,提交到線程池 Executor 處理。
Processor
接收 Endpoint 的 socket,讀取字節(jié)流解析成 tomcat request 和 response,通過 adapter 將其提交到容器處理。Processor 的具體實現(xiàn)類 AjpProcessor、Http11Processor 實現(xiàn)了特定協(xié)議的解析方法和請求處理方式。

Endpoint 接收到 socket 連接后,生成一個 socketProcessor 交給線程池處理,run 方法會調(diào)用 Processor 解析應(yīng)用層協(xié)議,生成 tomcat request 后,調(diào)用 adapter 的 service 方法。
Adapter
ProtocolHandler 接口負(fù)責(zé)解析請求生成 tomcat requst,CoyoteAdapter 的 service 方法,將 Tomcat Request 對象,轉(zhuǎn)成 ServletRequest,再調(diào)用 service 方法。
容器 Container
容器的層次結(jié)構(gòu)
父子關(guān)系的 Engine、Host、Context、Wrapper 和 Servlet。Context 表示 web 應(yīng)用程序、wrapper 表示 servlet、context 有多個 wrapper,host 也有多個 context。

Host 代表的是一個虛擬主機,或者說一個站點,可以給 Tomcat 配置多個虛擬主機地址,而一個虛擬主機下可以部署多個 Web 應(yīng)用程序;Engine 表示引擎,用來管理多個虛擬站點,一個 Service 最多只能有一個 Engine。

容器通過 Pipeline-Valve 責(zé)任鏈,對請求一次處理,invoke 處理方法,每個容器都有一個 Pipeline,觸發(fā)第一個 Valve,這個容器的 valve 都會被調(diào)到,不同容器之間通過 Pipeline 的 getBasic 方法,負(fù)責(zé)調(diào)用下層容器的第一個 Valve。

整個調(diào)用連由連接器中的 adapter 觸發(fā),調(diào)用 engine 中的第一個 Valve。
1// Calling the container
2connector.getService().getContainer().getPipeline().getFirst().invoke(request, response);
wrapper 容器的最后一個 valve 創(chuàng)建一個 filter 鏈,并調(diào)用 doFilter 方法,最終會調(diào)用到 servlet 的 service 方法。
1final class StandardWrapperValve
2 extends ValveBase {
3
4 @Override
5 public final void invoke(Request request, Response response)
6 throws IOException, ServletException {
7 // ...
8
9 ApplicationFilterChain filterChain =
10 ApplicationFilterFactory.createFilterChain(request, wrapper, servlet);
11
12 // Call the filter chain for this request
13 // NOTE: This also calls the servlet's service() method
14 Container container = this.container;
15 try {
16 if ((servlet != null) && (filterChain != null)) {
17 // Swallow output if needed
18 if (context.getSwallowOutput()) {
19 try {
20 SystemLogHandler.startCapture();
21 if (request.isAsyncDispatching()) {
22 request.getAsyncContextInternal().doInternalDispatch();
23 } else {
24
25 // dofilter
26 filterChain.doFilter(request.getRequest(),
27 response.getResponse());
28 }
29 } finally {
30 String log = SystemLogHandler.stopCapture();
31 if (log != null && log.length() > 0) {
32 context.getLogger().info(log);
33 }
34 }
35 } else {
36 if (request.isAsyncDispatching()) {
37 request.getAsyncContextInternal().doInternalDispatch();
38 } else {
39 // dofilter
40 filterChain.doFilter
41 (request.getRequest(), response.getResponse());
42 }
43 }
44
45 }
46 } catch() {
47 // ...
48 }
49 }
50}ServletContext 是 tomcat 中的一個成員變量,spring 中的 ApplicationContext 是 servlet 規(guī)范中的 ServletContext 屬性。
最近有讀者想要分布式的項目,還有想要商城的,還有想要springboot,springcloud,k8s等等,這次直接分享幾乎涵蓋了我們java程序員的大部分技術(shù)桟,可以說真的非常全面了。強烈建議大家都上手做一做,而且以后肯定用的上。資料包含高清視頻+課件+源碼……
掃以下二維碼并回復(fù)“99”即可獲取
掃描上方二維碼,關(guān)注并回復(fù)【99】馬上獲取

