這篇文章主要介紹了Tomcat的工作原理和處理請(qǐng)求流程是什么的相關(guān)知識(shí),內(nèi)容詳細(xì)易懂,操作簡(jiǎn)單快捷,具有一定借鑒價(jià)值,相信大家閱讀完這篇Tomcat的工作原理和處理請(qǐng)求流程是什么文章都會(huì)有所收獲,下面我們一起來看看吧。
成都創(chuàng)新互聯(lián)專業(yè)為企業(yè)提供丹東網(wǎng)站建設(shè)、丹東做網(wǎng)站、丹東網(wǎng)站設(shè)計(jì)、丹東網(wǎng)站制作等企業(yè)網(wǎng)站建設(shè)、網(wǎng)頁設(shè)計(jì)與制作、丹東企業(yè)網(wǎng)站模板建站服務(wù),十載丹東做網(wǎng)站經(jīng)驗(yàn),不只是建網(wǎng)站,更提供有價(jià)值的思路和整體網(wǎng)絡(luò)服務(wù)。
Tomcat 連接器框架——Coyote
一、監(jiān)聽網(wǎng)絡(luò)端口,接收和響應(yīng)網(wǎng)絡(luò)請(qǐng)求。
二、網(wǎng)絡(luò)字節(jié)流處理。將收到的網(wǎng)絡(luò)字節(jié)流轉(zhuǎn)換成 Tomcat Request 再轉(zhuǎn)成標(biāo)準(zhǔn)的 ServletRequest 給容器,同時(shí)將容器傳來的 ServletResponse 轉(zhuǎn)成 Tomcat Response 再轉(zhuǎn)成網(wǎng)絡(luò)字節(jié)流。
為滿足連接器的兩個(gè)核心功能,我們需要一個(gè)通訊端點(diǎn)來監(jiān)聽端口;需要一個(gè)處理器來處理網(wǎng)絡(luò)字節(jié)流;最后還需要一個(gè)適配器將處理后的結(jié)果轉(zhuǎn)成容器需要的結(jié)構(gòu)。
對(duì)應(yīng)的源碼包路徑 org.apache.coyote 。對(duì)應(yīng)的結(jié)構(gòu)圖如下
Tomcat 容器框架——Catalina
每個(gè) Service 會(huì)包含一個(gè)容器。容器由一個(gè)引擎可以管理多個(gè)虛擬主機(jī)。每個(gè)虛擬主機(jī)可以管理多個(gè) Web 應(yīng)用。每個(gè) Web 應(yīng)用會(huì)有多個(gè) Servlet 包裝器。Engine、Host、Context 和 Wrapper,四個(gè)容器之間屬于父子關(guān)系。
對(duì)應(yīng)的源碼包路徑 org.apache.coyote 。對(duì)應(yīng)的結(jié)構(gòu)圖如下
容器的請(qǐng)求處理過程就是在 Engine、Host、Context 和 Wrapper 這四個(gè)容器之間層層調(diào)用,最后在 Servlet 中執(zhí)行對(duì)應(yīng)的業(yè)務(wù)邏輯。各容器都會(huì)有一個(gè)通道 Pipeline,每個(gè)通道上都會(huì)有一個(gè) Basic Valve(如StandardEngineValve), 類似一個(gè)閘門用來處理 Request 和 Response 。其流程圖如下。
上面的知識(shí)點(diǎn)已經(jīng)零零碎碎地介紹了一個(gè) Tomcat 是如何處理一個(gè)請(qǐng)求。簡(jiǎn)單理解就是連接器的處理流程 + 容器的處理流程 = Tomcat 處理流程。哈!那么問題來了,Tomcat 是如何通過請(qǐng)求路徑找到對(duì)應(yīng)的虛擬站點(diǎn)?是如何找到對(duì)應(yīng)的 Servlet 呢?
這里需要引入一個(gè)上面沒有介紹的組件 Mapper。顧名思義,其作用是提供請(qǐng)求路徑的路由映射。根據(jù)請(qǐng)求URL地址匹配是由哪個(gè)容器來處理。其中每個(gè)容器都會(huì)它自己對(duì)應(yīng)的Mapper,如 MappedHost。不知道大家有沒有回憶起被 Mapper class not found 支配的恐懼。在以前,每寫一個(gè)完整的功能,都需要在 web.xml 配置映射規(guī)則,當(dāng)文件越來越龐大的時(shí)候,各個(gè)問題隨著也會(huì)出現(xiàn)
打開 tomcat/conf 目錄下的 server.xml 文件來分析一個(gè)http://localhost:8080/docs/api 請(qǐng)求。
第一步:連接器監(jiān)聽的端口是8080。由于請(qǐng)求的端口和監(jiān)聽的端口一致,連接器接受了該請(qǐng)求。
第二步:因?yàn)橐娴哪J(rèn)虛擬主機(jī)是 localhost,并且虛擬主機(jī)的目錄是webapps。所以請(qǐng)求找到了 tomcat/webapps 目錄。
第三步:解析的 docs 是 web 程序的應(yīng)用名,也就是 context。此時(shí)請(qǐng)求繼續(xù)從 webapps 目錄下找 docs 目錄。有的時(shí)候我們也會(huì)把應(yīng)用名省略。
第四步:解析的 api 是具體的業(yè)務(wù)邏輯地址。此時(shí)需要從 docs/WEB-INF/web.xml 中找映射關(guān)系,最后調(diào)用具體的函數(shù)。
<?xml version="1.0"> SpringBoot 如何啟動(dòng)內(nèi)嵌的 TomcatSpringBoot 一鍵啟動(dòng)服務(wù)的功能,讓有很多剛?cè)肷鐣?huì)的朋友都忘記 Tomcat 是啥。隨著硬件的性能越來越高,普通中小項(xiàng)目都可以直接用內(nèi)置 Tomcat 啟動(dòng)。但是有些大一點(diǎn)的項(xiàng)目可能會(huì)用到 Tomcat 集群和調(diào)優(yōu),內(nèi)置的 Tomcat 就不一定能滿足需求了。我們先從源碼中分析 SpringBoot 是如何啟動(dòng) Tomcat,以下是 SpringBoot 2.x 的代碼。代碼從 main 方法開始,執(zhí)行 run 方法啟動(dòng)項(xiàng)目。SpringApplication.run 從 run 方法點(diǎn)進(jìn)去,找到刷新應(yīng)用上下文的方法。this.prepareContext(context, environment, listeners, applicationArguments, printedBanner); this.refreshContext(context); this.afterRefresh(context, applicationArguments); 從 refreshContext 方法點(diǎn)進(jìn)去,找 refresh 方法。并一層層往上找其父類的方法。this.refresh(context); 在 AbstractApplicationContext 類的 refresh 方法中,有一行調(diào)用子容器刷新的邏輯。this.postProcessBeanFactory(beanFactory); this.invokeBeanFactoryPostProcessors(beanFactory); this.registerBeanPostProcessors(beanFactory); this.initMessageSource(); this.initApplicationEventMulticaster(); this.onRefresh(); this.registerListeners(); this.finishBeanFactoryInitialization(beanFactory); this.finishRefresh(); 從 onRefresh 方法點(diǎn)進(jìn)去,找到 ServletWebServerApplicationContext 的實(shí)現(xiàn)方法。在這里終于看到了希望。protected void onRefresh() { super.onRefresh(); try { this.createWebServer(); } catch (Throwable var2) { throw new ApplicationContextException("Unable to start web server", var2); } } 從 createWebServer 方法點(diǎn)進(jìn)去,找到從工廠類中獲取 WebServer的代碼。if (webServer == null && servletContext == null) { ServletWebServerFactory factory = this.getWebServerFactory(); // 獲取 web server this.webServer = factory.getWebServer(new ServletContextInitializer[]{this.getSelfInitializer()}); } else if (servletContext != null) { try { // 啟動(dòng) web server this.getSelfInitializer().onStartup(servletContext); } catch (ServletException var4) { throw new ApplicationContextException("Cannot initialize servlet context", var4); } } 從 getWebServer 方法點(diǎn)進(jìn)去,找到 TomcatServletWebServerFactory 的實(shí)現(xiàn)方法,與之對(duì)應(yīng)的還有 Jetty 和 Undertow。這里配置了基本的連接器、引擎、虛擬站點(diǎn)等配置。public WebServer getWebServer(ServletContextInitializer... initializers) { Tomcat tomcat = new Tomcat(); File baseDir = this.baseDirectory != null ? this.baseDirectory : this.createTempDir("tomcat"); tomcat.setBaseDir(baseDir.getAbsolutePath()); Connector connector = new Connector(this.protocol); tomcat.getService().addConnector(connector); this.customizeConnector(connector); tomcat.setConnector(connector); tomcat.getHost().setAutoDeploy(false); this.configureEngine(tomcat.getEngine()); Iterator var5 = this.additionalTomcatConnectors.iterator(); while(var5.hasNext()) { Connector additionalConnector = (Connector)var5.next(); tomcat.getService().addConnector(additionalConnector); } this.prepareContext(tomcat.getHost(), initializers); return this.getTomcatWebServer(tomcat); } 服務(wù)啟動(dòng)后會(huì)打印日志o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8900 (http) o.apache.catalina.core.StandardService : Starting service [Tomcat] org.apache.catalina.core.StandardEngine : Starting Servlet Engine: Apache Tomcat/8.5.34 o.a.catalina.core.AprLifecycleListener : The APR based Apache Tomcat Native library which allows optimal ... o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 16858 ms 我感覺我好像發(fā)現(xiàn)為什么比較牛的公司都會(huì)問到技術(shù)的底層源碼了,因?yàn)樵诳丛创a的過程中是真的很有意思,并且能夠發(fā)現(xiàn)很多的問題,而且真的是考驗(yàn)邏輯思維和耐心,我這看個(gè)tomcat源碼,一天的時(shí)候就那么過去了,還沒整完,這還是我以為我對(duì)tomcat已經(jīng)非常熟悉的前提下了,哈哈哈哈,關(guān)注我,后面有時(shí)間再慢慢更新吧 最后給大家介紹一份文檔,這也是我在解析tomcat過程中參考最多的書籍,內(nèi)部的知識(shí)基本涵蓋了tomcat的相關(guān)內(nèi)容,從架構(gòu)設(shè)計(jì)到配置到集群到性能優(yōu)化和擴(kuò)展等,全方位解析tomcat,有需要的朋友可以關(guān)注+轉(zhuǎn)發(fā)后,私信“源碼”即可查看獲取方式 tomcat架構(gòu) tomcat配置管理 tomcat安全 tomcat調(diào)優(yōu) tomcat附加功能 篇幅原因,只展示這一部分,有需要更多Java相關(guān)學(xué)習(xí)文檔,視頻的,關(guān)注我,后臺(tái)私信“資料”即可獲取
關(guān)于“Tomcat的工作原理和處理請(qǐng)求流程是什么”這篇文章的內(nèi)容就介紹到這里,感謝各位的閱讀!相信大家對(duì)“Tomcat的工作原理和處理請(qǐng)求流程是什么”知識(shí)都有一定的了解,大家如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。
文章標(biāo)題:Tomcat的工作原理和處理請(qǐng)求流程是什么
文章分享:http://muchs.cn/article46/ghggeg.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供外貿(mào)網(wǎng)站建設(shè)、ChatGPT、服務(wù)器托管、網(wǎng)站內(nèi)鏈、手機(jī)網(wǎng)站建設(shè)、App設(shè)計(jì)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)