自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

深入分析 Tomcat 原理

開(kāi)發(fā) 架構(gòu)
隨著互聯(lián)網(wǎng)發(fā)展,往往更多的是需要?jiǎng)討B(tài)的交互。所以 Sun 公司推出了 Servlet 技術(shù):servlet 規(guī)范!目前最新是 Servlet 4.0 ,它支持 HTTP2.0!

早期Web容器早期的 Web 應(yīng)用主要用于瀏覽新聞等靜態(tài)頁(yè)面,HTTP 服務(wù)器(比如 Apache、Nginx)向?yàn)g覽器返回靜態(tài) HTML,瀏覽器負(fù)責(zé)解析 HTML,將結(jié)果呈現(xiàn)給用戶。

Servlet規(guī)范

隨著互聯(lián)網(wǎng)發(fā)展,往往更多的是需要?jiǎng)討B(tài)的交互。所以 Sun 公司推出了 Servlet 技術(shù):servlet 規(guī)范!目前最新是 Servlet 4.0 ,它支持 HTTP2.0!

符合 Servlet 規(guī)范的 Web 流程:由 Servlet 容器來(lái)創(chuàng)建和管理 Servlet,客戶端的請(qǐng)求 會(huì)被封裝成 ServletRequest 和 ServletResponse,其本質(zhì)上就是對(duì)通信協(xié)議的封裝。

Tomcat簡(jiǎn)介

Tomcat 就是一個(gè) Servlet 容器,實(shí)現(xiàn)了對(duì) Servlet 和 JavaServer Page(JSP)的支持。同時(shí),它還具有 HTTP 服務(wù)器的功能。所以,「Tomcat = HTTP服務(wù)器 + Servlet容器」,一般我們給這種組件稱為:「輕量級(jí)web容器」!

Tomcat架構(gòu)

Tomcat-Server

  • 「Server」:一個(gè) Server 就是一個(gè) Tomcat 實(shí)例,下載 Tomcat 壓縮包,執(zhí)行 /bin/startup.sh,就可以啟動(dòng)一個(gè) Tomcat 實(shí)例。
  • 「Service」:一個(gè)對(duì)外服務(wù)的整體,它包括多個(gè) Connector 和一個(gè) Engine。同時(shí),一個(gè) Server 可以配置多個(gè) Service。實(shí)際上 Service 只是將組件組合到一起,本身并沒(méi)有實(shí)現(xiàn)什么功能。

Tomcat-連接器

連接器,啟動(dòng) ServerSocket,負(fù)責(zé)監(jiān)聽(tīng) Socket 請(qǐng)求,將數(shù)據(jù)轉(zhuǎn)換成 Tomcat Request,交給 Engine 處理。一個(gè) Service 可以有多個(gè) Connector,表示它可以監(jiān)聽(tīng)多個(gè)端口。

Tomcat-容器

即 Servlet 容器,它是 Tomcat 容器的最頂層組件,它會(huì)管理多個(gè)虛擬主機(jī) Host,一個(gè) Service 只能有一個(gè) Engine,但是一個(gè) Engine 可以配置多個(gè) Host。Tomcat 的 Servlet 容器是具有明顯的分層架構(gòu)的。

  • 「Host」:虛擬主機(jī),默認(rèn)為 localhost,也就是 127.0.0.1。也可以配置不同的 IP 地址,訪問(wèn)不同的 IP 地址就可以訪問(wèn)到不同的虛擬主機(jī)。一個(gè) Host 可以部署多個(gè) Context。
  • 「Context」:應(yīng)用程序,一般會(huì)把我們實(shí)現(xiàn)的 Servlet 應(yīng)用打包成 war,放到 Tomcat 的 webapps 目錄下,Tomcat 會(huì)將其解壓并部署映射成一個(gè) Context 組件,表示一個(gè)應(yīng)用上下文。一個(gè) Context 可以管理多個(gè) Wrapper,畢竟一個(gè) web 應(yīng)用肯定有多個(gè) Servlet。
  • 「Wrapper」:這個(gè)組件 Tomcat 配置文件并沒(méi)有,因?yàn)樗窃?web.xml 配置,它就是 Servlet。確切地說(shuō),是 Tomcat 用 Wrapper 包裹了我們自己實(shí)現(xiàn)的 Servlet。一個(gè)請(qǐng)求最終就會(huì)到 Wrapper 來(lái)執(zhí)行。

Tomcat生命周期管理

「Tomcat 設(shè)計(jì)眾多組件來(lái)保證高內(nèi)聚低耦合,保證可擴(kuò)展性」。但是,組件數(shù)量多也會(huì)帶來(lái)其它問(wèn)題,比如組件的管理,在啟動(dòng)、關(guān)閉和銷毀需要涉及多個(gè)組件的操作。Tomcat 設(shè)計(jì)了 LifeCycle 接口,它定義生命周期鉤子函數(shù):init()、start()、stop() 和 destroy(),組件都實(shí)現(xiàn)這個(gè)接口,定義自己的處理邏輯。并且,上層組件在觸發(fā)自己生命周期鉤子函數(shù)的同時(shí),會(huì)觸發(fā)它管理的下層組件的鉤子函數(shù)。其實(shí)國(guó)外設(shè)計(jì)框架很喜歡設(shè)計(jì)這個(gè) LifeCycle 接口,新版 Apache Dubbo 也加入了這一特性。

