【SpringBoot】Spring Boot 内嵌 Web 服务器入门,一文讲明白 Tomcat 的功能、目标、工作流程
⭐
参考资料:Tomcat系列教材 (一)- 教程
概述
- 定义:一个开源 Java Web 应用服务器,实现了 Java Servlet、JavaServer Pages (JSP) 等 Java EE 规范,是最流行的轻量级应用服务器之一
- Java Servlet:运行在 Web 服务器上的 Java 程序,用于处理客户端请求和生成动态内容,是 Java Web 应用的核心组件
- JavaServer Pages:基于 Java 的服务器端网页开发技术,允许在 HTML 中嵌入 Java 代码,简化动态网页的开发
- 功能:监听目标 ip 和端口,使得服务调用者只需要将请求发送到 ip 对应的 端口,而无需关心对方是什么类型的服务
- 核心目标:解耦调用者(前端或网关)和服务器(后端),让双方可以
通过 http 方式进行通信
,而不需要关心对方是如何运作的 - 下载: Apache Tomcat® - Apache Tomcat 9 Software Downloads
- 名称来历:Tomcat是一种野外的猫科动物,不依赖人类,独立生活。 Tomcat的作者,取这个名字的初衷是希望,这一款服务器可以自力更生,自给自足,像Tomcat这样一种野生动物一般,不依赖其他插件,而可以独立达到提供 web 服务的效果
相关概念
Web 服务器
- 定义:处理 HTTP 请求而不执行具体业务代码的服务器
- 功能
- 处理静态资源:HTML、CSS、JS、图片等,可以提供前端页面
- 转发请求:作为反向代理,把动态请求转发给 Web 应用服务器(如 Tomcat、JBoss)
- 负载均衡:负责分配流量到多个 Web 应用服务器
Web 容器
- 定义:实际上就是后端服务器,属于 Web 应用服务器的一部分,但是不具备 HTTP 请求处理能力
- 功能:负责处理动态请求,运行和管理 Java Web 应用(Servlet、JSP),执行具体的业务代码
Web 应用服务器
- 定义:Application Server,是一个提供业务逻辑执行环境的服务器软件,Web 应用服务器 = Web 容器 + 企业级服务
- 企业级服务:事务管理、安全认证、数据库连接池、消息队列等高级功能
- 功能
- 管理和运行 Web 应用程序,处理并发请求和负载均衡
- 提供企业级服务和资源管理,确保应用程序的安全性和可靠性
主要功能
- 部署和运行 Java Web 应用:支持JSP页面和Servlet组件的执行,处理动态Web内容
- Web 容器:符合 JavaEE 规范,提供完整的 Web 容器环境,管理 Servlet 生命周期
- 请求处理:高效处理HTTP请求,支持会话管理和请求转发
- 开发支持:为Java Web应用提供完整的开发、测试和调试环境,支持热部署
组成部分(不是很重要,只想了解基本原理可以跳过)
- Coyote(HTTP 连接器)
- 定义:Tomcat 的 HTTP 处理器,负责监听端口(默认 8080)并解析 HTTP 请求
- 功能:解析 HTTP 请求头、处理 Keep-Alive 连接、将请求交给 Catalina 处理
- Jasper(JSP 解析引擎)
- 功能:Jasper 负责解析 JSP 页面,将 JSP 转换成 Java 类,交给 Catalina 执行
- JSP 运行流程
- Tomcat 解析 JSP 文件(
index.jsp
)。 - Jasper 将 JSP 转换为 Java Servlet 代码。
- 编译 Java 代码成 .class 文件,交由 Catalina 运行。
- Tomcat 解析 JSP 文件(
- Catalina(Servlet 容器)
- 定义:负责 Servlet 处理的核心组件,即 Tomcat 的 Web 容器
- 功能
- 负责管理多个 Web 应用(WAR 包),一个应用对应一个 ServletContext 实例,并通过 ServletContext 实例将接口暴露给 Web 应用
- 处理 web.xml 配置,管理 Web 应用的生命周期(启动、销毁)
- 处理 Servlet 及其映射,调用
HttpServlet
的doGet()
和doPost()
方法
- Apr(原生库优化)
- 定义:Tomcat 的原生优化库,用于提高性能和安全性,需要额外安装 tomcat-native 才能启用
- APR 适用场景
- 处理高并发请求时,APR 提供更快的 Socket 通信。
- SSL/TLS 加密时,APR 可以提高加密效率。
- 在 Linux 服务器 上,APR 通过 epoll 提高 IO 性能。
- Cluster(集群管理)
- 定义:Tomcat 提供的集群支持,允许多个 Tomcat 服务器共享 Session 数据,适用于多台 Tomcat 部署的场景
- 功能:用于负载均衡和 Session 复制,防止单点故障(Session 失效)
- High-Availability(高可用性)
- 定义:Tomcat 提供的故障转移能力(Failover)
- 功能:保证在某台 Tomcat 崩溃时,Session 依然可用,适用于大规模 Web 应用,防止单点故障
- WebApps(Web 应用管理)
-
定义:WebApps 目录是 Tomcat 部署 Web 应用的地方,支持热部署
-
默认 WebApps 目录结构
├── webapps│ ├── ROOT (默认 Web 应用)│ ├── myapp (用户自定义 Web 应用)│ ├── docs (Tomcat 文档)│ ├── manager (Tomcat 管理界面)│ ├── host-manager (多站点管理)
-
工作流程
- **客户端发起 HTTP 请求:**比如用户访问
http://localhost:8080/myapp/hello
-
Coyote 监听 HTTP 端口(如 8080),接收 HTTP 请求。
-
Coyote 解析 HTTP 请求并转换为
ServletRequest
对象,交给 Catalina 处理。 -
Catalina 解析请求的主机和路径,确定该请求应该交给哪个 Web 应用 处理。
-
Catalina 将请求交给对应的 Servlet 处理
在这个 Web 应用中,Catalina 会查看它的
web.xml
文件或者注解配置,找到匹配该请求路径的 Servlet如果路径是
/*
(或者某个具体的路径),而这个路径被映射到了DispatcherServlet
,那么 Catalina 就会把请求交给DispatcherServlet
处理。 -
Servlet 处理请求(若请求的是
/hello
这种 Servlet 路径),或者 Jasper 处理 JSP 页面(若请求的是/index.jsp
) -
Servlet 或 JSP 生成响应 并返回给 Catalina。
-
Catalina 通过 Coyote 将响应封装成 HTTP 响应 并返回给客户端。
#mermaid-svg-Rm7ffSwQjq3cOgXo {font-family:\"trebuchet ms\",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-Rm7ffSwQjq3cOgXo .error-icon{fill:#552222;}#mermaid-svg-Rm7ffSwQjq3cOgXo .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-Rm7ffSwQjq3cOgXo .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-Rm7ffSwQjq3cOgXo .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-Rm7ffSwQjq3cOgXo .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-Rm7ffSwQjq3cOgXo .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-Rm7ffSwQjq3cOgXo .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-Rm7ffSwQjq3cOgXo .marker{fill:#333333;stroke:#333333;}#mermaid-svg-Rm7ffSwQjq3cOgXo .marker.cross{stroke:#333333;}#mermaid-svg-Rm7ffSwQjq3cOgXo svg{font-family:\"trebuchet ms\",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-Rm7ffSwQjq3cOgXo .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-Rm7ffSwQjq3cOgXo text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-Rm7ffSwQjq3cOgXo .actor-line{stroke:grey;}#mermaid-svg-Rm7ffSwQjq3cOgXo .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-Rm7ffSwQjq3cOgXo .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-Rm7ffSwQjq3cOgXo #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-Rm7ffSwQjq3cOgXo .sequenceNumber{fill:white;}#mermaid-svg-Rm7ffSwQjq3cOgXo #sequencenumber{fill:#333;}#mermaid-svg-Rm7ffSwQjq3cOgXo #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-Rm7ffSwQjq3cOgXo .messageText{fill:#333;stroke:#333;}#mermaid-svg-Rm7ffSwQjq3cOgXo .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-Rm7ffSwQjq3cOgXo .labelText,#mermaid-svg-Rm7ffSwQjq3cOgXo .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-Rm7ffSwQjq3cOgXo .loopText,#mermaid-svg-Rm7ffSwQjq3cOgXo .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-Rm7ffSwQjq3cOgXo .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-Rm7ffSwQjq3cOgXo .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-Rm7ffSwQjq3cOgXo .noteText,#mermaid-svg-Rm7ffSwQjq3cOgXo .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-Rm7ffSwQjq3cOgXo .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-Rm7ffSwQjq3cOgXo .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-Rm7ffSwQjq3cOgXo .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-Rm7ffSwQjq3cOgXo .actorPopupMenu{position:absolute;}#mermaid-svg-Rm7ffSwQjq3cOgXo .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-Rm7ffSwQjq3cOgXo .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-Rm7ffSwQjq3cOgXo .actor-man circle,#mermaid-svg-Rm7ffSwQjq3cOgXo line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-Rm7ffSwQjq3cOgXo :root{--mermaid-font-family:\"trebuchet ms\",verdana,arial,sans-serif;} Client Coyote Catalina Web Application Servlet/JSP HTTP请求 监听8080端口 解析HTTP请求 转换为Request对象 解析请求路径 确定目标Web应用 调用Servlet处理 Jasper处理JSP alt [Servlet请求 (/hello)] [JSP请求 (/index.jsp)] 返回处理结果 传递响应 返回HTTP响应 Client Coyote Catalina Web Application Servlet/JSP
Tomcat 结构关系图
Server (顶层服务器)└── Service (服务) ├── Connector (连接器,监听 8081 端口) └── Engine (核心引擎,处理请求) └── Host (虚拟主机,如 localhost) └── Context (Web 应用上下文,路径为 \"\") └── DispatcherServlet (Spring MVC 的核心 Servlet,映射 /*)
客户端(如浏览器) ↓ HTTP 请求Tomcat (Catalina + Coyote) ↓ Connector (Coyote 实现了底层通信) ↓ Engine -> Host -> ContextDispatcherServlet (Spring MVC 的核心 Servlet) ↓ Spring ApplicationContext ↓ Controller (处理请求的 Bean) ↓ Service / Repository (业务逻辑层)
- Server:代表整个 Tomcat 服务器,是最顶层的容器对象
- Service:包含一个 Engine 和多个 Connector,负责对外提供服务
- Connector:连接器,负责接收请求并将请求转发给 Engine 处理
- Engine:引擎,负责处理 Connector 接收到的请求,是 Service 中的核心处理组件
- Host:虚拟主机,负责管理一个或多个 Context(Web 应用)
- Context:代表一个 Web 应用,管理 Servlet 容器和相关资源
- DispatcherServlet:Spring MVC 的核心组件,负责将请求分发给对应的处理器
Tomcat & Nginx
- 二者优势
- Nginx:擅长处理静态资源和高并发
- Tomcat:专注于处理Java动态请求和业务逻辑。
- 二者关系:在实际生产环境中,Nginx 和 Tomcat 常常结合使用,充分发挥两者的优势
- 合作方式:Nginx 作为前端服务器处理静态资源请求,并将动态请求转发给后端的 Tomcat 处理
常见架构
用户请求 → Nginx (Web 服务器) → Tomcat (Web 容器) 处理 Java 业务逻辑
#mermaid-svg-Mte8JpzHtUIWxgZZ {font-family:\"trebuchet ms\",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-Mte8JpzHtUIWxgZZ .error-icon{fill:#552222;}#mermaid-svg-Mte8JpzHtUIWxgZZ .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-Mte8JpzHtUIWxgZZ .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-Mte8JpzHtUIWxgZZ .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-Mte8JpzHtUIWxgZZ .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-Mte8JpzHtUIWxgZZ .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-Mte8JpzHtUIWxgZZ .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-Mte8JpzHtUIWxgZZ .marker{fill:#333333;stroke:#333333;}#mermaid-svg-Mte8JpzHtUIWxgZZ .marker.cross{stroke:#333333;}#mermaid-svg-Mte8JpzHtUIWxgZZ svg{font-family:\"trebuchet ms\",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-Mte8JpzHtUIWxgZZ .label{font-family:\"trebuchet ms\",verdana,arial,sans-serif;color:#333;}#mermaid-svg-Mte8JpzHtUIWxgZZ .cluster-label text{fill:#333;}#mermaid-svg-Mte8JpzHtUIWxgZZ .cluster-label span{color:#333;}#mermaid-svg-Mte8JpzHtUIWxgZZ .label text,#mermaid-svg-Mte8JpzHtUIWxgZZ span{fill:#333;color:#333;}#mermaid-svg-Mte8JpzHtUIWxgZZ .node rect,#mermaid-svg-Mte8JpzHtUIWxgZZ .node circle,#mermaid-svg-Mte8JpzHtUIWxgZZ .node ellipse,#mermaid-svg-Mte8JpzHtUIWxgZZ .node polygon,#mermaid-svg-Mte8JpzHtUIWxgZZ .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-Mte8JpzHtUIWxgZZ .node .label{text-align:center;}#mermaid-svg-Mte8JpzHtUIWxgZZ .node.clickable{cursor:pointer;}#mermaid-svg-Mte8JpzHtUIWxgZZ .arrowheadPath{fill:#333333;}#mermaid-svg-Mte8JpzHtUIWxgZZ .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-Mte8JpzHtUIWxgZZ .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-Mte8JpzHtUIWxgZZ .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-Mte8JpzHtUIWxgZZ .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-Mte8JpzHtUIWxgZZ .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-Mte8JpzHtUIWxgZZ .cluster text{fill:#333;}#mermaid-svg-Mte8JpzHtUIWxgZZ .cluster span{color:#333;}#mermaid-svg-Mte8JpzHtUIWxgZZ div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\"trebuchet ms\",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-Mte8JpzHtUIWxgZZ :root{--mermaid-font-family:\"trebuchet ms\",verdana,arial,sans-serif;} HTTP请求 静态资源请求 动态请求转发 处理Java业务逻辑 用户 Nginx 处理静态资源 Tomcat 返回处理结果