Web 容器与 Tomcat 核心知识总结(李号双课程笔记)

本文整理自李号双《深入拆解 Tomcat & Jetty》专栏第 1-3 讲核心内容,聚焦 Web 容器本质、Servlet 规范及 Tomcat 架构设计,适合 Java 后端开发者夯实基础、突破技术深度。

一、课程核心定位

本课程以Tomcat、Jetty两大 Web 容器为核心,通过剖析开源系统的设计精髓,帮助开发者打通 “基础→框架→架构” 的知识链路,解决 “仅会用框架、不懂底层原理” 的痛点,为成长为高级程序员 / 架构师提供技术支撑。

二、Web 容器基础:是什么与为什么

1. Web 容器的由来(技术演进视角)

Web 容器的出现是为了解决 “静态 Web→动态 Web” 的需求升级,具体演进路径如下表:

阶段

核心技术

局限性

解决方案

早期 Web

HTTP 服务器(Apache、Nginx)

仅能返回静态 HTML,无交互能力

-

动态需求兴起

Servlet 技术(服务端 Java 小程序)

Servlet 无main方法,无法独立运行

引入Servlet 容器(管理 Servlet 的创建、调用、销毁)

易用性优化

“HTTP 服务器 + Servlet 容器” 组合

简化部署流程,降低使用门槛

形成Web 容器(Tomcat、Jetty 的本质)

2. Web 容器的核心定义

  • 本质:“HTTP 服务器 + Servlet 容器” 的结合体,兼具两大能力:
    1. 解析 HTTP 协议(接收浏览器请求、返回响应结果);
    1. 管理 Servlet 生命周期(实例化、调用service方法、销毁)。
  • 轻量级 vs 重量级对比

类型

代表产品

核心能力

适用场景

轻量级

Tomcat、Jetty

仅含 Servlet 容器,支持 Servlet 4.0 规范

微服务架构(Spring Boot 默认嵌入式容器)

重量级

JBoss、WebLogic

含 Servlet 容器 + EJB 容器,支持完整 Java EE 规范

传统单体应用(需复杂企业级特性)

  • 微服务适配性:轻量级容器因低资源消耗(内存 / CPU 占用少)、支持嵌入式启动(应用启动容器,而非容器部署应用),成为微服务架构的首选。

三、Servlet 规范:Web 容器的 “通信协议”

Servlet 规范是 Web 容器(如 Tomcat)与业务类(Servlet)的交互标准,核心解决 “HTTP 服务器与业务逻辑解耦” 的问题。

1. 核心组件与作用

(1)Servlet 接口:业务类的 “标准模板”

Servlet 接口定义了 5 个核心方法,强制规范业务类的实现逻辑:

 

public interface Servlet {

// 初始化(加载资源,仅调用1次)

void init(ServletConfig config) throws ServletException;

// 获取初始化参数(如web.xml中配置的参数)

ServletConfig getServletConfig();

// 核心方法:处理请求(每次请求调用1次)

void service(ServletRequest req, ServletResponse res) throws ServletException, IOException;

// 获取Servlet信息(如版本、作者)

String getServletInfo();

// 销毁(释放资源,仅调用1次)

void destroy();

}

  • 关键方法:service()是业务逻辑的核心实现处,其中:
    • ServletRequest:封装请求信息(如 URL 路径、请求参数、Cookie、HTTP 头);
    • ServletResponse:封装响应信息(如返回 HTML 内容、设置响应头、指定编码)。
  • 简化实现方式:通过继承抽象类减少重复代码:
    • GenericServlet:实现 Servlet 接口的通用逻辑(如getServletConfig()),仅需子类重写service();
    • HttpServlet:HTTP 场景专用抽象类(继承GenericServlet),将service()方法拆分为doGet()/doPost(),开发者仅需重写对应方法(无需处理请求方法判断)。
(2)Servlet 容器:规范的 “执行者”
  • 核心职责
    1. 加载 Web 应用(解析web.xml或注解配置);
    1. 管理 Servlet 生命周期(根据请求创建 Servlet 实例、调用方法);
    1. 转发请求(将 HTTP 请求传递给对应的 Servlet 处理)。
  • 解耦逻辑:HTTP 服务器不直接调用业务类,而是将请求交给 Servlet 容器,容器通过 Servlet 接口调用业务逻辑 —— 避免服务器代码与业务代码耦合(新增业务无需修改服务器代码)。
(3)Web 应用目录结构:规范的 “部署格式”

Web 应用需按固定结构部署,确保容器能识别并加载 Servlet,标准结构如下:

 

MyWebApp/ # Web应用根目录(访问时需指定此名称)

├─ WEB-INF/ # 核心配置目录(外界无法直接访问,安全隔离)

│ ├─ web.xml # 配置文件(Servlet映射、Filter、Listener、初始化参数)

│ ├─ classes/ # 业务类目录(Servlet类、工具类、实体类等)

│ └─ lib/ # 依赖JAR包目录(如Servlet API、Spring、MyBatis等)

└─ META-INF/ # 应用元信息目录(如MANIFEST.MF,描述应用信息)

(4)扩展机制:Filter 与 Listener

