Tomcat源码解析】整体架构组成及核心组件

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
简介: Tomcat,原名Catalina,是一款优雅轻盈的Web服务器,自4.x版本起扩展了JSP、EL等功能,超越了单纯的Servlet容器范畴。Servlet是Sun公司为Java编程Web应用制定的规范,Tomcat作为Servlet容器,负责构建Request与Response对象,并执行业务逻辑。

前言

Tomcat,昔日名为 Catalina,本是轻巧的 Servlet 容器。Catalina,美国加州海岸线上一颗璀璨的明珠。或许,Tomcat 的缔造者寄望于此,期冀将 Tomcat 塑造为一款既优雅又轻盈的 Web 服务器。自 4.x 版本起,Tomcat 不再局限于 Servlet 的支持,而是增添了诸多新功能,如 JSP、EL、命名服务等,从而超越了 Catalina 的范畴。

既然 Tomcat 的核心身份乃 Servlet 容器,我们便应更加关注 Servlet 本身。

何谓 Servlet?

追溯至互联网的萌芽时期,Sun 公司(后被 Oracle 纳入麾下)洞察到了这一时代机遇,便推出了 Applet 以支持 Web 应用。然而,Applet 并未如预期般在业界掀起波澜。Sun 在反思之后,意识到机遇与市场前景皆不可辜负,于是决定投身于制定一套新的规范,Servlet 便应运而生。

Servlet,乃 Sun 公司为使 Java 语言能够编织动态且富有交互性的网页,进而迈入 Web 编程之殿堂,所精心制定的一套规范。
一个 Servlet 的核心职责可概括为以下三端:

  1. 构建并充实 Request 对象,囊括 URI、参数、请求方式、头部讯息、以及请求本体等。
  2. 创建 Response 对象。
  3. 运行业务逻辑,并将成果经由 Response 的输出流,传递至客户端。

Servlet 自身并不包含 main 方法,故其执行需依托于一容器之中,此容器之存在,正为支撑 Servlet 之功能。Tomcat,便是这样一种 Servlet 容器的具象实现。

整体架构图:

在 Tomcat 的架构图之中,两个核心组件——连接器(Connector)与容器(Container)扮演着心脏般的关键角色,它们的重要性不言而喻。以下是它们各自的职责:

  1. 连接器(Connector)负责处理与连接相关的事务,它将 Socket 连接转化为 Request 和 Response 对象,以便进行后续处理。
  2. 容器(Container)则负责封装与管理工作中的 Servlet,并具体承担起处理 Request 请求的重任。

在 Tomcat 的体系结构中,仅存在一个 Server 实例,而一个 Server 可以容纳多个 Service。每个 Service 仅关联一个 Container,但可以配备多个 Connectors。这样的设计意味着一个服务能够通过多个连接器来接纳连接,例如同时提供 HTTP 与 HTTPS 协议的链接,或者针对同一协议的不同端口提供服务。架构的示意图如下(后续将详细介绍 Engine、Host、Context 等组件):

image.png

在 Tomcat 的宏伟蓝图中,多个 Connector 与一个 Container 共同构成了 Service,正是 Service 使得 Tomcat 能够向外提供服务。然而,Service 本身需要一个生存的依托,需要一个能够赋予其生命、掌控其存亡的主宰,这个角色非 Server 莫属。因此,Tomcat 的整个生命周期都受到 Server 的调控。

此外,这些组件之间的包含关系,或者说是层级关系,均可在 Tomcat 配置的心脏——conf目录下的server.xml文件中一览无余。在这个配置文件中,我们可以洞察到 Tomcat 的骨骼架构,理解各个组件如何相互连接、协作,共同支撑起整个服务器的运行。

上边的配置文件,还可以通过下边的一张结构图更清楚的理解:

image.png

