Tomcat

一、Tomcat 基础认知

1. 核心概念

Tomcat 是 Apache 软件基金会旗下开源、轻量级的 Java Web 服务器与 Servlet 容器 ,核心价值是实现 Java EE 规范中的 Servlet 规范JSP 规范,是中小型 Java Web 应用部署的标准载体,也可作为大型架构中动态资源的处理节点(与 Nginx 配合实现动静分离)。

1.1 核心定位与核心属性

属性 核心说明
角色定位 既是Web 服务器 (处理静态资源请求),也是Servlet 容器(运行 Java 动态代码),是 Java Web 应用的运行基座
规范实现 实现 Servlet 3.x/4.x/5.x 与 JSP 2.x/3.x 规范,兼容主流 Java 开发框架(Spring MVC、Struts 等)
轻量化特性 体积小、部署简单、资源占用低,支持热部署,适合开发测试与中小规模生产环境
架构适配 常与 Nginx 配合使用:Nginx 处理静态资源、反向代理,Tomcat 专注处理动态 Java 请求

1.2 Tomcat 核心容器架构

Tomcat 的核心架构以分层容器为核心,容器间呈父子包含关系,决定了请求的处理路径与部署逻辑,是理解 Tomcat 运行机制的关键:

容器层级 名称 核心作用 配置载体 核心特点
顶层容器 Server 代表整个 Tomcat 实例,包含一个或多个 Service server.xml<Server> 标签 负责 Tomcat 启动 / 关闭,监听关闭信号(如 SHUTDOWN 端口)
服务容器 Service 关联一个 Engine 和多个 Connector,实现 "连接处理" 与 "请求处理" 的解耦 server.xml<Service> 标签 一个 Service 对应一套独立的 "连接 - 处理" 体系,支持多端口监听
引擎容器 Engine 处理 Service 下所有 Connector 接收的请求,是请求处理的核心引擎 server.xml<Engine> 标签 包含多个 Host,负责将请求路由到对应虚拟主机(Host)
主机容器 Host 代表一个虚拟主机(域名),包含多个 Web 应用(Context) server.xml<Host> 标签 配置域名映射,管理该域名下的所有 Web 应用部署
应用容器 Context 代表一个独立的 Java Web 应用,是最小的部署单元 server.xmlcontext.xml 对应 webapps 下的一个应用目录,处理该应用的所有请求

1.3 核心功能组件

容器架构的运行依赖核心功能组件的协作,核心组件及作用如下:

组件 核心职责 关键说明
Connector(连接器) 接收客户端请求,封装请求数据,转发至 Engine 监听指定端口(如 8080),支持 HTTP/HTTPS/AJP 协议,是 Tomcat 与客户端的通信入口
Servlet 容器 运行 Servlet 类,处理动态请求,生成响应 是 Tomcat 的核心能力,负责 Servlet 的实例化、初始化、执行与销毁,遵循 Servlet 生命周期
JSP 引擎(Jasper) 编译 JSP 页面为 Servlet 类 将 JSP 代码转换为 Java 源码并编译为 class 文件,后续按 Servlet 逻辑执行
Executor(线程池) 管理请求处理线程,优化性能 统一管理线程资源,避免频繁创建销毁线程,是 Tomcat 性能调优的核心节点
Realm(域) 身份认证与权限控制 实现用户认证(如用户名密码校验),支持内存、数据库、LDAP 等多种认证方式

1.4 Tomcat 关键目录结构(核心部署基础)

Tomcat 以解压包形式部署,核心目录的功能是配置、部署、日志与运行的基础,所有操作均围绕这些目录展开:

目录名称 核心功能 关键文件 / 内容
bin 启动 / 关闭脚本目录 startup.sh/startup.bat(启动)、shutdown.sh/shutdown.bat(关闭)、catalina.sh(核心运行脚本)
conf 核心配置目录 server.xml(容器架构配置)、web.xml(全局 Web 应用配置)、context.xml(应用上下文配置)、tomcat-users.xml(用户认证配置)
lib 依赖库目录 Tomcat 核心 Jar 包、第三方依赖 Jar 包(所有 Web 应用共享)
webapps 应用部署目录 存放 Web 应用(WAR 包或解压目录),Tomcat 启动时自动部署该目录下的应用
logs 日志目录 catalina.out(核心运行日志)、localhost_access_log.*.txt(访问日志)、localhost.log(本地主机日志)
work 工作目录 存放 JSP 编译后的 Servlet 源码与 class 文件,重启 Tomcat 可删除该目录清理编译缓存
temp 临时文件目录 Tomcat 运行时生成的临时文件,重启后自动清理

