日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

tomcat的工作原理

發布時間:2023/12/10 编程问答 48 豆豆
生活随笔 收集整理的這篇文章主要介紹了 tomcat的工作原理 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

本文源自轉載:你還記得 Tomcat 的工作原理么

一、Tomcat 整體架構

Tomcat 是一個免費的、開源的、輕量級的 Web 應用服務器。適合在并發量不是很高的中小企業項目中使用。

?

二、文件目錄結構

以下是 Tomcat 8 主要目錄結構

?

三、功能組件結構

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

?

四、Tomcat 連接器核心原理

Tomcat 連接器框架——Coyote

4.1 連接器核心功能

一、監聽網絡端口,接收和響應網絡請求。

二、網絡字節流處理。將收到的網絡字節流轉換成 Tomcat Request 再轉成標準的 ServletRequest 給容器,同時將容器傳來的 ServletResponse 轉成 Tomcat Response 再轉成網絡字節流。

4.2 連接器模塊設計

為滿足連接器的兩個核心功能,我們需要一個通訊端點來監聽端口;需要一個處理器來處理網絡字節流;最后還需要一個適配器將處理后的結果轉成容器需要的結構。

對應的源碼包路徑?org.apache.coyote?。對應的結構圖如:

五、Tomcat 容器核心原理

Tomcat 容器框架——Catalina

5.1 容器結構分析

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

對應的源碼包路徑?org.apache.coyote?。對應的結構圖如下:

5.2 容器請求處理

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

六、Tomcat 請求處理流程

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

6.1 映射器功能介紹

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

6.2 HTTP請求流程

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

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

第二步:因為引擎的默認虛擬主機是 localhost,并且虛擬主機的目錄是webapps。所以請求找到了 tomcat/webapps 目錄。

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

第四步:解析的 api 是具體的業務邏輯地址。此時需要從 docs/WEB-INF/web.xml 中找映射關系,最后調用具體的函數。

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

七、SpringBoot 如何啟動內嵌的 Tomcat

SpringBoot 一鍵啟動服務的功能,讓有很多剛入社會的朋友都忘記 Tomcat 是啥。隨著硬件的性能越來越高,普通中小項目都可以直接用內置 Tomcat 啟動。但是有些大一點的項目可能會用到 Tomcat 集群和調優,內置的 Tomcat 就不一定能滿足需求了。

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

代碼從 main 方法開始,執行 run 方法啟動項目。

SpringApplication.run

從 run 方法點進去,找到刷新應用上下文的方法。

this.prepareContext(context, environment, listeners, applicationArguments, printedBanner); this.refreshContext(context); this.afterRefresh(context, applicationArguments);

從 refreshContext 方法點進去,找 refresh 方法。并一層層往上找其父類的方法。

this.refresh(context);

在 AbstractApplicationContext 類的 refresh 方法中,有一行調用子容器刷新的邏輯。

this.postProcessBeanFactory(beanFactory); this.invokeBeanFactoryPostProcessors(beanFactory); this.registerBeanPostProcessors(beanFactory); this.initMessageSource(); this.initApplicationEventMulticaster(); this.onRefresh(); this.registerListeners(); this.finishBeanFactoryInitialization(beanFactory); this.finishRefresh();

從 onRefresh 方法點進去,找到 ServletWebServerApplicationContext 的實現方法。在這里終于看到了希望。

protected void onRefresh() {super.onRefresh();try {this.createWebServer();} catch (Throwable var2) {throw new ApplicationContextException("Unable to start web server", var2);} }

從 createWebServer 方法點進去,找到從工廠類中獲取 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 serverthis.getSelfInitializer().onStartup(servletContext);} catch (ServletException var4) {throw new ApplicationContextException("Cannot initialize servlet context", var4);} }

從 getWebServer 方法點進去,找到 TomcatServletWebServerFactory 的實現方法,與之對應的還有 Jetty 和 Undertow。這里配置了基本的連接器、引擎、虛擬站點等配置。

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); }

服務啟動后會打印日志

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

?

總結

以上是生活随笔為你收集整理的tomcat的工作原理的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。