千家信息网

Tomcat的工作原理和处理请求流程是什么

发表于:2024-11-11 作者:千家信息网编辑
千家信息网最后更新 2024年11月11日,这篇文章主要介绍了Tomcat的工作原理和处理请求流程是什么的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Tomcat的工作原理和处理请求流程是什么文章都会有所收获,下面
千家信息网最后更新 2024年11月11日Tomcat的工作原理和处理请求流程是什么

这篇文章主要介绍了Tomcat的工作原理和处理请求流程是什么的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Tomcat的工作原理和处理请求流程是什么文章都会有所收获,下面我们一起来看看吧。

功能组件结构

Tomcat 连接器核心原理

Tomcat 连接器框架--Coyote

连接器核心功能

一、监听网络端口,接收和响应网络请求。

二、网络字节流处理。将收到的网络字节流转换成 Tomcat Request 再转成标准的 ServletRequest 给容器,同时将容器传来的 ServletResponse 转成 Tomcat Response 再转成网络字节流。

连接器模块设计

为满足连接器的两个核心功能,我们需要一个通讯端点来监听端口;需要一个处理器来处理网络字节流;最后还需要一个适配器将处理后的结果转成容器需要的结构。

对应的源码包路径 org.apache.coyote 。对应的结构图如下

Tomcat 容器核心原理

Tomcat 容器框架--Catalina

容器结构分析

每个 Service 会包含一个容器。容器由一个引擎可以管理多个虚拟主机。每个虚拟主机可以管理多个 Web 应用。每个 Web 应用会有多个 Servlet 包装器。Engine、Host、Context 和 Wrapper,四个容器之间属于父子关系。

对应的源码包路径 org.apache.coyote 。对应的结构图如下

容器请求处理

容器的请求处理过程就是在 Engine、Host、Context 和 Wrapper 这四个容器之间层层调用,最后在 Servlet 中执行对应的业务逻辑。各容器都会有一个通道 Pipeline,每个通道上都会有一个 Basic Valve(如StandardEngineValve), 类似一个闸门用来处理 Request 和 Response 。其流程图如下。

Tomcat 请求处理流程

上面的知识点已经零零碎碎地介绍了一个 Tomcat 是如何处理一个请求。简单理解就是连接器的处理流程 + 容器的处理流程 = Tomcat 处理流程。哈!那么问题来了,Tomcat 是如何通过请求路径找到对应的虚拟站点?是如何找到对应的 Servlet 呢?

映射器功能介绍

这里需要引入一个上面没有介绍的组件 Mapper。顾名思义,其作用是提供请求路径的路由映射。根据请求URL地址匹配是由哪个容器来处理。其中每个容器都会它自己对应的Mapper,如 MappedHost。不知道大家有没有回忆起被 Mapper class not found 支配的恐惧。在以前,每写一个完整的功能,都需要在 web.xml 配置映射规则,当文件越来越庞大的时候,各个问题随着也会出现

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 中找映射关系,最后调用具体的函数。

  SpringBoot 如何启动内嵌的 TomcatSpringBoot 一键启动服务的功能,让有很多刚入社会的朋友都忘记 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 server        this.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.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 我感觉我好像发现为什么比较牛的公司都会问到技术的底层源码了,因为在看源码的过程中是真的很有意思,并且能够发现很多的问题,而且真的是考验逻辑思维和耐心,我这看个tomcat源码,一天的时候就那么过去了,还没整完,这还是我以为我对tomcat已经非常熟悉的前提下了,哈哈哈哈,关注我,后面有时间再慢慢更新吧 最后给大家介绍一份文档,这也是我在解析tomcat过程中参考最多的书籍,内部的知识基本涵盖了tomcat的相关内容,从架构设计到配置到集群到性能优化和扩展等,全方位解析tomcat,有需要的朋友可以关注+转发后,私信"源码"即可查看获取方式 tomcat架构 tomcat配置管理 tomcat安全 tomcat调优 tomcat附加功能  篇幅原因,只展示这一部分,有需要更多Java相关学习文档,视频的,关注我,后台私信"资料"即可获取

关于"Tomcat的工作原理和处理请求流程是什么"这篇文章的内容就介绍到这里,感谢各位的阅读!相信大家对"Tomcat的工作原理和处理请求流程是什么"知识都有一定的了解,大家如果还想学习更多知识,欢迎关注行业资讯频道。

容器 处理 方法 流程 连接器 功能 源码 原理 网络 目录 知识 端口 结构 应用 配置 工作 主机 核心 虚拟主机 路径 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 数据库2008连接服务器 全连接支撑的数据库 软件开发的系统需求分析 pLc与软件开发哪个难 一刀传世vivo服务器 数据库迁移能通过什么技术 中国应对网络安全的基本方略 早期阅读软件开发 网络安全工程师岗位认知 河南利越网络技术有限公司 本地域名服务器和权威域名服务器 软件开发月月都开工资 互联网尖端科技 常见的数据库检索系统平台 南宁环视网网络技术有限公司 网络安全的特性有哪些 一梦江湖挂锁需要一个服务器吗 大学计算机建立数据库表 网络安全照片原图app下载 为什么要部署网络安全设备 测试转软件开发怎么样 网络技术如何划分子网 网格化数据综合管理软件开发 怎么看手机上的网络安全密钥 怀柔区技术软件开发服务保障 dash流媒体服务器搭建 网络安全防诈骗心得体会300 网络安全实训营讲话 抚州个人服务器哪里比较好 数据库有哪几种
0