Tomcat架構解析 讀書筆記 (1)

在這裏插入圖片描述

  • tomcat 的基本架構,下面是上圖中一些實體的概念
組件名稱 說明
Server 表示整個Servlet容器,在單個Tomcat進程中只有唯一一個Server實例
Service Service 表示一個或者多個Connector集合,這些Connector共享一個Container處理請求,同一個Tomcat實例內包含任意多個Service實例,他們彼此獨立
Connector 連接器,用於監聽並轉化Socket請求,同時將讀取的Socket請求交給Container處理,支持不同協議以及不同的I/O方式
Container Container 表示執行用戶請求並返回響應的對象,Tomcat中包括不同級別的容器:包括 Engine Host Context Wrapper
Engine 表示整個Servlet引擎,作爲最高級的容器對象,儘管Engine不是直接處理請求容器。是獲取目標容器的入口
Host 表示Servlet引擎中的虛擬機,與域名有關的
Context Context作爲一類容器,用於表示ServletContext,即表示一個獨立的Web應用
Wrapper Wrapper作爲一類容器,用於表示Web應用中定義的具體的Servlet
Executor Tomcat組件間可以共享的線程池,由Service維護,同一個Service共享同一個線程池
Mapper 維護容器映射信息,同時按照映射規則查找容器(比如Servlet規範查找)
MapperListener 用於在容器組件狀態發生變化時,註冊或者取消對應容器映射信息
ProtocolHandler 一個協議處理器,針對不同協議和I/O 提供不同實現,通常關聯一個Endpoint:用於啓動Socket的監聽,還關聯一個Processor用於按照指定協議讀取數據
LifeCycle 生命週期的抽象接口,每個組件都有類似的生命週期
BootStrap 和 Catalina BootStrap作爲應用服務器的啓動入口。Catalina作爲Shell程序,用於啓動/停止服務器(PS:我也沒弄懂書上的意思)

JVM 的endorsed standands Override Mechanism機制

  • 通過該機制,應用程序可以提供新版本的API 替換JVM默認實現
  • J2SE包含大量的拓展,這些拓展由JVM加載供所有程序使用 JAXP(解析xml的API).作爲核心類庫 (作爲rt.jar)由BootStrap類加載器加載。因此即使應用程序提供新版本JAXP,也會使用jvm的老版本,該機制就是爲了解決該問題
  • JVM 的默認的 Endoresd目錄爲 %JAVA_HOME%/lib/endorsed,複製到該目錄下的Jar包,將優先於JVM中的類加載
  • 有的應用服務器也實現了該機制,如Tomcat 和 jBoss,都有相應配置
  • 不是所有的Java核心類都可以被覆蓋,只有部分類可以被覆蓋

Tomcat加載器

  • 隔離性:Web應用類庫相互隔離,避免依賴庫或者應用包相互影響,web採用不同的類加載器實現隔離
  • 靈活性:既然Web應用之間的類加載器相互獨立,當我們只針對特定一個Web應用進行重新部署,web加載器會重新創建,如果只採用一個類加載器,是無法高效梳理類之間的關係,無法完整的移除特定Web應用的類文件
  • 性能:由於每個web應用有特定的類加載器,那麼加載類的時候,只會搜索特定web應用包含的jar文件

Tomcat類加載器的層級

在這裏插入圖片描述

Tomcat提供了三個基礎類加載器和應用類加載器,具體配置在catalina.properties中,默認情況下 Common/Catalina/Shared爲同一個類加載器

  • Common:以System爲父類加載器,是位於Tomcat應用服務器頂層的公用類加載器。其路徑爲common.loader 默認爲$CATALINA_HOME/lib
  • Catalina:以Common爲父加載器,用於加載Tomcat應用服務器的類加載器,默認爲空,此時Tomcat使用Common加載器加載應用服務器
  • Shared: 以Common爲父加載器,是所有Web應用的父加載器,默認爲空,此時Tomcat使用Common加載器作爲Web應用的父加載器
  • Web應用:以Shared爲父加載器,加載/WEB-INF/classes目錄下的未壓縮的Class和資源文件以及/WEB-INF/lib下的Jar包。該類加載器只對當前Web應用可見,對其他Web應用均不可見

應用類加載順序

Tomcat提供delegate屬性用於控制是否啓用Java委派屬性,默認爲false(不啓用),加載順序如下:

1) 從緩存中加載
2) 如果沒有,則從JVM的BootStrap類加載器加載
3) 如果沒有, 則從當前類加載器(即web應用加載器)加載(按照/WEB-INF/classes、/WEB-INF/lib順序)
4) 如果沒有, 則從父類加載器加載,由於父類加載器採用默認的委派模式,所以加載順序爲 system -> common ->shared

delegate爲true,採用默認的Java加載委派機制,加載順序如下:

1) 從緩存中加載
2) 如果沒有,則從JVM的BootStrap類加載器加載
3) 如果沒有, 則從父類加載器加載,由於父類加載器採用默認的委派模式,所以加載順序爲 system -> common ->shared
4) 如果沒有, 則從當前類加載器(即web應用加載器)加載(按照/WEB-INF/classes、/WEB-INF/lib順序)
  • 總結
    • Tomcat通過上述加載順序機制,實現web應用中的Jar包覆蓋服務器提供的Jar包。但是java核心類庫(比如JAXP)由於加載順序優先所以是無法被覆蓋的
    • Servlet規範相關API禁止通過Web應用加載器加載,所以,Web應用中不能包含這些包,那麼這些jar包,就只能通過Common(默認情況也是shared,catalina加載器加載),所以如果某個tomcat版本提供的Servlet實現版本不符合要求,我們無法再web應用中通過提供相應實現來覆蓋
    • 針對上述兩種情況,可以採用endorsed方式實現覆蓋
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章