本文主要介紹tomcat源代碼解讀(tomcat編譯的項目在哪里),下面一起看看tomcat源代碼解讀(tomcat編譯的項目在哪里)相關(guān)資訊。
概述tomcat、jetty、undertow都是非常著名的實現(xiàn)servlet規(guī)范的應(yīng)用服務(wù)器。tomcat本身也是業(yè)界優(yōu)秀的中間件。簡單來說,tomcat可以看作是一個http服務(wù)器servlet容器,它管理和運行servlet。相信大家對這個三條腿的貓logo都很熟悉,在學(xué)校和工作中也經(jīng)常用到。特別是java程序員,一開始都有在idea或者eclipse的集成環(huán)境中配置tomcat啟動web項目的經(jīng)驗,當(dāng)然也可以在springboot中基于tomcat maven插件或者嵌入式web容器調(diào)試運行。
源代碼編譯官方下載tomcat源代碼,最新穩(wěn)定版本是10.0.12。
#因為tomcat源代碼依賴于jakartaee-migration模塊,而jakartaee-migration還沒有發(fā)布到maven repository,所以我們需要git克隆到本地,然后mvn安裝部署,解決tomcat源代碼的編譯問題。-jakartaee-migration#解壓文件并進入tomcat-jakarta ee-migration-main目錄。在地址欄輸入cmd進入命令行窗口自動進入當(dāng)前目錄#執(zhí)行maven安裝到本地倉庫mvn干凈安裝#解壓文件apache-tomcat-10 . 0 . 12-src . zip . tomcat源代碼不是maven項目結(jié)構(gòu),但是可以通過pom指定java代碼目錄(不遵循src/main結(jié)構(gòu)),在項目目錄下創(chuàng)建一個pom.xml文件,內(nèi)容如下:?xml版本= 1.0 編碼= utf-8 ?xmlns項目= http://maven.apache.org/pom/4.0.0xmlns : xsi = http://www.w3.org/2001/ xml schema-實例和xsie cho 15-@ . com schema location = http://maven.apache.org/pom/4.0.0 -4.0.0.xsd;模型版本4 . 0 . 0/模型版本groupidcom.github.sources/groupid artifact id source-tomcat/artifact id版本10.0-snapshot/版本名稱source-tomcat/名稱依賴項依賴項group id junit/groupid artifact id junit/artifact id版本4.12/版本scope test/scope/依賴項依賴項groupidorg.easymock/groupid artifact ideas mock/artifact id版本3 . 5 . 1/版本/依賴項依賴項groupidorg.apache.ant/groupid artifact id/artifact id版本1 . 10 . 1/版本/依賴項依賴項group id wsdl 4j/groupion/artifactid版本0 . 2 . 1-快照/版本/依賴項依賴項groupidbiz.aqute.bnd/groupid artifactidbiz.aqute.bndlib/artifactid版本5.2.0/版本范圍provided/scope/依賴項/依賴項生成final name tomcat 10.0/final name source directory java/source directory test source directory resources資源目錄java/directory/resources test resources test resource directory test/directory/test resource/test resources插件groupidorg.apache.maven.plugins/groupid artifact id maven-compiler-plugin/artifact id版本3.6.1/版本配置編碼utf-8;t報告沒有編譯器選項。version _ 16//設(shè)置。put(編譯器選項。選項_源,編譯器選項。version _ 16);// settings.put(compileroptions。選擇權(quán)_targetplatform,編譯器選項。version _ 16);// settings.put(compileroptions。option_compliance,編譯器選項。version _ 16);上一章我們已經(jīng)提到了tomcat主函數(shù)的入口在org . apache . catalina . startup . bootstrap中,我們知道主函數(shù)會遇到如下測試類的錯誤。你可以試著運行并忽略測試類,或者直接刪除maven編譯時生成的測試文件夾。我們將在這里直接刪除測試文件夾。
目前,tomcat初創(chuàng)公司can 找不到配置文件,所以我們在源代碼的根目錄下創(chuàng)建源文件夾,并將conf和webapps這兩個目錄轉(zhuǎn)移到源文件夾。
然后在運行設(shè)置中添加以下vm參數(shù)。
-dca talina . home = f: \ develop \ apache-tomcat-10 . 0 . 12-src \ source-dca talina . base = f: \ develop \ apache-tomcat-10 . 0 . 12-src \ source-dj ava . util . logging . manager = org . apache . juli . classloaderlogmanager-dj ava . util . logging . config . file = f: \ develop \ develop此時,我們可以啟動tomcat程序了。但是當(dāng)你訪問: 8080/,會得到一個500錯誤。當(dāng)您啟動tomcat bootstrap時,jsp編譯器jasperinitializer不會被加載。
org . apache . catalina . startup . context config中的# configurestart//添加以下初始化語句上下文。在這句話下面添加addservletcontainerizinitia。lizer(new jasperinitializer,null);重啟tomcat,勾選: 8080,會出現(xiàn)tomcat的歡迎頁面。
架構(gòu)源代碼分析整體架構(gòu)tomcat源代碼使用了大量的模板方法和適配器設(shè)計模式,封裝了很多組件,組件之間有明顯的層次關(guān)系,是經(jīng)典的玩偶式架構(gòu)設(shè)計;個人建議從配置文件了解tomca的架構(gòu),這也是基于玩偶式架構(gòu)設(shè)計的優(yōu)勢。tomcat模塊的層次結(jié)構(gòu)和相關(guān)模塊的功能描述如下:
器組件是tomcat的核心組件,可以完成tomcat生命周期中一些容器相關(guān)的器。jndijndi是一個java命名和目錄接口,屬于j2ee規(guī)范。tomcat實現(xiàn)了它。jndi在《j2ee》中的角色是a 開關(guān) ,即j2ee組件在運行時查找其他組件、資源或服務(wù)的一種通用機制(你可以簡單理解為給一個資源起一個名字,然后根據(jù)名字查找一個資源)。集群組件提供了集群功能,可以將相應(yīng)容器需要共享的數(shù)據(jù)同步到集群中的其他tomcat實例。realm組件提供了一個容器級的用戶密碼權(quán)限數(shù)據(jù)對象,它與資源認證模塊一起使用。加載器組件web應(yīng)用程序加載器用于加載web應(yīng)用程序的資源,它應(yīng)該保證不同web應(yīng)用程序之間的資源隔離。管理器組件servlet mapper屬于上下文中的路由映射器,它只負責(zé)上下文容器的路由導(dǎo)航。catalina是tomcat中的一個重要組件。它負責(zé)解析tomcat的配置文件(server.xml),從而創(chuàng)建服務(wù)器組件并對其進行管理。以下是tomcat amp中知名的server.xml核心配置的內(nèi)容結(jié)構(gòu) conf目錄,服務(wù)器-服務(wù)-(連接器引擎)。全局資源tomcat-user.xml可以在globalnamingresouce域中定義,在web.xml文件中也很常見,比如session-config配置的默認超時是30分鐘。
?xml版本= 1.0 編碼= utf-8 ?服務(wù)器端口= 8005 關(guān)機= 關(guān)機 器classname = org . apache . catalina . startup . version logger listener /globalnamingresources resource name = 用戶數(shù)據(jù)庫和auth = 集裝箱與運輸type = org . apache . catalina . user database 描述= 可以更新和保存的用戶數(shù)據(jù)庫工廠= users . memoryuserdatabase factory 路徑名= conf/tomcat-users.xml/ / globalnamingresources服務(wù)名稱= 卡特琳娜 遺囑執(zhí)行人姓名= tomcatthreadpool 名稱前綴= 卡特琳娜-執(zhí)行- maxthreads = 150英鎊minsparethreads = 4 /連接器執(zhí)行器= tomcatthreadpool port = 8080 協(xié)議= http/1.1 connectiontimeout = 兩萬英鎊重定向端口= 8443 / /連接器引擎名稱= 卡特琳娜 defaulthost = 本地主機 realm classname = org . apache . catalina . realm . lock out realm realm classname = org.apache.catalina. realm。用戶數(shù)據(jù)庫領(lǐng)域 資源名= 用戶數(shù)據(jù)庫和/ /領(lǐng)域主機名= 本地主機 appbase = webapps unpackwars = 真實 自動部署= 真實 閥門classname = apache . catalina . valves . accesslog valve 目錄= 日志 前綴= 本地主機訪問日志后綴= 。txt 爸爸ttern = % h % l % u % t % r% s % b //host/engine/service/server:表示一個tomcat實例,包含servlet容器和其他組件,負責(zé)組裝和啟動servlet引擎和tomcat連接器。每個tomcat只有一個服務(wù)器,它代表整個服務(wù)環(huán)境。一個服務(wù)器中可以有多個服務(wù)。服務(wù)器管理多種服務(wù)。tomcat源代碼中的服務(wù)繼承自生命周期,tomcat服務(wù)組件的頂層接口有standardserver的唯一實現(xiàn)。服務(wù):服務(wù)是服務(wù)器中的一個組件。一個服務(wù)器可以有多個服務(wù),這些服務(wù)將幾個連接器組件綁定到一個容器,每個服務(wù)可以有多個連接器和一個容器(引擎)。連接器主要用于接收請求,解析請求內(nèi)容,封裝請求和響應(yīng),然后將準(zhǔn)備好的數(shù)據(jù)交給容器進行處理。集裝箱就是我們常說的集裝箱。其中可以有多個主機。一個主機代表一個虛擬主機,即一個對應(yīng)一個webapps。最后,在容器處理完請求后,它會將響應(yīng)內(nèi)容返回給連接器,然后連接器會將其返回給客戶端。executor executor:tomcat線程池的配置,提供給連接器。連接器:負責(zé)處理用戶的servlet請求并將對象返回給web用戶的模塊。我們知道tomcat處理http請求,也就是說tomcat使用http協(xié)議進行數(shù)據(jù)傳輸,而http協(xié)議是應(yīng)用層協(xié)議,其本質(zhì)是瀏覽器和服務(wù)器之間約定的一種通信格式。因此,作為http服務(wù)器,tomcat需要包含幾個功能,比如接受連接、解析請求數(shù)據(jù)、處理請求和發(fā)送響應(yīng)。這里我們分析tomcat的兩個核心功能:
處理套接字連接,負責(zé)網(wǎng)絡(luò)字節(jié)流與請求和響應(yīng)對象之間的轉(zhuǎn)換。加載和管理servlet,它負責(zé)處理請求請求。tomcat的底層使用socket進行連接,所以還涉及到網(wǎng)絡(luò)io模型,通過socket本地端口,接收并處理端口的網(wǎng)絡(luò)請求reque。st和response是按照http協(xié)議封裝的,所以連接器需要同時實現(xiàn)tcp/ip協(xié)議和http協(xié)議?;趖omcat的核心功能,分別設(shè)計實現(xiàn)了兩個核心組件:連接器和容器。連接器很復(fù)雜,要接收和分析請求,封裝請求和響應(yīng),最后把數(shù)據(jù)交給容器,容器負責(zé)內(nèi)部處理。
網(wǎng)絡(luò)傳播。應(yīng)用層協(xié)議分析。tomcat請求/響應(yīng)和servletrequest/servletresponse之間的轉(zhuǎn)換。連接器連接器主要需要完成以下三個核心功能:
套接字通信,也就是網(wǎng)絡(luò)通信。應(yīng)用層協(xié)議解析,解析處理應(yīng)用層協(xié)議,封裝成請求對象。將請求轉(zhuǎn)換為servletrequest,將響應(yīng)轉(zhuǎn)換為servletresponse。tomcat通過三個組件實現(xiàn)連接器:端點、處理器和適配器,它們通過抽象接口相互交互。從請求的轉(zhuǎn)發(fā)流來看,端點負責(zé)向處理器提供請求字節(jié)流,處理器負責(zé)向適配器提供tomcat定義的請求對象,適配器負責(zé)向servlet容器提供標(biāo)準(zhǔn)的servletrequest對象:
端點和處理器可以自由組合并抽象成一個protocolhandler組件。連接器使用protocolhandler來處理網(wǎng)絡(luò)連接和應(yīng)用層協(xié)議。在連接器中,事件處理程序?qū)iT用于處理請求[proto handler];不同協(xié)議處理程序代表不同的連接類型[因此一個服務(wù)中可以有多個連接器]。比如http11protocol用普通socket連接,http11nioprotocol用niosocket連接。端點:對接i/o模型,向處理器提供字節(jié)流,通信端口,是傳輸層的抽象,處理底層socket的網(wǎng)絡(luò)連接,實現(xiàn)tcp/ip協(xié)議。是一個接口,對應(yīng)的抽象類是abstractendpoint,還有很多實現(xiàn)類,比如nioendpoint,jioendpoint等等。它有兩個組成部分,一一個是acceptor,另一個是socketprocessor。acceptor用于監(jiān)控套接字連接請求,socketprocessor用于處理接收到的套接字請求。端點接收到套接字連接后,生成套接字處理器任務(wù)并提交給線程池進行處理。socketprocessor的run方調(diào)用處理器組件解析應(yīng)用層協(xié)議。處理器通過解析生成請求對象后,會調(diào)用適配器的服務(wù)方法。處理器:對接應(yīng)用層協(xié)議,向適配器提供tomcat請求對象。處理器用于實現(xiàn)http協(xié)議,這意味著處理器是應(yīng)用層協(xié)議的抽象。處理器接受來自端點的socket,然后解析成tomcat請求和tomcat響應(yīng)對象,最后通過適配器提交給容器。對應(yīng)的抽象類是abstractprocessor,還有很多實現(xiàn)類,比如ajpprocessor,http11processor。適配器:遵循servlet規(guī)范,servletrequest被提供給容器,protocolhandler接口負責(zé)解析請求并生成tomcat請求類。您需要將此請求對象轉(zhuǎn)換為servletrequest。tomcat引入了coyoteadapter,這是適配器模式的經(jīng)典應(yīng)用。連接器調(diào)用coyoteadapter的sevice方法,tomcat請求對象被傳入。coyoteadapter負責(zé)將tomcat請求轉(zhuǎn)換成servletrequest,然后調(diào)用容器的服務(wù)方法使請求適應(yīng)servlet容器架構(gòu)。容器容器主要用于封裝和管理servlet,并專門處理請求請求。tomcat中設(shè)計了四個servlet容器組件,即引擎、主機、上下文和包裝器- servlet。這四個容器不是平行的,而是父子關(guān)系。tomcat源代碼org、apache、catalina、core和standard engine都有它們的標(biāo)準(zhǔn)實現(xiàn),每個容器都有一個pipel。ine對象。
引擎:catalina的servlet容器引擎,用于管理多個虛擬站點。一個服務(wù)最多只能有一個引擎,但是一個引擎可以包含多個主機。主機:代表虛擬主機或站點。tomcat可以配置多個虛擬主機地址,一個虛擬主機可以包含多個上下文。context:代表一個web應(yīng)用,相當(dāng)于我們在webapp下的應(yīng)用。一個web應(yīng)用程序通常有多個servlet,一個web應(yīng)用程序可以包含多個包裝器子容器。wrapper:servlet包裝類,負責(zé)管理整個servlet生命周期,包括加載、初始化、資源恢復(fù)等。每個包裝器包裝一個servlet。管道和閥門(pipeline and valve)引擎、主機、上下文和包裝容器都繼承了containerbase,containerbase有一個standardpipeline對象。每個容器構(gòu)造方法setbasic設(shè)置默認閥門(標(biāo)準(zhǔn)引擎閥門),初始化和開始管道和閥門組件。
當(dāng)連接器使用容器處理請求時,連接器。getservice。getcontainer。getpipeline。getfirst。調(diào)用(請求、響應(yīng));
啟動過程整個tomcat實際上是一個catalina實例,tomcat啟動時會初始化這個實例。catalina實例通過加載server.xml,創(chuàng)建和管理一個服務(wù)器來完成其他實例的創(chuàng)建,服務(wù)器創(chuàng)建和管理多個服務(wù),每個服務(wù)可以有多個連接器和一個容器。
我們知道啟動tomcat就是執(zhí)行startup.sh腳本文件,其中執(zhí)行catalina.sh,最后是org。執(zhí)行apache . catalina . startup . bootstrap類。
所以知道tomcat是從bootstrap類main方法開始,一步步鏈?zhǔn)秸{(diào)用各個模塊的init方法進行初始化。每個模塊初始化后,會一步步調(diào)用每個模塊的start方法來啟動每個模塊。commonloader、catalinaloader和sharedloader中斷了家長委托。
嵌入式示例接下來,我們將演示嵌入式tomcat運行示例,創(chuàng)建mavxmlns : xsi = http://www.w3.org/2001/ xml schema-實例和xsie cho 15-@ . com schema location = http://maven.apac·梅文父artifactid spring-extend/artifactid groupidcom.itxs/groupid版本1.0-snapshot/version/父model version 4 . 0 . 0/model version artifactid tomcat-test/artifactid屬性maven . compiler . source 8/maven . compiler . target 8/maven . compiler . target 8/properties依賴關(guān)系groupidorg.apache.tomcat.embed/groupid artifactid tomcat-embed-core/artifactid版本8.5.28/version依賴關(guān)系groupidorg.apache.tomcat/groupid artifactid tomcat-jasper/artifactid版本8 . 5 . 28/copy/dependency/dependencies/project創(chuàng)建一個可以回顯0-@ myfirstservlet.java .com的servlet。
包com.itxs導(dǎo)入javax . servlet . http . http servlet;導(dǎo)入javax . servlet . http . http servlet request;導(dǎo)入javax . servlet . http . http servlet response;導(dǎo)入java . io . io exception;公共類myfirstservlet擴展http servlet { private static final long serial version uid = 1l;@ override protected void doget(http servlet request req,httpservletresponse resp)拋出ioexception { dopost(req,resp);} @ override protected void dopost(http servlet request req,httpservletresponse resp)拋出ioexception { resp.getwriter。打印( 您好tomcat servlet,訪問成功?。。?);}}tomcatapplication.java文件
包com.itxsimport org . apache . catalina . life cycle exception;import org . apache . catalina . core . aprlifecyclelistener;導(dǎo)入org . apache . catalina . core . standard context;導(dǎo)入org . apache . catalina . startup . tomcat;導(dǎo)入javax . servlet . servlet exception;導(dǎo)入java . io . file;public class tomcat application { public static int tomcat _ port = 8080公共靜態(tài)字符串tomcat _ hostname = 127.0.0.1公共靜態(tài)字符串webapp _ path = src/main 公共靜態(tài)void main(string[] args)拋出life cycle exception { tomcatapplication . run;}公共靜態(tài)void run拋出life cycle exception { tomcat tomcat = new tomcat;tomcat . setport(tomcat application。tomcat _ port);tomcat . set hostname(tomcat application。tomcat _ hostname);setbasedir( 。 );// tomcat信息保存在項目下;standardcontext mycontext = null請嘗試{ my context =(standard context)tomcat . add web app( /itxsamp,system . getproperty( 目錄 )file . separator to cata application。web app _ path);my context . setreloadable(false);//上下文偵聽器my context . addlifecyclelistener(new april cyclelistener);//register servlet tomcat . add servlet( /itxsamp, 我的第一個servlet ,new my first servlet);// servlet映射my context . addservletmapping decoded( /first . do , myfirstservlet );tomcat . start;tomcat.getserver。await;} catch(servlet exception e){ e . printstacktrace;}}}運行main方法。
并訪問echo3-@。com 127 . 0 . 0 . 1 : 8080/itxs/first . do,接收結(jié)果頁面。
性能調(diào)優(yōu)關(guān)于性能調(diào)優(yōu),您可以考慮幾個因素:
內(nèi)存:jvm參數(shù),實際生產(chǎn)中經(jīng)常用到。并發(fā)優(yōu)化:連接器開放線程池,優(yōu)化線程池;緩存優(yōu)化:連接器壓縮和客戶端連接超時;io優(yōu)化:協(xié)議選擇bio nio nio 2(aio);組件優(yōu)化:apr sendfile epoll openssl tomcat native;我們只是簡單了解一下tomcat的架構(gòu),搭建一下tomcat源碼調(diào)試環(huán)境,然后有時間再進一步分析分享tomcat源碼和設(shè)計模式。
標(biāo)簽:
集裝箱裝配
了解更多tomcat源代碼解讀(tomcat編譯的項目在哪里)相關(guān)內(nèi)容請關(guān)注本站點。