Servlet 规范提供两种扩展机制,满足个性化需求:

  • Filter(过滤器)
    • 作用:统一处理请求 / 响应(如权限校验、字符编码设置、日志记录);
    • 原理:通过FilterChain链式调用,多个 Filter 按配置顺序执行;
    • 场景:登录校验(未登录则跳转登录页)、统一设置UTF-8编码。
  • Listener(监听器)
    • 作用:监听容器事件(如 Web 应用启动 / 停止、Session 创建 / 销毁),触发自定义逻辑;
    • 场景:Spring 框架通过ContextLoaderListener,在 Web 应用启动时初始化 Spring 容器。

2. 手动实现 Servlet:从 0 到 1 实践

以 “返回 Hello Servlet” 为例,演示 Servlet 的开发、编译、部署全流程:

步骤 1:编写 Servlet 类(继承 HttpServlet)
 

import javax.servlet.annotation.WebServlet;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import java.io.IOException;

import java.io.PrintWriter;

// 注解配置:指定Servlet映射路径(Servlet 3.0+支持,无需web.xml)

@WebServlet("/myServlet")

public class MyServlet extends HttpServlet {

// 处理GET请求

@Override

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {

// 设置响应内容类型及编码(避免中文乱码)

resp.setContentType("text/html;charset=utf-8");

// 获取输出流,返回HTML内容

PrintWriter out = resp.getWriter();

out.println("<h1>Hello Servlet!</h1>");

out.println("<p>这是手动实现的第一个Servlet</p>");

}

}

步骤 2:编译 Servlet 类
  • 依赖:需引入 Tomcat 的lib/servlet-api.jar(提供 Servlet 接口);
  • 编译命令(Windows/Linux 通用):
 

javac -cp ./servlet-api.jar MyServlet.java

  • 结果:生成MyServlet.class字节码文件。
步骤 3:部署到 Tomcat
  1. 在 Tomcat 的webapps目录下,创建MyWebApp/WEB-INF/classes目录;
  1. 将MyServlet.class放入classes目录;
  1. (注解方式无需此步)若用web.xml配置,需在WEB-INF下创建web.xml,配置如下:
 

<?xml version="1.0" encoding="UTF-8"?>

<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" version="4.0">

<servlet>

<servlet-name>myServlet</servlet-name>

<servlet-class>MyServlet</servlet-class>

</servlet>

<servlet-mapping>

<servlet-name>myServlet</servlet-name>

<url-pattern>/myServlet</url-pattern>

</servlet-mapping>

</web-app>

步骤 4:启动与访问
  1. 启动 Tomcat:执行Tomcat/bin/startup.bat(Windows)或startup.sh(Linux);
  1. 访问地址:http://localhost:8080/MyWebApp/myServlet
  1. 预期结果:页面显示 “Hello Servlet!” 及后续内容。

四、Tomcat 架构:核心组件与工作原理

Tomcat 的设计围绕 “处理请求” 与 “管理 Servlet” 两大核心,通过模块化拆分实现 “高内聚、低耦合”。

1. 总体架构:从顶层到核心

Tomcat 的顶层组件层级关系如下,每个组件各司其职:

 

Server(Tomcat实例) → Service(服务单元) → [多个Connector(连接器) + 1个Container(容器)]

  • Server:整个 Tomcat 实例,可包含多个 Service(如同时提供 HTTP 和 AJP 服务);
  • Service:逻辑上的 “服务单元”,仅负责将 Connector 与 Container 绑定(无实际业务逻辑);
  • Connector:对外 “通信窗口”—— 处理 Socket 连接、解析 HTTP/AJP 协议,将字节流转为ServletRequest;
  • Container:对内 “业务处理器”—— 管理 Servlet,处理请求并生成ServletResponse。

2. Connector:连接器的 “三层架构”

Connector 通过 3 个组件实现 “通信→协议解析→请求转换” 的全流程,屏蔽 I/O 模型与协议的差异,确保 Container 无需关注底层通信细节:

组件

核心职责

关键特性

EndPoint

底层通信(TCP/IP 协议)

1. 监听指定端口(如 8080)、接收 Socket 连接;2. 支持多种 I/O 模型(NIO、NIO2、APR);3. 含 Acceptor(监听连接)、SocketProcessor(处理连接,提交线程池)。

Processor

应用层协议解析

1. 解析 HTTP/AJP 协议(如解析请求行、请求头);2. 将字节流转为 Tomcat 内部Request对象;3. 支持多种协议(HTTP/1.1、HTTP2、AJP)。

Adapter(CoyoteAdapter)

请求格式转换

1. 将 Tomcat 内部Request转为 Servlet 规范的ServletRequest;2. 调用 Container 的service方法处理请求;3. 适配器模式的典型应用(解决 Connector 与 Container 的接口差异)。

3. Container:容器的 “四层结构”

Container 采用组合模式,通过四层容器实现 “精细化管理 Servlet”,支持多虚拟主机、多 Web 应用的部署:

 

Engine(引擎) → Host(虚拟主机) → Context(Web应用) → Wrapper(Servlet)

  • 各层容器作用

容器层级