1.5 Tomcat 核心运行模式(性能核心维度)

Tomcat 的 Connector 支持三种 I/O 运行模式,直接决定并发处理能力与资源占用,是性能调优的首要选择:

运行模式 全称 核心特点 并发能力 适用场景
BIO Blocking I/O(阻塞 I/O) 一个请求占用一个线程,线程阻塞等待响应,资源利用率低 低(适合低并发场景) 开发测试环境,老旧系统兼容
NIO Non-Blocking I/O(非阻塞 I/O) 基于多路复用技术,一个线程处理多个请求,非阻塞等待 中高(Tomcat 8+ 默认模式) 生产环境主流选择,适配中高并发
AIO Asynchronous I/O(异步 I/O) 基于异步事件驱动,请求处理完全异步,线程无等待 高(需操作系统支持) 超高并发场景,Linux 环境下推荐

2. 核心应用场景

1. 独立部署 Java Web 应用

  • 适用场景:中小型企业官网、内部 OA 系统、电商后台、教学演示等轻量级 Java Web 项目。
  • 架构特点 :直接将 WAR 包或解压后的应用部署到 webapps 目录,Tomcat 作为唯一的 Web 服务器,同时处理静态资源(HTML/CSS/JS)和动态请求(Servlet/JSP)。
  • 核心优势:部署流程极简、资源占用低,无需额外依赖,适合快速上线和轻量业务场景。

2. 与 Nginx 配合实现动静分离

  • 适用场景:中大型 Web 项目(如电商平台、内容门户、SaaS 服务),对静态资源访问速度和并发能力有较高要求。
  • 架构特点
    • Nginx 监听 80/443 端口,负责处理静态资源(图片、CSS、JS、静态 HTML),并提供 HTTPS 加密、缓存优化等能力;
    • 动态请求(如 JSP、Servlet 接口)通过反向代理转发到后端 Tomcat 集群(8080 端口);
    • 可配合负载均衡策略(轮询、加权轮询)分发请求到多台 Tomcat 节点。
  • 核心优势:大幅减轻 Tomcat 的静态资源处理压力,提升整体并发能力与响应速度,同时实现服务解耦与高可用。

3. 微服务架构中的应用容器

  • 适用场景:Spring Boot / Spring Cloud 微服务项目,以及云原生应用部署。
  • 架构特点
    • 微服务应用以可执行 JAR 包形式打包,内嵌 Tomcat(或其他 Servlet 容器),独立部署;
    • 每个微服务对应一个独立的 Tomcat 实例,通过服务注册中心(如 Nacos、Eureka)实现服务发现与治理;
    • 可容器化部署(Docker/K8s),实现弹性扩缩容。
  • 核心优势:轻量化、独立部署、便于扩展,完美适配微服务的分布式架构理念。

4. 开发与测试环境的轻量级服务器

  • 适用场景:开发调试、单元测试、集成测试、教学实验等场景。
  • 架构特点
    • 开发工具(如 IntelliJ IDEA、Eclipse)可直接内嵌 Tomcat,一键启动应用;
    • 本地部署 Tomcat,快速部署测试代码,支持热部署(修改代码后无需重启服务)。
  • 核心优势:启动速度快、配置灵活,大幅提升开发与测试效率,是 Java 开发者的 "标配工具"。

5. 高可用集群部署

  • 适用场景:对可用性和并发能力要求极高的生产环境(如大型电商、金融交易系统、政务平台)。
  • 架构特点
    • 多台 Tomcat 节点组成集群,前端通过负载均衡器(Nginx、HAProxy、LVS)分发请求;
    • 通过 Session 共享方案(如 Redis、Memcached)实现跨节点会话同步;
    • 配合 Keepalived 等工具实现负载均衡器的高可用,避免单点故障。
  • 核心优势:消除单点故障,提升系统并发承载能力,保障服务 7×24 小时稳定运行。

