一: 生命周期
Tomcat 為了方便管理組件和容器的生命周期,定義了從創建、啟動、到停止、銷毀共 12 中狀態,tomcat 生命周期管理了內部狀態變化的規則控制,組件和容器只需實作相應的生命周期 方法即可完成各生命周期內的操作(initInternal、startInternal、stopInternal、 destroyInternal),

Tomcat 的生命周期管理引入了事件機制,在組件或容器的生命周期狀態發生變化時會通 知事件監聽器,監聽器通過判斷事件的型別來進行相應的操作,事件監聽器的添加可以在 server.xml 檔案中進行配置,
Tomcat 各類容器的配置程序就是通過添加 listener 的方式來進行的,從而達到配置邏輯與 容器的解耦,
-
EngineConfig:主要列印start和stop事件的debug日志
-
HostConfig:主要處理部署應用,決議應用 META-INF/context.xml 并創建應用的 Context
-
ContextConfig:主要決議并合并 web.xml,掃描應用的各類 web 資源 (filter、servlet、listener)
請求的處理流程
容器的責任鏈模式:
-
請求被Connector組件接收, 創建Request和Response物件,
-
Connector將Request和Response交給Container,先通過Engine的pipeline組件流經內部的每個Valve,
-
請求流轉到Host的pipeline組件中, 并且經過內部Valve的過濾,
-
請求流轉到Context的pipeline組件中, 并且經過內部的Valve的過濾,
-
請求流轉到Wrapper的pipeline組件中, 并且經過內部的Valve的過濾,
-
Wrapper內部的WrapperValve創建FilterChain實體, 呼叫指定的Servlet實體處理請求,
-
回傳結果

2: 類加載機制
雙親委派模型:
-
Bootstrap ClassLoader :啟動類加載器,負責加載 Java 的核心類,它不是 java.lang.ClassLoader 的子類,而是由 JVM自身實作,null c,c++實作的,加載jre/lib
-
Extension ClassLoader :擴展類加載器,擴展類加載器的加載路徑是 JDK 目錄下 jre/lib/ext ,擴展加載器的 #getParent() 方法回傳 null ,實際上擴展類加載器的父類加載器是啟動類加載器,
-
System ClassLoader :系統(應用)類加載器,它負責在 JVM 啟動時加載來自 Java 命令的 -classpath 選項、java.class.path 系統屬性或 CLASSPATH 環境變數所指定的 jar 包和類路徑,程式可以通過 #getSystemClassLoader() 來獲取系統類加載器,系統加載器的加載路徑是程式運行的當前路徑,
ClassLoader#loadClass(java.lang.String, boolean)
jvm如何確定一個class唯一性: 全類名(包名+類名)+ classLoader的id

類的加載程序:

類加載器:
Tomcat 擁有不同的自定義類加載器,以實作對各種資源庫的控制, Tomcat 主要用類加載器解決以下 4 個問題:
-
同一個 Web 服務器里,各個 Web 專案之間各自使用的 Java 類別庫要互相隔離,
-
同一個 Web 服務器里,各個 Web 專案之間可以提供共享的 Java 類別庫 ,
-
為了使服務器不受 Web 專案的影響,應該使服務器的類別庫與應用程式的類別庫互相獨立,
-
對于支持 JSP 的 Web 服務器,應該支持熱插拔(HotSwap)功能 ,
Tomcat提供了四組目錄供用戶存放第三方類別庫:
-
放置在/common目錄中:類別庫可被Tomcat和所有的 Web應用程式共同使用,
-
放置在/server目錄中:類別庫可被Tomcat使用,對所有的Web應用程式都不可見,
-
放置在/shared目錄中:類別庫可被所有的Web應用程式共同使用,但對 Tomcat自己不可見,
-
放置在/WebApp/WEB-INF目錄中:類別庫僅僅可以被此Web應用程式使用,對 Tomcat和其他Web應用程式都不可見,
Tomcat自定義了多個類加載器,CommonClassLoader、CatalinaClassLoader、SharedClassLoader和WebappClassLoader則是Tomcat自己定義的類加載器,它們分別加載/common/、/server/、/shared/和/WebApp/WEB-INF/中的Java類別庫,其中WebApp類加載器和Jsp類加載器通常會存在多個實體,每一個Web應用程式對應一個WebApp類加載器,每一個JSP檔案對應一個Jsp類加載器,
LauncherHelper
3: 執行緒模型
Tomcat對IO模型支持
| IO模型 | 描述 |
|---|---|
| BIO (JIoEndpoint) | 同步阻塞式IO,即Tomcat使用傳統的java.io進行操作,該模式下每個請求都會創建一個執行緒,對性能開銷大,不適合高并發場景,優點是穩定,適合連接數目小且固定架構, |
| NIO(NioEndpoint) | 同步非阻塞式IO,jdk1.4 之后實作的新IO,該模式基于多路復用選擇器監測連接狀態再同步通知執行緒處理,從而達到非阻塞的目的,比傳統BIO能更好的支持并發性能,Tomcat 8.0之后默認采用該模式 |
| AIO (Nio2Endpoint) | 異步非阻塞式IO,jdk1.7后之支持 ,與nio不同在于不需要多路復用選擇器,而是請求處理執行緒執行完成進行回呼調知,繼續執行后續操作,Tomcat 8之后支持, |
| APR(AprEndpoint) | 全稱是 Apache Portable Runtime/Apache可移植運行庫),是Apache HTTP服務器的支持庫,可以簡單地理解為,Tomcat將以JNI的形式呼叫Apache HTTP服務器的核心元件來處理檔案讀取或網路傳輸操作,使用需要編譯安裝APR 庫 |
通過修改server.xml中protocol配置來指定IO模型
<Connector protocol="HTTP/1.1">
Tomcat7連接器比較

Tomcat8連接器比較

JIOEndpoint原理

NioEndpoint原理

4: 性能調優
Tomcat啟動引數
一般生產環境中Tomcat 程式目錄和部署目錄分開的,只需要在啟動時指定CATALINA_HOME 與 CATALINA_BASE 引數即可,
| 啟動引數 | 描述說明 |
|---|---|
| JAVA_OPTS | jvm 啟動引數 , 設定記憶體 編碼等 -Xms100m -Xmx200m -Dfile.encoding=UTF-8 |
| JAVA_HOME | 指定jdk 目錄,如果未設定從java 環境變數當中去找, |
| CATALINA_HOME | Tomcat 程式根目錄 |
| CATALINA_BASE | 應用部署目錄,默認為$CATALINA_HOME |
| CATALINA_OUT | 應用日志輸出目錄:默認$CATALINA_BASE/log |
| CATALINA_TMPDIR | 應用臨時目錄:默認:$CATALINA_BASE/temp |
并發相關引數
Connector屬性:
| 名稱 | 描述 |
|---|---|
| address | 對于具有多個IP地址的服務器,此屬性指定將用于監聽指定埠的地址,默認情況下,連接器將偵聽所有本地地址 |
| compression | 是否使用HTTP/1.1 GZIP壓縮來節省服務器帶寬,默認off |
| connectionTimeout | 客戶端發起連接到服務端接收為止,中間最大的等待時間 |
| connectionUploadTimeout | 指定資料上傳程序中使用的超時時間(以毫秒為單位),只有將disableUploadTimeout設定為false時才會生效, |
| disableUploadTimeout | true 則使用connectionTimeout |
| enableLookups | 如果需要呼叫request.getRemoteHost()來執行DNS查找以回傳遠程客戶端的實際主機名,則將其設定為true,設定為false可以跳過DNS查找并以字串形式回傳IP地址(從而提高性能),默認情況下,DNS查找是禁用的 |
| executorTerminationTimeoutMillis | 私有內部執行程式在繼續停止連接器之前等待請求處理執行緒終止的時間,如果沒有設定,默認值為5000(5秒), |
| acceptCount | 使用所有可能的請求處理執行緒時傳入連接請求的最大佇列長度,佇列滿時接收到的任何請求都將被拒絕,默認值是100, |
| maxConnections | 服務器在任何給定時間將接受和處理的最大連接數,當到達此數值時,服務器將接受(但不處理)另一個連接,此附加連接將被阻塞,直到正在處理的連接數量低于maxConnections,此時服務器將再次開始接受和處理新連接,注意,一旦達到了限制,作業系統仍然可以基于acceptCount設定接受連接,默認值因連接器型別而異,對于NIO和NIO2,預設值是10000, |
| maxHttpHeaderSize | 請求和回應HTTP頭的最大大小,默認8k |
| maxThreads | 可以處理的并發請求的最大數量,默認200 ,如果使用了executor,將被忽略 |
| minSpareThreads | 始終保持運行的最小執行緒數,默認10,如果使用了executor,將被忽略 |
Executor屬性:
| 名稱 | 描述 |
|---|---|
| daemon | 是否是守護執行緒,默認true |
| namePrefix | 由執行程式創建的每個執行緒的名稱前綴,單個執行緒的執行緒名將是namePrefix+threadNumber |
| maxThreads | 池中活動執行緒的最大數量,默認為200 |
| minSpareThreads | 保持活動的執行緒的最小數量(空閑和活動),默認為25 |
| maxIdleTime | 一個空閑執行緒關閉前的毫秒數,除非活動執行緒數小于或等于minSpareThreads,默認值為60000(1分鐘) |
| maxQueueSize | 在拒絕可運行任務之前,可以排隊等待執行的最大可運行任務數,默認值是Integer.MAX_VALUE |
| prestartminSpareThreads | minSpareThreads是否應該在啟動執行程式時啟動,默認值都是false |
引數配置官方地址 https://tomcat.apache.org/tomcat-8.5-doc/config/http.html
學習記錄
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/151700.html
標籤:Java
