tomcat的原理-組件connector

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è)大概。


image.png

所有組件:
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í) :

  1. tomcat組件實(shí)現(xiàn)了lifeCyle接口 生命周期方法為: init-> start -> stop-> destroy
  2. tomcat組件繼承了lifeCyleBase 抽象類
  3. 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

  1. 構(gòu)造函數(shù)初始化


    image.png

connector 是通過(guò)此構(gòu)造器創(chuàng)建的【上層如何創(chuàng)建這個(gè)對(duì)象 ,我們后續(xù)再說(shuō)

看一下 ProtocolHandler 的創(chuàng)建過(guò)程


image.png
image.png
image.png
image.png

到這里已明白, protocolHandler 默認(rèn)使用Http11NioProtocol .
Http11NioProtocol 對(duì)象創(chuàng)建時(shí)候 屬性 endpoint 被賦值為 NioEndpoint 對(duì)象。
Http11NioProtocol handler 屬性設(shè)置為 ConnectionHandler
Endpoint handler 屬性設(shè)置為 ConnectionHandler

  1. 初始化init

a> 創(chuàng)建 CoyoteAdapter 并注冊(cè)到protocolHandler 中


image.png

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


image.png

image.png

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

在 AbstractProtocol.init() 中 endpoint 初始化:

image.png

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


image.png

類: NioEndpoint 方法 init()

image.png

類: AbstractEndpoint 方法: init()


image.png

類: NioEndpoint 方法 : bind()


image.png

類: NioEndpNioEnoint 方法 : initServerSocket()


image.png

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


image.png

類 : AbstractProtocol 方法: start()


image.png

類: NioEndpNioEnoint 方法 : startInternal()


image.png

我們分析下紅色箭頭 3,4 中的創(chuàng)建 poller 線程 和 acceptor 線程的作用是什么?

先看Accetpor 線程:
1.實(shí)現(xiàn)了runnable 接口 ,在run()方法中:

image.png

image.png

再看poller 線程:


image.png

Abs


image.png
image.png

至此,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


image.png

看下SocketProcessor類的作用

類: NioEndpoint.SocketProcessor
創(chuàng)建:


image.png

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

image.png

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

類: NioEndpoint.SocketProcessor 方法 : doRun()


image.png

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

image.png
image.png

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


image.png

AbstractProcessorLight類中 的process() 方法


image.png

子類: Http11Processor 的service()方法


image.png

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


image.png

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

image.png

自此, 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

  1. 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

  2. adapter 用于 內(nèi)部 request 和 response 轉(zhuǎn)換 成sevlet 規(guī)范的 HttpServletReqeust , HttpServiceResponse

  3. EndPoint 一圖以避之


    image.png
  4. 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é)下:

protocl.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容