Tomcat 在實(shí)現(xiàn)組件生命周期管理,充分利用了「組合模式、觀察者模式和模板模式」。

  • 「組合模式」:Tomcat 通過(guò)組合模式,用上層組件來(lái)管理它下一級(jí)組件,每個(gè)組件都是這樣的管理方式。這樣暴露給用戶的是,只需要對(duì)一個(gè)組件進(jìn)行訪問(wèn),則可以達(dá)到一個(gè)完整系統(tǒng)調(diào)用的一致性效果。以 Tomcat 最頂級(jí)的組件 Server 來(lái)看,它的 init() 方法:
  • 「觀察者模式」:Tomcat 考慮自身的可擴(kuò)展性,避免版本升級(jí)就得修改生命周期鉤子函數(shù),它引入了監(jiān)聽(tīng)器 LifecycleListener 和 LifecycleState。它設(shè)計(jì)了一套貫穿組件生命周期全過(guò)程的狀態(tài)集合,例如:當(dāng)組件剛創(chuàng)建則處于 NEW 狀態(tài),調(diào)用了 init() 方法處于 INITIALIZED 狀態(tài)...在調(diào)用生命周期方法的前后,會(huì)改變組件的狀態(tài),而狀態(tài)的改變會(huì)被封裝成為一個(gè)個(gè)事件 LifecycleEvent,由監(jiān)聽(tīng)器來(lái)處理這些事件。
  • 「模板模式」:主要體現(xiàn)了代碼實(shí)現(xiàn)上,實(shí)際上狀態(tài)的轉(zhuǎn)變、事件的創(chuàng)建以及監(jiān)聽(tīng)器的回調(diào),這些操作其實(shí)沒(méi)有必要在每個(gè)組件中自己實(shí)現(xiàn),這會(huì)造成重復(fù)代碼。Tomcat 在實(shí)現(xiàn)這個(gè)功能的時(shí)候,把這些通用邏輯抽象了出來(lái),定義為一個(gè) LifecycleBase 抽象類,它會(huì)定義骨架方法,比如 init() 方法。

Tomcat連接器

Tomcat 連接器,用來(lái)監(jiān)聽(tīng) Socket 連接,將 TCP 底層的字節(jié)流數(shù)據(jù),轉(zhuǎn)換為 Request 和 Response;連接器主要有3個(gè)組件:「EndPoint、Processor、Adapter」。

  • ?「Endpoint」 負(fù)責(zé)提供字節(jié)流給 Processor。
  • 「Processor」 負(fù)責(zé)提供 Tomcat Request 對(duì)象給 Adapter。
  • 「Adapter」 負(fù)責(zé)轉(zhuǎn)換 ServletRequest 對(duì)象給容器。

其中,Tomcat 將 EndPoint 和 Processor 組合到一起,組成了 ProtocolHandler,這其實(shí)就是一種組合設(shè)計(jì)模式的使用。

Tomcat連接器-NioEndpoint

「Tomcat 使用 NioEndPoint 基于 java 的 nio 包實(shí)現(xiàn)了 I/O 多路復(fù)用模型」,主要包含了 LimitLatch、Acceptor、Poller、SocketProcessor 和 Executor 共 5 個(gè)組件。它的工作過(guò)程如下:

  1. 「LimitLatch」:負(fù)責(zé)控制最大連接數(shù),NIO 模式下默認(rèn)是 10000,達(dá)到這個(gè)閾值后,連接請(qǐng)求被拒絕。它是基于 AQS 實(shí)現(xiàn),原理就跟 Lock 一樣。
  2. 「Acceptor」:獨(dú)立線程,不斷調(diào)用 ServerSocketChannel 的 accept() 方法來(lái)接收新連接,一旦有新的連接請(qǐng)求到來(lái),返回 SocketChannel 對(duì)象,然后將其封裝在一個(gè) PollerEvent 對(duì)象中,并將 PollerEvent 對(duì)象壓入 Poller 的 Queue 里(「典型的生產(chǎn)者 - 消費(fèi)者模式」)。
  3. 「Poller」:獨(dú)立運(yùn)行在一個(gè)線程里,底層就是一個(gè) Selector,每個(gè) Poller 線程可能同時(shí)被多個(gè) Acceptor 線程調(diào)用來(lái)注冊(cè) PollerEvent。Poller 不斷的通過(guò)內(nèi)部的 Selector 對(duì)象向內(nèi)核查詢 Channel 的狀態(tài),一旦可讀就生成任務(wù)類 SocketProcessor 交給 Executor 去處理。
  4. 「SocketProcessor」:實(shí)現(xiàn)了 Runable 接口,主要是調(diào)用 Http11Processor 來(lái)處理請(qǐng)求。Tomcat 會(huì)將 Socket 包裝成一個(gè) SocketWrapper,Http11Processor 會(huì)調(diào)用 SocketWrapper 來(lái)讀寫(xiě)數(shù)據(jù)。
  5. 「Executor」:自定義的線程池,負(fù)責(zé)運(yùn)行 SocketProcessor ,會(huì)調(diào)用 Http11Processor 來(lái)讀取和解析請(qǐng)求數(shù)據(jù)。Http11Processor 是應(yīng)用層協(xié)議的封裝,它會(huì)調(diào)用容器獲得響應(yīng),再把響應(yīng)通過(guò) Channel 寫(xiě)出。

