tomcat伺服器源碼解讀02-基本原理

来源:https://www.cnblogs.com/wangrq/archive/2020/07/04/13233480.html
-Advertisement-
Play Games

tomcat學習記錄,深入理解http請求整個流程,伺服器低層處理過程 ...


一: 生命周期

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)

請求的處理流程

容器的責任鏈模式:

  1. 請求被Connector組件接收, 創建Request和Response對象。

  2. Connector將Request和Response交給Container,先通過Engine的pipeline組件流經內部的每個Valve。

  3. 請求流轉到Host的pipeline組件中, 並且經過內部Valve的過濾。

  4. 請求流轉到Context的pipeline組件中, 並且經過內部的Valve的過濾。

  5. 請求流轉到Wrapper的pipeline組件中, 並且經過內部的Valve的過濾。

  6. Wrapper內部的WrapperValve創建FilterChain實例, 調用指定的Servlet實例處理請求。

  7. 返回結果

 

 

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

學習記錄


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 下麵是總結的css技巧,建議大家收藏,以後用的時候就不用到處查資料了。當然這些也不是所有的,大家如果有什麼好的css有趣樣式技巧也可以發出來哦 三角形 最常見的一種形狀了。切圖,不存在的。 /** 正三角 */ .triangle { width: 0; height: 0; border-styl ...
  • Levy曲線是將一條線段不停地分形成兩條長度相等且相互垂直的線段而生成的。Levy分形的最後很像一個英文字母C,所以也稱它為C曲線。 Levy曲線的生成示意如圖1所示。 圖1 Levy曲線的生成 1.Levy曲線 Levy曲線採用遞歸過程易於實現,編寫如下的HTML代碼。 <!DOCTYPE htm ...
  • 說一下我個人理解跟建議,僅供參考 第一步,先看一本前端入門的書+《Javascript權威指南》:前端入門的書隨便哪本都行,主要是瞭解一下前端HTML + CSS + Javascript大致是怎麼回事,有個概念,腦海中留個大致輪廓就好,非要推薦的話,可以看看《HTML5權威指南》,Apress的書 ...
  • 1.內嵌標簽: iframe: src:要顯示的網路資源路徑 可以是本地資源(相對路徑)也可以是網路資源(url) 註:預設當前頁面打開及載入src指向的資源 width:設置顯示區域寬度 height:設置顯示區域高度 name:設置內嵌區域的名字,結合超鏈接標簽的target屬性使用 註:在當前 ...
  • 開發環境配置 一般情況下開發環境是會跨域的,所以我們只需要在跨域的位置配置即可。進入config/index.js,在proxyTable對象裡面添加代碼,如下 '/api': { target: 'http://localhost:8082', //開發環境,設置調用介面功能變數名稱和埠號別忘了加htt ...
  • 這個遞歸不太難 相信大家都知道什麼是遞歸,但在實際開發的時候用過多少次遞歸呢? 程式的世界有句話叫“人用迴圈,神用遞歸”,很多情況下我們都會優先使用迴圈而不是遞歸。我和幾個朋友聊過,他們的看法是:“相比迴圈而言,遞歸性能更差,而且更不可控,容易出問題。” 捕獲關鍵詞“問題”,啟動“解決”模式... ...
  • 工作中涉及需求 參考案例1: https://blog.csdn.net/IMFaust/article/details/92630595 效果: 參考案例2: https://www.cnblogs.com/cindy-hmy/p/8251193.html 效果: 官方案例: https://ec ...
  • Apache DolphinScheduler 是一個分散式去中心化,易擴展的可視化 DAG 工作流任務調度系統。致力於解決數據處理流程中錯綜複雜的依賴關係,使調度系統在數據處理流程中開箱即用。 近日,伯毅同學給社區貢獻了工作流核心表結構的剖析文章,非常細緻,喜歡的伙伴請轉走 1. 工作流總體存儲結 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...