在 Tomcat 的架构中,各个组件各司其职,共同织就了一张精密的服务网络。下面,让我们逐一探究这些组件的独特功能:

  1. Server:作为整个服务器的代表,Server 提供了一种简洁而优雅的方式,用以启动和停止整个 Tomcat 系统。它使得我们无需单独对连接器和容器进行繁琐的启停操作。
  2. Service:Service 代表着服务本身,一个 Server 可以运行多个 Service。例如,在单个 Tomcat 实例中,可以同时运行订单服务、支付服务和用户服务等。
  3. Connector:Connector 是连接的桥梁,一个 Service 可以包含多个 Connector,以支持多种通信协议。例如,可以同时支持 AJP、HTTP 和 HTTPS 协议,每种协议都可以通过特定的 Connector 来实现。但是每种协议最终执行的 servlet 是相通的。
  4. Container:Container 是 Servlet 的栖息之地,它负责管理和执行 Servlet。
    1. Engine:作为引擎,Engine 是 Container 的最高层级,它可以包含多个 Host。
    2. Host:Host 代表虚拟主机,每个 Host 可以包含多个 Context。
    3. Context:Context 是 Web 应用的上下文,它定义了 Web 应用的部署参数和路径。
    4. Wrapper:Wrapper 是 Servlet 的包装器,它负责 Servlet 的生命周期管理和资源分配。
  5. Service 服务之下还有各种支撑组件
    1. Manager:Manager 是会话管理器,它负责管理用户的会话(Session)。
    2. Logger:Logger 是日志管理器,它负责记录和管理日志信息。
    3. Loader:Loader 是类加载器,它与类的加载机制相关,通常由 Context 使用。
    4. Pipeline:Pipeline 是管道组件,它与 Valve 一起实现过滤器功能。
    5. Valve:Valve 是阀门组件,它与 Pipeline 配合,用于实现请求和响应的过滤处理。
    6. Realm:Realm 是安全域,它负责认证和授权。

在 Tomcat 的架构中,除了连接器和容器之外,Pipeline 和 Valve 也扮演着至关重要的角色。它们共同构成了 Tomcat 强大的过滤和处理能力。通过一张图,我们可以更直观地理解这两个组件如何在请求处理流程中发挥作用。

image.png

Connector 和 Container 的微妙关系

在 Tomcat 的宏伟舞台之上,当一个请求翩翩而至,它的旅程便开始了:

  1. Service:请求首先抵达 Service,这是 Tomcat 服务的起点,调度着整个服务的流程。
  2. Connector:随后,请求被引导至 Connector,它是 Tomcat 的忠实门卫,负责接收来自远方的请求。Connector 将原始的网络连接转化为符合 HTTP 协议的 Request 和 Response 对象。
  3. Container:Request 和 Response 在 Connector 的精心包装后,便被递交至 Container。它负责管理和执行 Servlet,对请求进行细致的处理。
  4. 处理与返回:Container 在处理完请求后,将结果交回 Connector。Connector 再次承担起信使的角色,通过 Socket 将处理结果沿着 TCP/IP 协议的路径,送回客户端。

在整个过程中,Connector 不仅是沟通客户端与服务器的桥梁,更是实现 TCP/IP 协议和 HTTP 协议的使者。它确保了请求和响应的准确传递,使得整个 Web 服务顺利的流转起来

Connector 架构分析

连接器(Connector)犹如一扇沟通外界与应用系统的窗口,负责接收来自客户端的请求,将其转化为标准化的 Request 和 Response 对象,并交给容器(Container)进行处理。Container 处理完后再交给 Connector 返回给客户端。从功能上看,我们可以将连接器拆解为以下三个核心环节:

  1. 请求的捕获: 连接器如何精准地捕捉到来自客户端的海量请求?
  2. 请求与响应的封装: 连接器是如何将纷繁复杂的原始请求数据,规范地封装成 Request 对象,并将容器处理后的结果打包成 Response 对象的?
  3. 请求的传递与响应的回传: 封装后的 Request 对象如何被高效地传递给容器,而容器生成的 Response 对象又如何准确地返回给客户端?

我们看下 Connector 的结构图,如下:
image.png

Connector 的核心组件与工作原理

