Spring" />

国产成人精品无码青草_亚洲国产美女精品久久久久∴_欧美人与鲁交大毛片免费_国产果冻豆传媒麻婆精东

15158846557 在線咨詢 在線咨詢
15158846557 在線咨詢
所在位置: 首頁 > 營銷資訊 > 網(wǎng)站運(yùn)營 > Tomcat 的工作原理萬字總結(jié),這回終于搞懂了!

Tomcat 的工作原理萬字總結(jié),這回終于搞懂了!

時間:2023-07-15 05:30:01 | 來源:網(wǎng)站運(yùn)營

時間:2023-07-15 05:30:01 來源:網(wǎng)站運(yùn)營

Tomcat 的工作原理萬字總結(jié),這回終于搞懂了!:

前言

如果同一臺電腦上同時裝了兩個Tomcat并且都啟動了有相同的網(wǎng)頁,當(dāng)我們訪問其中的網(wǎng)頁,輸入URL后,Tomcat如何判斷我請求的是哪個服務(wù)器的網(wǎng)頁呢?它將用哪個為我服務(wù)呢?

SpringBoot 就像一條巨蟒,慢慢纏繞著我們,使我們麻痹。不得不承認(rèn),使用了 SpringBoot 確實(shí)提高了工作效率,但同時也讓我們遺忘了很多技能。剛?cè)肷鐣臅r候,我還是通過 Tomcat 手動部署 JavaWeb 項(xiàng)目,還經(jīng)常對 Tomcat 進(jìn)行性能調(diào)優(yōu)。除此之外,還需要自己理清楚各 Jar 之間的關(guān)系,以避免 Jar 丟失和各版本沖突導(dǎo)致服務(wù)啟動異常的問題。到如今,這些繁瑣而又重復(fù)的工作已經(jīng)統(tǒng)統(tǒng)交給 SpringBoot 處理,我們可以把更多的精力放在業(yè)務(wù)邏輯上。但是,清楚 Tomcat 的工作原理和處理請求流程和分析 Spring 框架源碼一樣的重要。至少面試官特別喜歡問這些底層原理和設(shè)計(jì)思路。希望這篇文章能給你一些幫助。

Tomcat 整體架構(gòu)

Tomcat 是一個免費(fèi)的、開源的、輕量級的 Web 應(yīng)用服務(wù)器。適合在并發(fā)量不是很高的中小企業(yè)項(xiàng)目中使用。

文件目錄結(jié)構(gòu)

以下是 Tomcat 8 主要目錄結(jié)構(gòu)







功能組件結(jié)構(gòu)

Tomcat 的核心功能有兩個,分別是負(fù)責(zé)接收和反饋外部請求的連接器 Connector,和負(fù)責(zé)處理請求的容器 Container。其中連接器和容器相輔相成,一起構(gòu)成了基本的 web 服務(wù) Service。每個 Tomcat 服務(wù)器可以管理多個 Service。













Tomcat 連接器核心原理

Tomcat 連接器框架——Coyote

連接器核心功能

一、監(jiān)聽網(wǎng)絡(luò)端口,接收和響應(yīng)網(wǎng)絡(luò)請求。

二、網(wǎng)絡(luò)字節(jié)流處理。將收到的網(wǎng)絡(luò)字節(jié)流轉(zhuǎn)換成 Tomcat Request 再轉(zhuǎn)成標(biāo)準(zhǔn)的 ServletRequest 給容器,同時將容器傳來的 ServletResponse 轉(zhuǎn)成 Tomcat Response 再轉(zhuǎn)成網(wǎng)絡(luò)字節(jié)流。

連接器模塊設(shè)計(jì)

為滿足連接器的兩個核心功能,我們需要一個通訊端點(diǎn)來監(jiān)聽端口;需要一個處理器來處理網(wǎng)絡(luò)字節(jié)流;最后還需要一個適配器將處理后的結(jié)果轉(zhuǎn)成容器需要的結(jié)構(gòu)。







對應(yīng)的源碼包路徑 org.apache.coyote 。對應(yīng)的結(jié)構(gòu)圖如下







Tomcat 容器核心原理

Tomcat 容器框架——Catalina

容器結(jié)構(gòu)分析

每個 Service 會包含一個容器。容器由一個引擎可以管理多個虛擬主機(jī)。每個虛擬主機(jī)可以管理多個 Web 應(yīng)用。每個 Web 應(yīng)用會有多個 Servlet 包裝器。Engine、Host、Context 和 Wrapper,四個容器之間屬于父子關(guān)系。







對應(yīng)的源碼包路徑 org.apache.coyote 。對應(yīng)的結(jié)構(gòu)圖如下







容器請求處理

容器的請求處理過程就是在 Engine、Host、Context 和 Wrapper 這四個容器之間層層調(diào)用,最后在 Servlet 中執(zhí)行對應(yīng)的業(yè)務(wù)邏輯。各容器都會有一個通道 Pipeline,每個通道上都會有一個 Basic Valve(如StandardEngineValve), 類似一個閘門用來處理 Request 和 Response 。其流程圖如下。







Tomcat 請求處理流程

上面的知識點(diǎn)已經(jīng)零零碎碎地介紹了一個 Tomcat 是如何處理一個請求。簡單理解就是連接器的處理流程 + 容器的處理流程 = Tomcat 處理流程。哈!那么問題來了,Tomcat 是如何通過請求路徑找到對應(yīng)的虛擬站點(diǎn)?是如何找到對應(yīng)的 Servlet 呢?

映射器功能介紹