核心作用

示例

Engine

顶级容器,管理多个 Host(一个 Service 对应一个 Engine)

Tomcat 默认 Engine:Catalina

Host

虚拟主机(对应一个域名),管理多个 Context

域名manage.shopping.com、user.shopping.com

Context

Web 应用(对应一个 Web 应用目录),管理多个 Wrapper

应用/order(订单系统)、/search(搜索系统)

Wrapper

最小容器,对应一个 Servlet(每个 Servlet 对应一个 Wrapper)

MyServlet、LoginServlet

4. 请求处理全流程

以 “用户访问http://user.shopping.com:8080/order/buy” 为例,Tomcat 的请求处理流程如下:

  1. 定位容器:Mapper 组件通过 URL 解析,定位到目标 Wrapper:
    • 端口8080→确定 Connector(HTTP 连接器)→确定 Service→确定 Engine;
    • 路径/order→确定 Context(order对应的 Web 应用);
    • 路径/buy→确定 Wrapper(buy对应的 Servlet)。
  1. 链式调用(Pipeline-Valve)
    • 每个容器(Engine/Host/Context/Wrapper)都有一个Pipeline(管道),Pipeline中维护Valve(阀门)链表;
    • Valve分为两类:
      • 自定义 Valve:实现通用逻辑(如日志记录、权限校验);
      • BasicValve:每个 Pipeline 的 “收尾 Valve”,负责调用下一层容器的 Pipeline。
    • 调用顺序:Engine Pipeline → Host Pipeline → Context Pipeline → Wrapper Pipeline。
  1. 最终处理:Wrapper 的 BasicValve 创建 Filter 链,调用 Servlet 的service方法,生成响应并返回给浏览器。

五、Web 容器学习路径:打好基础是关键

课程强调 “先夯实基础,再深入源码”,核心基础分为三类,缺一不可:

1. 操作系统基础(核心)

  • 必学内容
    • 进程 / 线程、内核空间 / 用户空间、线程同步;
    • I/O 模型(阻塞 / 非阻塞、同步 / 异步);
    • 网络协议(TCP/IP、UDP、HTTP、OSI 七层模型);
    • 虚拟内存、内存分配。
  • 推荐书籍:《UNIX 环境高级编程》(APUE)。

2. Java 语言基础(核心)

  • 必学内容
    • 面向对象(封装、继承、多态、接口、抽象类);
    • Java I/O(字节流 / 字符流、NIO);
    • 多线程(线程池、并发容器、原子类、锁机制);
    • JVM(类加载机制、内存模型、GC 原理、本地内存);
    • Java 网络编程(BIO、NIO、AIO)。
  • 推荐书籍
    • 《Java 核心技术》(卷 1 / 卷 2);
    • 《深入理解 Java 虚拟机》(周志明);
    • 《Java 并发编程实战》。

3. Java Web 基础(核心)

  • 必学内容
    • Servlet 规范(Servlet、Filter、Listener);
    • Web 应用工作原理(请求 / 响应流程);
    • 设计模式(适配器、责任链、组合、模板方法);
    • 关键认知:Web 框架(如 Spring)是对 Servlet 的封装,理解 Servlet 容器是掌握框架原理的前提。

六、核心思考题与答案

思考题:Tomcat 的 Context 与 ServletContext、Spring 的 ApplicationContext 有什么区别?

概念

归属

核心作用

生命周期

Tomcat Context

Tomcat 容器组件

管理 Web 应用的 Servlet、资源(如 JSP、静态文件),是 Tomcat 内部的容器实例

与 Web 应用一致(部署时创建,卸载时销毁)

ServletContext

Servlet 规范接口

提供 Web 应用的全局配置(如获取初始化参数、共享全局数据、访问资源),是 Web 应用的 “全局上下文”

与 Web 应用一致(Web 应用启动时创建,停止时销毁)

Spring ApplicationContext

Spring 框架容器

管理 Spring Bean 的创建、依赖注入、生命周期,是 Spring 应用的 “核心上下文”

由 Spring 监听器(如ContextLoaderListener)触发创建,Web 应用停止时销毁

  • 关联关系:Spring 的ApplicationContext依赖ServletContext—— 通过ServletContext获取 Web 应用的配置信息,在 Web 应用启动时初始化。

七、总结

  1. Web 容器本质:Tomcat/Jetty 是 “HTTP 服务器 + Servlet 容器” 的结合体,核心解决 “动态请求处理” 与 “微服务适配”;
  1. Servlet 规范是基石:定义了容器与业务类的交互标准,Filter/Listener 提供灵活的扩展能力;
  1. Tomcat 架构精髓:通过 Connector 与 Container 解耦 “通信” 与 “业务”,通过分层组件实现高灵活性与可扩展性;
  1. 学习建议:先掌握 OS/Java/Web 基础,再从 “手动实现 Servlet” 入手,逐步深入 Tomcat 源码,理解设计模式的实际应用 —— 只有打通底层原理,才能在框架迭代中保持技术竞争力。

转载说明:本文整理自李号双《深入拆解 Tomcat & Jetty》专栏,如需转载,请注明原文出处及作者。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