Connector 通过 ProtocolHandler 来处理各种类型的网络请求。不同的 ProtocolHandler 对应不同的连接方式,如Http11Protocol使用传统的阻塞式 Socket,而 Http11NioProtocol 则采用高效的非阻塞式 NIO Socket。
ProtocolHandler 主要由 Endpoint、Processor 和 Adapter 三个组件构成:

  • Endpoint: 负责底层网络连接的管理,包括 Socket 的创建、监听、接受以及连接的关闭。它相当于一个“门卫”,负责把控所有进出系统的网络流量。Endpoint 通常实现了 TCP/IP 协议栈的部分功能,用于建立可靠的网络连接。
  • Processor: 专门负责将 Endpoint 接收到的原始 Socket 数据解析为标准化的 HTTP 请求(Request)。它可以看作是一个“翻译官”,将底层的网络字节流转化为应用程序可以理解的请求信息。Processor 实现了 HTTP 协议的具体细节,包括请求行的解析、请求头的处理、请求体的读取等。
  • Adapter: 充当了连接器与容器之间的适配器。它将 Processor 处理好的 Request 对象传递给 Container,以便容器中的 Servlet 或其他组件对请求进行具体的处理。Adapter 的作用类似于一个“中介”,将不同层次的组件联系起来。

Endpoint 内部机制
Endpoint 的抽象实现 AbstractEndpoint 定义了几个重要的内部类和接口:

  • Acceptor: 负责监听来自客户端的连接请求,一旦有新的连接到来,Acceptor 就会创建一个新的 Socket,并将其交给 Handler 处理。
  • AsyncTimeout: 用来监控异步请求的超时情况。对于长时间未得到响应的异步请求,AsyncTimeout 会采取相应的处理措施,比如关闭连接或者触发超时事件。
  • Handler: 是一个接口,定义了处理新连接的具体逻辑。当 Acceptor 接收到一个新的 Socket 时,会创建一个 Handler 实例,并将其与该 Socket 关联起来。Handler 会调用 Processor 来解析请求,并将处理结果返回给客户端。

小结:

Connector 通过这三个组件的协同工作,实现了从接收客户端请求到返回处理结果的整个过程。Endpoint 负责建立连接,Processor 负责解析请求,Adapter 负责将请求传递给容器。这种分层设计使得 Connector 具有良好的扩展性和可维护性。

Container 如何处理请求的

容器(Container)采用 Pipeline-Valve 管道机制来处理请求,这是一种基于责任链模式的设计。在请求处理过程中,多个 Valve 会依次对请求进行处理,每个 Valve 负责特定的任务。
与传统的责任链模式不同,Pipeline-Valve 具有以下特点:

  • 固定终点: 每个 Pipeline 都有一个特殊的 Valve,即 BaseValve。BaseValve 位于 Pipeline 的末端,不可删除,确保每个请求都经过它的处理。
  • 层级调用: 上层容器的 BaseValve 会调用下层容器的 Pipeline,形成一个嵌套的责任链,使得请求在不同层次的容器中依次得到处理。

Tomcat 中的四个标准容器(Engine、Host、Context、Wrapper)分别对应一个 BaseValve:StandardEngineValve、StandardHostValve、StandardContextValve、StandardWrapperValve。

Pipeline 的处理流程图如下:
image.png

当 Connector 接收到一个请求时,它会将请求委派给最顶层的容器——Engine。Engine 拥有一个 Pipeline,就像一条流水线,流水线上的每个工位就是一个 Valve。这些 Valve 按照预定的顺序对请求进行处理。

  1. Engine 管道: 请求首先进入 Engine 的 Pipeline。在这个管道中,一系列 EngineValve 会依次对请求进行处理,例如进行全局性的日志记录、安全检查等。最后,StandardEngineValve 会将请求转发给下一层容器——Host。
  2. 逐级传递: Host、Context、Wrapper 等容器都拥有自己的 Pipeline,它们会按照同样的方式处理请求。每个容器的 BaseValve(如 StandardHostValve、StandardContextValve)负责将请求传递给下一层容器。
  3. FilterChain: 当请求到达 Wrapper 容器时,StandardWrapperValve 会创建一个 FilterChain。FilterChain 包含了与该请求匹配的所有 Filter 和 Servlet。这些 Filter 和 Servlet 会按照配置的顺序依次执行 doFilter 方法,最终调用 Servlet 的 service 方法来处理请求。
  4. 返回响应: 一旦请求处理完毕,响应结果会沿着原路返回,经过各个 Valve,最终由 Connector 发送回客户端。

好了,我们已经从整体上看到了 Tomcat 的结构,对于每个组件并没有详细分析。后续章节我们会从几个方面来学习 Tomcat