這里需要引入一個上面沒有介紹的組件 Mapper。顧名思義,其作用是提供請求路徑的路由映射。根據(jù)請求URL地址匹配是由哪個容器來處理。其中每個容器都會它自己對應(yīng)的Mapper,如 MappedHost。不知道大家有沒有回憶起被 Mapper class not found 支配的恐懼。在以前,每寫一個完整的功能,都需要在 web.xml 配置映射規(guī)則,當(dāng)文件越來越龐大的時候,各個問題隨著也會出現(xiàn)

HTTP請求流程

打開 tomcat/conf 目錄下的 server.xml 文件來分析一個http://localhost:8080/docs/api 請求。

第一步:連接器監(jiān)聽的端口是8080。由于請求的端口和監(jiān)聽的端口一致,連接器接受了該請求。

第二步:因?yàn)橐娴哪J(rèn)虛擬主機(jī)是 localhost,并且虛擬主機(jī)的目錄是webapps。所以請求找到了 tomcat/webapps 目錄。

第三步:解析的 docs 是 web 程序的應(yīng)用名,也就是 context。此時請求繼續(xù)從 webapps 目錄下找 docs 目錄。有的時候我們也會把應(yīng)用名省略。

第四步:解析的 api 是具體的業(yè)務(wù)邏輯地址。此時需要從 docs/WEB-INF/web.xml 中找映射關(guān)系,最后調(diào)用具體的函數(shù)。

<?xml version="1.0" encoding="UTF-8"?><Server port="8005" shutdown="SHUTDOWN"> <Service name="Catalina"> <!-- 連接器監(jiān)聽端口是 8080,默認(rèn)通訊協(xié)議是 HTTP/1.1 --> <Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" /> <!-- 名字為 Catalina 的引擎,其默認(rèn)的虛擬主機(jī)是 localhost --> <Engine name="Catalina" defaultHost="localhost"> <!-- 名字為 localhost 的虛擬主機(jī),其目錄是 webapps--> <Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true"> </Host> </Engine> </Service></Server>

SpringBoot 如何啟動內(nèi)嵌的 Tomcat

SpringBoot 一鍵啟動服務(wù)的功能,讓有很多剛?cè)肷鐣呐笥讯纪?Tomcat 是啥。隨著硬件的性能越來越高,普通中小項(xiàng)目都可以直接用內(nèi)置 Tomcat 啟動。但是有些大一點(diǎn)的項(xiàng)目可能會用到 Tomcat 集群和調(diào)優(yōu),內(nèi)置的 Tomcat 就不一定能滿足需求了。

我們先從源碼中分析 SpringBoot 是如何啟動 Tomcat,以下是 SpringBoot 2.x 的代碼。

代碼從 main 方法開始,執(zhí)行 run 方法啟動項(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 { // 啟動 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)方法,與之對應(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ù)啟動后會打印日志

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.34o.a.catalina.core.AprLifecycleListener : The APR based Apache Tomcat Native library which allows optimal ...o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContexto.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 16858 ms

END

作者:ITDragon龍
鏈接:https://www.cnblogs.com/itdragon/p/13657104.html
來源:cnblogs

下面是 Tomcat Server處理一個HTTP請求的過程







1、用戶點(diǎn)擊網(wǎng)頁內(nèi)容,請求被發(fā)送到本機(jī)端口8080,被在那里監(jiān)聽的Coyote HTTP/1.1 Connector獲得。

2、Connector把該請求交給它所在的Service的Engine來處理,并等待Engine的回應(yīng)。

3、Engine獲得請求localhost/test/index.jsp,匹配所有的虛擬主機(jī)Host。

4、Engine匹配到名為localhost的Host(即使匹配不到也把請求交給該Host處理,因?yàn)樵揌ost被定義為該Engine的默認(rèn)主機(jī)),名為localhost的Host獲得請求/test/index.jsp,匹配它所擁有的所有的Context。Host匹配到路徑為/test的Context(如果匹配不到就把該請求交給路徑名為“ ”的Context去處理)。

5、path=“/test”的Context獲得請求/index.jsp,在它的mapping table中尋找出對應(yīng)的Servlet。Context匹配到URL PATTERN為*.jsp的Servlet,對應(yīng)于JspServlet類。

6、構(gòu)造HttpServletRequest對象和HttpServletResponse對象,作為參數(shù)調(diào)用JspServlet的doGet()或doPost().執(zhí)行業(yè)務(wù)邏輯、數(shù)據(jù)存儲等程序。

7、Context把執(zhí)行完之后的HttpServletResponse對象返回給Host。

8、Host把HttpServletResponse對象返回給Engine。

9、Engine把HttpServletResponse對象返回Connector。

10、Connector把HttpServletResponse對象返回給客戶Browser。

作者:zxl_Dragon
原文鏈接:https://blog.csdn.net/zxl_Dragon/article/details/83584667
來源:csdn
最后,照舊安利一波我們的公眾號:「終端研發(fā)部」,目前每天都會推薦一篇優(yōu)質(zhì)的技術(shù)相關(guān)的文章,主要分享java相關(guān)的技術(shù)與面試技巧,我們的目標(biāo)是: 知道是什么,為什么,打好基礎(chǔ),做好每一點(diǎn)!這個主創(chuàng)技術(shù)公眾號超級值得大家關(guān)注。

關(guān)鍵詞:總結(jié),工作,原理

74
73
25
news

版權(quán)所有? 億企邦 1997-2025 保留一切法律許可權(quán)利。

為了最佳展示效果,本站不支持IE9及以下版本的瀏覽器,建議您使用谷歌Chrome瀏覽器。 點(diǎn)擊下載Chrome瀏覽器
關(guān)閉