6. 传统企业级应用的 Servlet 容器

  • 适用场景:遗留 Java EE 应用(如基于 Struts、EJB 的企业级系统),以及对 Servlet/JSP 规范兼容性要求高的项目。
  • 架构特点:Tomcat 作为核心 Servlet 容器,部署传统企业级应用,兼容旧版 Java EE 规范,支持 JNDI、JDBC 资源池等企业级特性。
  • 核心优势:稳定可靠、生态成熟,保护企业在传统应用上的技术投资,同时可逐步向微服务架构演进。

二、实验:Tomcat 单机安装与部署

1. 实验步骤

1.1 安装 JDK 环境(Tomcat 运行依赖)

Tomcat 是 Java 开发的程序,必须先安装 Java 运行环境,此处选择开源的 OpenJDK 1.8:

复制代码
yum install java-1.8.0-openjdk.x86_64 -y

安装完成后可通过 java -version 验证,输出 1.8.0 版本信息即表示安装成功。

1.2 下载 Tomcat 安装包并解压

从 Apache 官方源下载 Tomcat 9.0.107 压缩包,解压到 /usr/local 目录并简化目录名:

复制代码
# 下载安装包
wget https://dlcdn.apache.org/tomcat/tomcat-9/v9.0.115/bin/apache-tomcat-9.0.107.tar.gz
# 解压到 /usr/local 目录
tar zxf apache-tomcat-9.0.107.tar.gz  -C /usr/local
# 进入 /usr/local 并重命名,简化后续操作
cd /usr/local/
mv apache-tomcat-9.0.107/ tomcat

1.3 临时启动 Tomcat 并验证启动状态

通过 bin 目录下的脚本启动 Tomcat,并检查默认 8080 端口的监听状态:

复制代码
# 进入 Tomcat 启动脚本目录
cd tomcat/bin/
# 启动 Tomcat
./startup.sh
# 验证 8080 端口监听(Tomcat 默认服务端口)
netstat -antlupe | grep 8080

启动成功标识:执行 ./startup.sh 后输出 Tomcat started.;netstat 命令输出包含 :::8080 的 LISTEN 状态。

1.4 配置 Tomcat 系统服务

临时启动仅适用于测试,配置 systemd 系统服务可实现 Tomcat 开机自启、便捷的启停管理,步骤如下:

重载系统服务并设置 Tomcat 开机自启,验证服务状态:

复制代码
# 创建 Tomcat 环境配置文件,指定 JAVA_HOME 路径
vim /usr/local/tomcat/conf/tomcat.conf
# 写入以下内容并保存
JAVA_HOME=/etc/alternatives/jre


# 创建 systemd 服务文件 /lib/systemd/system/tomcat.service
vim /lib/systemd/system/tomcat.service
# 写入以下完整配置
[Unit]
Description=Tomcat
After=syslog.target network.target

[Service]
Type=forking
EnvironmentFile=/usr/local/tomcat/conf/tomcat.conf
ExecStart=/usr/local/tomcat/bin/startup.sh
ExecStop=/usr/local/tomcat/bin/shutdown.sh
PrivateTmp=true
User=tomcat
Group=tomcat

[Install]
WantedBy=multi-user.target


# 创建 Tomcat 专用用户
# 创建无登录权限的 tomcat 用户和用户组
useradd  -s /sbin/nologin -M tomcat
# 为 tomcat 用户授权 Tomcat 整个目录
chown  tomcat.tomcat /usr/local/tomcat/ -R


# 重载系统服务并设置 Tomcat 开机自启,验证服务状态:
# 重载 systemd 配置,使新服务生效
systemctl daemon-reload
# 启动 Tomcat 并设置开机自启
systemctl enable --now tomcat
# 验证 Tomcat 相关端口监听
netstat -antlupe | grep java

服务配置成功标识netstat 命令输出 8080(服务端口)和 8005(管理端口)的 LISTEN 状态。

2. 实验结果

  1. 核心总结