如有问题,欢迎微信搜索【码上遇见你】。

相关文章
|
6天前
|
数据采集 监控 前端开发
二级公立医院绩效考核系统源码,B/S架构,前后端分别基于Spring Boot和Avue框架
医院绩效管理系统通过与HIS系统的无缝对接,实现数据网络化采集、评价结果透明化管理及奖金分配自动化生成。系统涵盖科室和个人绩效考核、医疗质量考核、数据采集、绩效工资核算、收支核算、工作量统计、单项奖惩等功能,提升绩效评估的全面性、准确性和公正性。技术栈采用B/S架构,前后端分别基于Spring Boot和Avue框架。
|
5天前
|
边缘计算 自动驾驶 5G
|
18小时前
|
机器学习/深度学习 人工智能 自然语言处理
医疗行业的语音识别技术解析:AI多模态能力平台的应用与架构
AI多模态能力平台通过语音识别技术,实现实时转录医患对话,自动生成结构化数据,提高医疗效率。平台具备强大的环境降噪、语音分离及自然语言处理能力,支持与医院系统无缝集成,广泛应用于门诊记录、多学科会诊和急诊场景,显著提升工作效率和数据准确性。
|
4天前
|
消息中间件 编解码 开发者
深入解析 Flutter兼容鸿蒙next全体生态的横竖屏适配与多屏协作兼容架构
本文深入探讨了 Flutter 在屏幕适配、横竖屏切换及多屏协作方面的兼容架构。介绍了 Flutter 的响应式布局、逻辑像素、方向感知、LayoutBuilder 等工具,以及如何通过 StreamBuilder 和 Provider 实现多屏数据同步。结合实际应用场景,如移动办公和教育应用,展示了 Flutter 的强大功能和灵活性。
71 6
|
3天前
|
消息中间件 缓存 安全
Future与FutureTask源码解析,接口阻塞问题及解决方案
【11月更文挑战第5天】在Java开发中,多线程编程是提高系统并发性能和资源利用率的重要手段。然而,多线程编程也带来了诸如线程安全、死锁、接口阻塞等一系列复杂问题。本文将深度剖析多线程优化技巧、Future与FutureTask的源码、接口阻塞问题及解决方案,并通过具体业务场景和Java代码示例进行实战演示。
20 3
|
4天前
|
存储 SQL 缓存
AnalyticDB 实时数仓架构解析
AnalyticDB 是阿里云自研的 OLAP 数据库,广泛应用于行为分析、数据报表、金融风控等应用场景,可支持 100 trillion 行记录、10PB 量级的数据规模,亚秒级完成交互式分析查询。本文是对 《 AnalyticDB: Real-time OLAP Database System at Alibaba Cloud 》的学习总结。
17 1
|
6天前
|
监控 安全 Serverless
"揭秘D2终端大会热点技术:Serverless架构最佳实践全解析,让你的开发效率翻倍,迈向技术新高峰!"
【10月更文挑战第23天】D2终端大会汇聚了众多前沿技术,其中Serverless架构备受瞩目。它让开发者无需关注服务器管理,专注于业务逻辑,提高开发效率。本文介绍了选择合适平台、设计合理函数架构、优化性能及安全监控的最佳实践,助力开发者充分挖掘Serverless潜力,推动技术发展。
17 1
|
6天前
|
数据管理 Nacos 开发者
"Nacos架构深度解析:一篇文章带你掌握业务层四大核心功能,服务注册、配置管理、元数据与健康检查一网打尽!"
【10月更文挑战第23天】Nacos 是一个用于服务注册发现和配置管理的平台,支持动态服务发现、配置管理、元数据管理和健康检查。其业务层包括服务注册与发现、配置管理、元数据管理和健康检查四大核心功能。通过示例代码展示了如何在业务层中使用Nacos,帮助开发者构建高可用、动态扩展的微服务生态系统。
29 0
|
28天前
|
安全 应用服务中间件 网络安全
Tomcat如何配置PFX证书?
【10月更文挑战第2天】Tomcat如何配置PFX证书?
141 7
|
28天前
|
存储 算法 应用服务中间件
Tomcat如何配置JKS证书?
【10月更文挑战第2天】Tomcat如何配置JKS证书?
203 4

推荐镜像

更多