Tomcat 整体架构与启动流程:从 Server 到 Servlet 加载

刚接触 Java Web 时,我一直把 Tomcat 简单理解成"运行 Java 项目的服务器"。后来接触 Nginx、Apache HTTP Server,又看到 Tomcat 自己也能监听 8080 端口,几个概念很容易混在一起。

其实只要分清"谁负责接收请求"和"谁负责执行 Servlet",再顺着 Tomcat 的启动过程看一遍,它的整体结构并没有想象中复杂。

一、Tomcat、Apache 和 Nginx 有什么区别

这里所说的 Apache,一般是指 Apache HTTP Server,而不是整个 Apache 软件基金会。

Nginx 和 Apache HTTP Server 主要定位为 Web 服务器,擅长处理静态资源、反向代理、负载均衡和 HTTPS。Tomcat 则首先是一个 Servlet 容器,主要用于部署和运行 Java Web 应用。

简单对比如下:

对比项 Tomcat Nginx Apache HTTP Server
核心定位 Servlet 容器 Web 服务器、反向代理 Web 服务器
Java Servlet/JSP 原生支持 不直接支持 不直接支持
静态资源 可以处理,但不是主要优势 性能和并发能力较强 支持完善
反向代理 可以实现,但不常作为主要网关 非常常见 支持
常见场景 运行 Spring MVC、Servlet 应用 网关、负载均衡、静态资源 静态站点、模块化 Web 服务

Tomcat 本身也包含 HTTP Connector,所以它可以独立接收 HTTP 请求,并不是必须与 Nginx 搭配。开发环境中,我们直接访问 Spring Boot 的 8080 端口,本质上就是在访问内嵌 Tomcat。

生产环境经常采用下面的结构:

复制代码
浏览器 → Nginx → 多个 Tomcat 实例 → Java 应用

这样做并不是因为 Tomcat 无法提供 HTTP 服务,而是希望让 Nginx 负责域名、HTTPS、静态资源、限流和负载均衡,Tomcat 专心运行 Java 业务。

二、Tomcat 的启动过程

我们在 Linux 中通常执行:

复制代码
bin/startup.sh

Windows 中对应的是 startup.bat。脚本的主要作用是准备环境变量和 JVM 参数,随后调用 catalina.sh start,最终启动 Java 入口类:

复制代码
org.apache.catalina.startup.Bootstrap.main(args)

Tomcat 的启动过程可以概括为下面几步。

1. 脚本准备运行环境

2. Bootstrap 创建类加载器

3. Catalina 解析 server.xml

下面是一段简化配置:

复制代码
<Server port="8005" shutdown="SHUTDOWN">
    <Service name="Catalina">
        <Connector port="8080" protocol="HTTP/1.1" />
        <Engine name="Catalina" defaultHost="localhost">
            <Host name="localhost" appBase="webapps" />
        </Engine>
    </Service>
</Server>

4. 初始化和启动各级组件

复制代码
启动脚本 → Bootstrap → Catalina → 解析 server.xml
        → 创建组件 → 初始化组件 → 启动组件 → 监听请求

三、Tomcat 的整体分层架构

Tomcat 的核心架构中,最常见的四个名称是 Server、Service、Connector 和 Container。

Server:代表整个 Tomcat

Server 是 server.xml 的最外层元素,代表整个 Catalina Servlet 容器。一个 Tomcat 实例通常只有一个 Server,其中可以包含多个 Service。

Service:连接网络层和容器层

Service 不是直接处理业务的组件,它更像一个组合层:一个 Service 可以包含多个 Connector,但通常只关联一个 Engine。

例如 HTTP 端口 8080 和 HTTPS 端口 8443 可以使用两个 Connector,最后把请求交给同一个 Engine,这样两种入口可以共享同一批 Web 应用。

Connector:负责网络和协议

Connector 负责监听端口、接收连接、解析 HTTP 或 AJP 协议,并把网络请求转换成 Tomcat 内部能够处理的 Request。业务处理完成后,它还负责把 Response 写回客户端。

