tomcat學習記錄,深入理解http請求整個流程,伺服器低層處理過程 ...
一: 生命周期
Tomcat 為了方便管理組件和容器的生命周期,定義了從創建、啟動、到停止、銷毀共 12 中狀態,tomcat 生命周期管理了內部狀態變化的規則控制,組件和容器只需實現相應的生命周期 方法即可完成各生命周期內的操作(initInternal、startInternal、stopInternal、 destroyInternal)。
Tomcat 的生命周期管理引入了事件機制,在組件或容器的生命周期狀態發生變化時會通 知事件監聽器,監聽器通過判斷事件的類型來進行相應的操作。事件監聽器的添加可以在 server.xml 文件中進行配置。
Tomcat 各類容器的配置過程就是通過添加 listener 的方式來進行的,從而達到配置邏輯與 容器的解耦。
-
-
HostConfig:主要處理部署應用,解析應用 META-INF/context.xml 並創建應用的 Context
-
請求的處理流程
容器的責任鏈模式:
-
-
Connector將Request和Response交給Container,先通過Engine的pipeline組件流經內部的每個Valve。
-
請求流轉到Host的pipeline組件中, 並且經過內部Valve的過濾。
-
請求流轉到Context的pipeline組件中, 並且經過內部的Valve的過濾。
-
請求流轉到Wrapper的pipeline組件中, 並且經過內部的Valve的過濾。
-
Wrapper內部的WrapperValve創建FilterChain實例, 調用指定的Servlet實例處理請求。
-
2: 類載入機制
雙親委派模型:
-
-
Extension ClassLoader :擴展類載入器,擴展類載入器的載入路徑是 JDK 目錄下 jre/lib/ext 。擴展載入器的 #getParent() 方法返回 null ,實際上擴展類載入器的父類載入器是啟動類載入器。
-
System ClassLoader
ClassLoader#loadClass(java.lang.String, boolean)
類的載入過程:
類載入器:
-
同一個 Web 伺服器里,各個 Web 項目之間各自使用的 Java 類庫要互相隔離。
-
同一個 Web 伺服器里,各個 Web 項目之間可以提供共用的 Java 類庫 。
-
為了使伺服器不受 Web 項目的影響,應該使伺服器的類庫與應用程式的類庫互相獨立。
-
對於支持 JSP 的 Web 伺服器,應該支持熱插拔(HotSwap)功能 。
-
放置在/common目錄中:類庫可被Tomcat和所有的 Web應用程式共同使用。
-
放置在/server目錄中:類庫可被Tomcat使用,對所有的Web應用程式都不可見。
-
放置在/shared目錄中:類庫可被所有的Web應用程式共同使用,但對 Tomcat自己不可見。
-
放置在/WebApp/WEB-INF目錄中:類庫僅僅可以被此Web應用程式使用,對 Tomcat和其他Web應用程式都不可見。
LauncherHelper
3: 線程模型
描述 | |
---|---|
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) |
通過修改server.xml中protocol配置來指定IO模型
<Connector protocol="HTTP/1.1">
Tomcat8連接器比較
4: 性能調優
一般生產環境中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 |
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屬性:
名稱 | 描述 |
---|---|
daemon | 是否是守護線程,預設true |
namePrefix | 由執行程式創建的每個線程的名稱首碼。單個線程的線程名將是namePrefix+threadNumber |
maxThreads | 池中活動線程的最大數量,預設為200 |
minSpareThreads | 保持活動的線程的最小數量(空閑和活動),預設為25 |
maxIdleTime | 一個空閑線程關閉前的毫秒數,除非活動線程數小於或等於minSpareThreads。預設值為60000(1分鐘) |
maxQueueSize | 在拒絕可運行任務之前,可以排隊等待執行的最大可運行任務數。預設值是Integer.MAX_VALUE |
prestartminSpareThreads |
學習記錄