核心知识点 核心风险 实操落地步骤 关键注意事项
Tomcat 运行强依赖 JDK,需配置正确 JAVA_HOME 配置错误会导致 Tomcat 启动失败,抛出JAVA_HOME not set类异常 1. 安装对应版本 JDK(Tomcat 9 + 推荐 JDK 8/11);2. 配置环境变量:echo "export JAVA_HOME=/usr/local/jdk1.8.0_381" >> /etc/profile``echo "export PATH=\$JAVA_HOME/bin:\$PATH" >> /etc/profile3. 生效配置:source /etc/profile4. 验证:java -versionecho $JAVA_HOME 1. JDK 版本需与 Tomcat 兼容(如 Tomcat 10 不兼容 JDK 7);2. 避免配置为JRE_HOME,Tomcat 运行需完整 JDK
临时启停脚本(startup.sh/shutdown.sh)存在服务中断风险 关闭终端、服务器重启后,Tomcat 进程会终止,服务不可用 方案:将 Tomcat 注册为系统服务,实现开机自启与后台运行:1. 创建服务文件:vi /usr/lib/systemd/system/tomcat.service2. 写入配置(见下文);3. 重载服务:systemctl daemon-reload4. 启动并开机自启:systemctl start tomcat && systemctl enable tomcat 注册系统服务后,禁止再使用临时脚本启停,避免进程冲突
禁止 root 用户运行 Tomcat,需创建专用用户 root 运行会大幅提升服务器安全风险(如被攻击后获取系统最高权限) 1. 创建用户组与用户:groupadd tomcat``useradd -g tomcat -m -d /home/tomcat tomcat2. 授权 Tomcat 目录:chown -R tomcat:tomcat /usr/local/tomcat3. 以 tomcat 用户运行:su - tomcat -c "/usr/local/tomcat/bin/startup.sh" 专用用户仅需 Tomcat 目录的读写执行权限,无需系统管理员权限
Tomcat 默认占用 8080 端口,端口冲突需修改配置 端口被占用会导致 Tomcat 启动失败,日志提示Address already in use 1. 查找占用端口的进程:`ss -tulnp grep 8080<br>2. 修改端口配置:编辑conf/server.xml,修改<Connector>标签的port属性:<br><Connector port="8081" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />`3. 重启 Tomcat 生效 1. 避免修改为系统保留端口(1-1024),普通用户运行需用 1024 以上端口;2. 若修改 HTTPS 端口,需同步修改redirectPort

三、实验:Tomcat + Memcached 实现 Session 会话零丢失

1. 实验步骤

1.1 为 Tomcat 加载 Memcached 相关模块

将 memcached-session-manager 相关 Jar 包复制到 Tomcat 的 lib 目录,并同步到所有 Tomcat 节点(RS1、RS2):

复制代码
# 解压依赖包压缩包
unzip jar.zip
# 进入解压后的目录
cd jar/
# 复制所有 Jar 包到本地 Tomcat lib 目录
cp * /usr/local/tomcat/lib/
# 将 Jar 包同步到另一台 Tomcat 服务器 RS2
scp * root@172.25.254.20:/usr/local/tomcat/lib/

1.2 安装并配置 Memcached

两台服务器均需执行以下操作,实现 Memcached 部署和可远程访问配置:

1.2.1 安装 Memcached:

复制代码
dnf install memcached -y

1.2.2 修改 Memcached 配置文件,允许所有地址访问

复制代码
vim /etc/sysconfig/memcached
# 确保配置内容如下
PORT="11211"
USER="memcached"
MAXCONN="1024"
CACHESIZE="64"
OPTIONS="-l 0.0.0.0,::1"

1.2.3 启动 Memcached 并验证端口监听

复制代码
systemctl start memcached
# 验证 11211 端口监听
netstat -antluple | grep memcached

Memcached 启动成功标识 :终端输出包含 0.0.0.0:11211::1:11211 的 LISTEN 状态。

1.3 配置 Tomcat 关联 Memcached

修改 Tomcat 核心配置文件 conf/context.xml,添加 Memcached 会话管理配置,RS1 和 RS2 配置仅 ** failoverNodes ** 不同

1.3.1 配置 RS1的 context.xml:

复制代码
[root@RS1 ]#  vim /usr/local/tomcat/conf/context.xml
# 在 <Context> 标签内添加以下配置,完整文件内容如下
<Context>
    <!-- 原有监控资源配置,保留不变 -->
    <WatchedResource>WEB-INF/web.xml</WatchedResource>
    <WatchedResource>WEB-INF/tomcat-web.xml</WatchedResource>
    <WatchedResource>${catalina.base}/conf/web.xml</WatchedResource>

    <!-- Memcached 会话管理核心配置 -->
    <Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager"
     memcachedNodes="n1:172.25.254.10:11211,n2:172.25.254.20:11211"
     failoverNodes="n1"
     requestUriIgnorePattern=".*\.(ico|png|gif|jpg|css|js)$"
     transcoderFactoryClass="de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFactory"
     />
</Context>

1.3.2 配置 RS2的 context.xml:

复制代码
[root@RS2 ]#  vim /usr/local/tomcat/conf/context.xml
# 仅修改 failoverNodes 为 n2,其余配置与 RS1 一致
<Context>
    <WatchedResource>WEB-INF/web.xml</WatchedResource>
    <WatchedResource>WEB-INF/tomcat-web.xml</WatchedResource>
    <WatchedResource>${catalina.base}/conf/web.xml</WatchedResource>

    <Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager"
     memcachedNodes="n1:172.25.254.10:11211,n2:172.25.254.20:11211"
     failoverNodes="n2"  # 仅此处与 RS1 不同
     requestUriIgnorePattern=".*\.(ico|png|gif|jpg|css|js)$"
     transcoderFactoryClass="de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFactory"
     />
</Context>

1.3.3 重启两台服务器的 Tomcat,使配置生效

复制代码
systemctl restart tomcat.service

2. 实验结果

3. 实验总结

1. Memcached 核心定位

  • 类型内存型分布式缓存系统,数据存储在内存中,读写性能远高于磁盘存储。
  • 核心场景 :适合存储临时、高频访问的数据,如用户会话(Session)、热点缓存数据等,避免频繁访问数据库,大幅提升系统响应速度。

2. 会话管理扩展:MemcachedBackupSessionManager

  • 角色 :Tomcat 的第三方会话管理插件,用于实现 Session 的跨节点共享(解决 Tomcat 集群下 Session 不一致问题)。
  • 核心能力:将 Tomcat 生成的 Session 数据持久化到 Memcached 集群中,而非仅存储在单个 Tomcat 节点内存,实现会话的高可用与跨节点迁移。

3. 关键配置项解析

配置项 核心作用 配置格式 / 示例
memcachedNodes 定义 Memcached 集群节点列表,Tomcat 会将 Session 写入这些节点 格式:节点名1:IP1:端口1,节点名2:IP2:端口2示例:node1:192.168.1.10:11211,node2:192.168.1.11:11211
failoverNodes 配置故障切换节点,当主 Memcached 节点故障时,自动切换到这些节点,保证会话不丢失 格式:节点名3:IP3:端口3示例:node3:192.168.1.12:11211
requestUriIgnorePattern 配置忽略 Session 交互的静态资源路径,减少不必要的 Memcached 读写开销,提升访问速度 格式:正则表达式,匹配静态资源(如 .css, .js, .jpg 等)示例:`.*.(png jpg css js)$`

4. 核心价值

  • 高可用:Session 存储在 Memcached 集群,单节点故障不影响会话可用性。
  • 性能优化:内存级读写,避免磁盘 IO 瓶颈;忽略静态资源的 Session 交互,减少缓存压力。
  • 集群兼容:支持 Tomcat 集群部署,实现会话跨节点共享,解决负载均衡下的会话粘滞问题。
相关推荐
dustcell.1 小时前
haproxy七层代理
java·开发语言·前端
游离态指针1 小时前
以为发消息=下单成功?RabbitMQ从0到秒杀实战的完整踩坑笔记
java
BD_Marathon2 小时前
工厂方法模式
android·java·工厂方法模式
玹外之音2 小时前
Spring AI MCP 无状态服务器实战:构建AI智能用户管理系统
java·后端
java干货2 小时前
Redis 的 ZipList 是什么?它是怎么解决内存碎片问题的?
java
失重外太空啦2 小时前
Tomcat
java·服务器·tomcat
屎到临头想搅便2 小时前
TOMCAT
java·tomcat
Sylvia33.3 小时前
火星数据:解构斯诺克每一杆进攻背后的数字语言
java·前端·python·数据挖掘·数据分析