一: 生命周期
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類加載器。
LauncherHelper3: 線程模型
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_OPTSjvm 啟動參數 , 設置內存 編碼等 -Xms100m -Xmx200m -Dfile.encoding=UTF-8JAVA_HOME指定jdk 目錄,如果未設置從java 環境變量當中去找。CATALINA_HOMETomcat 程序根目錄CATALINA_BASE應用部署目錄,默認為$CATALINA_HOMECATALINA_OUT應用日誌輸出目錄:默認$
CATALINA_BASE/logCATALINA_TMPDIR應用臨時目錄:默認:$CATALINA_BASE/temp
並發相關參數
Connector屬性:
名稱描述address對於具有多個IP地址的服務器,此屬性指定將用於監聽指定端口的地址。默認情況下,連接器將偵聽所有本地地址compression是否使用HTTP/1.1 GZIP壓縮來節省服務器帶寬,默認offconnectionTimeout客戶端發起連接到服務端接收為止,中間最大的等待時間connectionUploadTimeout指定數據上傳過程中使用的超時時間(以毫秒為單位)。只有將disableUploadTimeout設置為false時才會生效。disableUploadTimeouttrue 則使用
connectionTimeoutenableLookups如果需要調用request.getRemoteHost()來執行DNS查找以返回遠程客戶端的實際主機名,則將其設置為true。設置為false可以跳過DNS查找並以字符串形式返回IP地址(從而提高性能)。默認情況下,DNS查找是禁用的executorTerminationTimeoutMillis私有內部執行程序在繼續停止連接器之前等待請求處理線程終止的時間。如果沒有設置,默認值為5000(5秒)。acceptCount使用所有可能的請求處理線程時傳入連接請求的最大隊列長度。隊列滿時接收到的任何請求都將被拒絕。默認值是100。maxConnections服務器在任何給定時間將接受和處理的最大連接數。當到達此數值時,服務器將接受(但不處理)另一個連接。此附加連接將被阻塞,直到正在處理的連接數量低於maxConnections,此時服務器將再次開始接受和處理新連接。注意,一旦達到了限制,操作系統仍然可以基於acceptCount設置接受連接。默認值因連接器類型而異。對於NIO和NIO2,缺省值是10000。maxHttpHeaderSize請求和響應HTTP頭的最大大小,默認8kmaxThreads可以處理的並發請求的最大數量,默認200 ,如果使用了executor,將被忽略minSpareThreads始終保持運行的最小線程數,默認10,如果使用了executor,將被忽略
Executor屬性:
名稱描述daemon是否是守護線程,默認truenamePrefix由執行程序創建的每個線程的名稱前綴。單個線程的線程名將是namePrefix+threadNumbermaxThreads池中活動線程的最大數量,默認為200minSpareThreads保持活動的線程的最小數量(空閑和活動),默認為25maxIdleTime一個空閑線程關閉前的毫秒數,除非活動線程數小於或等於minSpareThreads。默認值為60000(1分鐘)maxQueueSize在拒絕可運行任務之前,可以排隊等待執行的最大可運行任務數。默認值是
Integer.MAX_VALUEprestartminSpareThreadsminSpareThreads是否應該在啟動執行程序時啟動,默認值都是false
原創文章,作者:投稿專員,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/287851.html
微信掃一掃
支付寶掃一掃