Connector 解决的是"请求怎么进来、响应怎么出去",并不负责判断最终调用哪个 Servlet。

Container:负责找到并执行 Servlet

Container 负责请求在 Servlet 容器内部的处理。它还可以继续分为四层:

复制代码
Engine
└── Host
    └── Context
        └── Wrapper
  • Engine:处理当前 Service 中所有 Connector 转交的请求;

  • Host:代表一个虚拟主机,例如 www.example.com;

  • Context:代表一个 Web 应用,例如 /shop;

  • Wrapper:代表一个具体 Servlet,例如 Spring MVC 的 DispatcherServlet。

假设访问 http://localhost:8080/shop/order/list,Connector 先接收并解析请求,Engine 再找到 localhost 对应的 Host,Host 根据 /shop 找到 Context,最后由 Wrapper 调用对应的 Servlet。

可以把整体关系简单记为:Server 管整个 Tomcat,Service 组合入口与容器,Connector 处理网络,Container 执行业务请求。

四、load-on-startup 有什么作用

在传统 Java Web 项目的 web.xml 中,可以通过 <load-on-startup> 控制 Servlet 的创建时机:

复制代码
<servlet>
    <servlet-name>initServlet</servlet-name>
    <servlet-class>com.example.InitServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>

如果配置的是非负整数,Tomcat 会在 Web 应用启动阶段创建 Servlet,并调用它的 init() 方法,而不是等第一次请求到来时才初始化。

多个 Servlet 都配置了 load-on-startup 时,数值较小的会优先加载。例如,值为 1 的 Servlet 通常早于值为 5 的 Servlet;相同数值之间的先后顺序不应依赖。如果配置负数或者没有配置,一般会在第一次请求匹配到该 Servlet 时再创建。

使用注解也能达到同样效果:

复制代码
@WebServlet(urlPatterns = "/init", loadOnStartup = 1)
public class InitServlet extends HttpServlet {
    @Override
    public void init() {
        System.out.println("应用启动时完成初始化");
    }
}

它常用于提前初始化必要资源,让第一次请求不用承担初始化耗时。不过,不建议把大量数据加载、长时间远程调用或者不稳定任务全部放进 init()。一旦初始化抛出异常,Servlet 可能不可用,甚至影响应用正常启动。

在 Spring Boot 项目中,我们很少直接配置 Servlet 的 load-on-startup,但它并没有消失。Spring MVC 的 DispatcherServlet 同样由 Servlet 容器管理,只是大部分注册工作由 Spring Boot 自动配置完成。

参考资料

相关推荐
天空属于哈夫克34 天前
企业微信二次开发:精准实现关键词自动回复
架构·企业微信
晨米酱4 天前
AGENTS.md:Agent 的上下文策略层
面试·架构·agent
这个DBA有点耶4 天前
MVCC深入:Read View、版本链与快照读——InnoDB并发控制的内核
数据库·mysql·架构
码流子4 天前
高速公路安全监测实践:碰撞监测预警+物联网底座,从感知到处置的闭环
大数据·人工智能·物联网·算法·架构
moMo4 天前
从固定流程到问题路由:让 LangGraph RAG 按需检索
架构
白远山4 天前
上海24小时自助健身房解决方案实战指南与经验分享
java·数据库·架构·需求分析
LorryJovens4 天前
【LAAP科研】双系统具身AGI范式研究——基于LAAP认知架构与Jev概率决策模型的系统性技术调研与范式验证
人工智能·gpt·安全·架构
需要8264 天前
JVM 内存区域与对象创建:一次 GC 从哪来
java·jvm·spring boot·spring·servlet·tomcat
JQweryuiop4 天前
中小型游戏陪练工作室数字化管理实践:基于七彩屋电竞护航小程序订单、履约与绩效系统的落地复盘
大数据·游戏·小程序·架构
LONGZETECH4 天前
一线职教实测:风光 580 汽车故障诊断仿真系统,破解实车实训四大核心痛点
人工智能·学习·安全·架构·汽车