Tomcat連接器-Nio2Endpoint

Tomcat 還支持了異步 I/O,基于 Java AIO 實(shí)現(xiàn) - Nio2Endpoint 的組件跟 NioEndpoint 類似,但是 Nio2Endpoint 中沒(méi)有 Poller 組件,也就是沒(méi)有 Selector。這是因?yàn)樵诋惒?I/O 模式下,Selector 的工作交給內(nèi)核來(lái)做了。

  • LimitLatch」:跟 NioEndPoint 一樣,連接控制器,它負(fù)責(zé)控制最大連接數(shù)。
  • 「Nio2Acceptor」:擴(kuò)展了 Acceptor,自己就是處理連接的回調(diào)類,用異步 I/O 的方式來(lái)接收新連接后,得到一個(gè) AsynchronousSocketChannel,它會(huì)將其封裝成一個(gè) Nio2SocketWrapper,并創(chuàng)建一個(gè)SocketProcessor 任務(wù)類交給線程池處理。
  • 「Nio2SocketWrapper」:實(shí)際讀取 Channel 內(nèi)的數(shù)據(jù),并提供接口給 Http11Processor 讀寫(xiě)。但是由于異步 I/O 的性質(zhì),Http11Processor 讀取 Nio2SocketWrapper 時(shí)很有可能內(nèi)核還沒(méi)有將數(shù)據(jù)準(zhǔn)備好,為了解決這個(gè)問(wèn)題,Http11Processor 采用了2次 read 調(diào)用:通過(guò)注冊(cè)回調(diào)類 readCompletionHandler。

最后

其實(shí) Tomcat 的實(shí)現(xiàn)細(xì)節(jié)很多,沒(méi)辦法一一重現(xiàn),大部分情況下需要自己去對(duì)著源碼跑一遍,像很多實(shí)際運(yùn)用:

  • ContainerBackgroundProcessor,實(shí)現(xiàn)熱更新機(jī)制:熱加載和熱部署。
  • 對(duì)象池技術(shù),典型的以空間換時(shí)間的思路,通過(guò) SynchronizedStack 減少 SocketWrapper 和SocketProcessor 的創(chuàng)建和銷毀。
  • Servlet 3.0 中引入的異步 Servlet,Tomcat 對(duì)其做了支持,它的思想是:讓業(yè)務(wù)線程和 Tomcat I/O 線程分離開(kāi),將復(fù)雜耗時(shí)的業(yè)務(wù)計(jì)算移到業(yè)務(wù)線程池中進(jìn)行,釋放 Tomcat的I/O 線程,以便可以及時(shí)響應(yīng)其它請(qǐng)求。
  • 會(huì)話管理...
  • 集群管理...
責(zé)任編輯:姜華 來(lái)源: Java架構(gòu)師進(jìn)階編程
相關(guān)推薦

2009-11-13 13:08:19

2010-09-07 14:21:22

PPPoE協(xié)議

2011-03-23 11:01:55

LAMP 架構(gòu)

2010-03-08 14:53:48

Linux分區(qū)

2011-09-01 13:51:52

JavaScript

2023-02-01 08:13:30

Redis內(nèi)存碎片

2017-02-27 10:43:07

Javasynchronize

2022-03-17 10:24:28

JavaJVM

2022-08-30 07:00:18

執(zhí)行引擎Hotspot虛擬機(jī)

2021-10-29 16:36:53

AMSAndroidActivityMan

2009-12-14 14:50:46

Ruby傳參數(shù)

2009-12-16 16:39:01

Visual Stud

2009-06-10 18:12:38

Equinox動(dòng)態(tài)化OSGi動(dòng)態(tài)化

2009-12-22 15:39:36

IPPBX技術(shù)

2018-12-18 10:11:37

軟件復(fù)雜度軟件系統(tǒng)軟件開(kāi)發(fā)

2015-08-03 09:54:26

Java線程Java

2020-12-07 06:23:48

Java內(nèi)存

2013-11-14 17:02:41

Android多窗口

2018-10-25 15:24:10

ThreadLocal內(nèi)存泄漏Java

2023-08-07 07:44:44

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)