tomcat 發(fā)展多年,成熟而穩(wěn)定, 但是在當(dāng)今最新求快的 java web 技術(shù)棧中,這種優(yōu)秀的中間件卻與我們漸行漸遠(yuǎn)。
靜下心來(lái)學(xué)習(xí) , 賞析大牛們是如何設(shè)計(jì)和架構(gòu)一個(gè)優(yōu)秀的中間件系統(tǒng),如有錯(cuò)誤,共同探討,共同學(xué)習(xí)。
宏觀架構(gòu)
tomcat 的啟動(dòng)流程: startup.sh -> catalina.sh start ->java -jar org.apache.catalina.startup.Bootstrap.main()
先上小圖,一圖以避之,看個(gè)大概。

所有組件:
1.server: 一個(gè)tomcat實(shí)例
2.service: 處理即將到來(lái)的socket服務(wù)
3.connector : socket 連接器 , http協(xié)議的轉(zhuǎn)化
4.container : 加載管理servlet 并處理request
其中核心組件 為connector, container
預(yù)備知識(shí) :
- tomcat組件實(shí)現(xiàn)了lifeCyle接口 生命周期方法為: init-> start -> stop-> destroy
- tomcat組件繼承了lifeCyleBase 抽象類
- lifeCyleBase 抽象類 中實(shí)現(xiàn)了 lifeCycle接口的方法, 并且個(gè)主鍵在調(diào)用相應(yīng)的生命周期方法會(huì)調(diào)用內(nèi)部的 initInternal startInternal stopInternal destroyInternal 方法
關(guān)于組件的初始化 啟動(dòng) 停止 銷毀 我們后續(xù)探討。
connector
-
構(gòu)造函數(shù)初始化
image.png
connector 是通過(guò)此構(gòu)造器創(chuàng)建的【上層如何創(chuàng)建這個(gè)對(duì)象 ,我們后續(xù)再說(shuō)】
看一下 ProtocolHandler 的創(chuàng)建過(guò)程




到這里已明白, protocolHandler 默認(rèn)使用Http11NioProtocol .
Http11NioProtocol 對(duì)象創(chuàng)建時(shí)候 屬性 endpoint 被賦值為 NioEndpoint 對(duì)象。
Http11NioProtocol handler 屬性設(shè)置為 ConnectionHandler
Endpoint handler 屬性設(shè)置為 ConnectionHandler
- 初始化init
a> 創(chuàng)建 CoyoteAdapter 并注冊(cè)到protocolHandler 中

b> protocolHandler 【即 構(gòu)造函數(shù)初始化 分析的Http11NioProtocol 】初始化, 先看下ProtocolHandler 的體系圖。


初始化過(guò)程:
Http11NioProtocol.init()->AbstractHttp11Protocol.init()->AbstractProtocol.init()
即子類初始化調(diào)用父類初始化。
在 AbstractProtocol.init() 中 endpoint 初始化:

c.endpoint初始化
看下endpint 的類繼承關(guān)系

類: NioEndpoint 方法 init()

類: AbstractEndpoint 方法: init()

類: NioEndpoint 方法 : bind()

類: NioEndpNioEnoint 方法 : initServerSocket()

3.啟動(dòng)start() 方法
類 : Connector 方法 : startInternal()

類 : AbstractProtocol 方法: start()

類: NioEndpNioEnoint 方法 : startInternal()

我們分析下紅色箭頭 3,4 中的創(chuàng)建 poller 線程 和 acceptor 線程的作用是什么?
先看Accetpor 線程:
1.實(shí)現(xiàn)了runnable 接口 ,在run()方法中:


再看poller 線程:

Abs


至此,Acceptor跑在一個(gè)單獨(dú)的線程里,它在一個(gè)死循環(huán)里調(diào)用 accept方法來(lái)接收新連接,一旦有新的連接請(qǐng)求到來(lái),accept方法返回一個(gè) Channel 對(duì)象,接著把 Channel對(duì)象交給 Poller 去處理。
Poller 的本質(zhì)是一個(gè) Selector,也跑在單獨(dú)線程里。Poller在內(nèi)部維護(hù)一個(gè) Channel數(shù)組,它在一個(gè)死循環(huán)里不斷檢測(cè) Channel的數(shù)據(jù)就緒狀態(tài),一旦有 Channel可讀,就生成一個(gè) SocketProcessor任務(wù)對(duì)象扔給 Executor去處理。
我們來(lái)看下processSocket方法是如何處理socketWrapper的?
類: AbstractEndpoint 方法 : processSocket

看下SocketProcessor類的作用
類: NioEndpoint.SocketProcessor
創(chuàng)建:

看下繼承關(guān)系:

當(dāng)使用線程池執(zhí)行的時(shí)候,活執(zhí)行父類SocketProcessorBase 的run()方法 ,父類的run()方法 會(huì)調(diào)用子類SocketProcessor的doRun()方法。
類: NioEndpoint.SocketProcessor 方法 : doRun()

我們知道在創(chuàng)建Http11NioProtocol 對(duì)象的同時(shí) ,創(chuàng)建了NioEndpoint ,并給NioEndpoint 設(shè)置handler 屬性為 ConnectionHandler , 我們看下
ConnectionHandler 的 process 方法。


會(huì)調(diào)用Http11NioProtocol 的 createProcessor方法 創(chuàng)建 Http11Processor 對(duì)象 http11Processor繼承關(guān)系如下 :

AbstractProcessorLight類中 的process() 方法

子類: Http11Processor 的service()方法

我們知道在 Connector組件初始化的時(shí)候 給protocolHandler設(shè)置了adapter屬性,如下:

也就是說(shuō): getAdapter().servcive(req , rep) 交給了CoyoteAdapter 適配器來(lái)處理。

自此, connector 組件如何處理一個(gè)socket 請(qǐng)求,分析完畢
總結(jié):
1.一個(gè)connector組件 可分為 protocolHandler 和 Adapter ,protocolHandler 用于處理 網(wǎng)絡(luò)請(qǐng)求 , Adapter 將內(nèi)部request , response 適配成 servlet的HttpServletReqeust , HttpServiceResponse
protocolHandler主要處理 網(wǎng)絡(luò)連接 和 應(yīng)用層協(xié)議 ,包含了兩個(gè)重要部件 EndPoint 和 Processor, EndPoint 是用來(lái)實(shí)現(xiàn) TCP/IP 協(xié)議數(shù)據(jù)讀寫(xiě)的,本質(zhì)調(diào)用操作系統(tǒng)的 socket 接口 , Processor用于處理socket, 轉(zhuǎn)換應(yīng)用層協(xié)議 ,封裝內(nèi)部 request 和 response
adapter 用于 內(nèi)部 request 和 response 轉(zhuǎn)換 成sevlet 規(guī)范的 HttpServletReqeust , HttpServiceResponse
-
EndPoint 一圖以避之
image.png -
Processor 用來(lái)實(shí)現(xiàn) HTTP 協(xié)議,Processor 接收來(lái)自 EndPoint 的 Socket,讀取字節(jié)流解析成 Tomcat Request 和 Response 對(duì)象,并通過(guò) Adapter 將其提交到容器處理,Processor 是對(duì)應(yīng)用層協(xié)議的抽象
image.png
最后簡(jiǎn)圖總結(jié)下:



