Tomcat 安装部署与目录结构详解
概述
Tomcat 的部署比想象中简单,但要做到"装得对、起得稳、理得清",需要对安装方式、目录职责、环境变量与启动脚本都有准确的认识。本文从下载安装开始,逐层拆解 Tomcat 的目录结构,再落到环境变量、启动流程与常见部署形态上。
一、安装方式选择
| 方式 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
| 二进制包(zip/tar.gz) | 绝大多数生产环境 | 开箱即用、部署快 | 无法定制编译选项 |
| 源码编译 | 需要定制 JNI/APR 等 | 可裁剪、可加参数 | 需要构建工具链 |
| 系统包管理(yum/apt) | 快速搭建、测试环境 | 自动管理依赖 | 版本滞后、目录分散 |
| Docker 镜像 | 容器化部署 | 可复现、易迁移 | 需要镜像仓库与编排 |
生产环境推荐二进制包 + 独立目录方式:版本可控、目录清晰、升级替换简单。
二、二进制包安装步骤
2.1 前置条件
Tomcat 9/10/11 对 JDK 版本要求:
| Tomcat 版本 | 最低 JDK | Servlet 规范 |
|---|---|---|
| Tomcat 9.0 | JDK 8+ | Servlet 4.0 |
| Tomcat 10.0 | JDK 8+ | Servlet 5.0(javax → jakarta) |
| Tomcat 10.1 | JDK 11+ | Servlet 6.0 |
| Tomcat 11.0 | JDK 17+ | Servlet 6.1 |
先确认 JDK 版本:
java -versionTomcat 10 起包名从
javax.servlet迁移到jakarta.servlet,依赖老 API 的应用需适配后才可迁移。
2.2 下载与解压
从 Apache 官网或国内镜像下载 tar.gz 包,解压到目标目录:
# 下载(以 10.1.x 为例)
wget https://dlcdn.apache.org/tomcat/tomcat-10/v10.1.34/bin/apache-tomcat-10.1.34.tar.gz
# 解压并移动到统一目录
tar -zxvf apache-tomcat-10.1.34.tar.gz
mv apache-tomcat-10.1.34 /opt/tomcat
# 创建运行用户(安全建议:不用 root 运行)
useradd -r -s /sbin/nologin tomcat
chown -R tomcat:tomcat /opt/tomcat2.3 配置环境变量
在 /etc/profile.d/tomcat.sh 中配置:
export CATALINA_HOME=/opt/tomcat
export PATH=$PATH:$CATALINA_HOME/bin关键环境变量说明:
| 变量 | 作用 |
|---|---|
CATALINA_HOME | Tomcat 安装根目录,运行脚本依据它定位 |
CATALINA_BASE | 实例目录,多实例部署时指向各自配置目录 |
JAVA_HOME | JDK 安装目录,脚本用它找 java 命令 |
JAVA_OPTS | JVM 启动参数(堆内存、GC、JMX 等) |
CATALINA_OPTS | 仅启动时生效的参数(与停服时的 JAVA_OPTS 区分) |
2.4 启动与验证
# 前台启动(调试用,日志直接打到终端)
/opt/tomcat/bin/catalina.sh run
# 后台启动
/opt/tomcat/bin/startup.sh
# 验证
curl -I http://localhost:8080
tail -f /opt/tomcat/logs/catalina.out启动成功的标志是日志中出现:
INFO [main] org.apache.catalina.startup.Catalina.start Server startup in [1234] milliseconds三、目录结构逐项解析
解压后的 Tomcat 目录(以 10.1.x 为例):
apache-tomcat-10.1.34/
├── bin/ # 启动/停止脚本、系统服务脚本
├── conf/ # 全部配置文件
│ ├── server.xml # 组件树配置(端口、容器、虚拟主机)
│ ├── web.xml # 全局 Servlet 规范默认配置
│ ├── context.xml # 全局 Context 默认配置
│ ├── catalina.properties # 类加载器路径、包隔离列表
│ ├── tomcat-users.xml # Manager 等角色的用户配置
│ └── logging.properties # JUL 日志配置
├── lib/ # Tomcat 自身与所有应用共享的 Jar
├── logs/ # 运行日志输出目录
├── temp/ # 临时文件目录
├── webapps/ # Web 应用部署目录(WAR/解压目录)
└── work/ # JSP 编译产物与 Session 序列化临时文件3.1 bin 目录
| 文件 | 作用 |
|---|---|
startup.sh / startup.bat | 启动脚本(最终调用 catalina.sh start) |
shutdown.sh / shutdown.bat | 停止脚本(向 8005 端口发 SHUTDOWN 命令) |
catalina.sh | 核心脚本,支持 start/stop/run/version 等命令 |
daemon.sh | 以 Linux 守护进程方式运行(jsvc) |
version.sh | 打印版本与环境信息 |
catalina.sh 执行逻辑:校验 CATALINA_HOME 与 JAVA_HOME → 组装 classpath → 计算 JAVA_OPTS → 定位启动类 org.apache.catalina.startup.Bootstrap → 前台或后台启动。
3.2 conf 目录
配置文件按职责划分:
| 文件 | 管控范围 | 生效层级 |
|---|---|---|
server.xml | 组件树、端口、连接器 | Server 级 |
web.xml | 默认 Servlet 映射、MIME 类型、欢迎页 | 全局默认,应用内可覆盖 |
context.xml | 默认 JNDI 数据源、会话配置 | 全局默认 |
catalina.properties | 类加载器 loader 路径、安全包列表 | JVM 级 |
tomcat-users.xml | Manager/Host-Manager 用户角色 | 管理级 |
logging.properties | 各组件日志级别与文件输出 | JVM 级 |
这些文件的具体配置项会在"server.xml 配置全面解析"一篇中详细展开。
3.3 lib 目录
lib/ 下的 Jar 被 Common 类加载器加载,所有 Web 应用可见。常见的冲突点就在这里:如果业务应用的 WEB-INF/lib 中带了与 lib/ 同名的旧版 Jar(如 servlet-api.jar),可能引发类加载冲突。
3.4 webapps 与 work
webapps/:放置 WAR 包或解压后的应用目录,Tomcat 启动时自动部署work/:Jasper 编译 JSP 的产物(.java+.class),以及SESSIONS.ser(正常关闭时会话序列化文件)
四、目录职责的两个关键概念
4.1 CATALINA_HOME 与 CATALINA_BASE
这两个概念容易混淆,其实区别很清晰:
| 概念 | 指向 | 包含内容 |
|---|---|---|
CATALINA_HOME | 安装目录(只读) | bin、lib |
CATALINA_BASE | 实例目录(可写) | conf、logs、temp、webapps、work |
单实例部署时两者相同;多实例部署时,一个 CATALINA_HOME 对应多个 CATALINA_BASE——每个实例有独立的 conf/logs/webapps,但共享同一套 bin/lib。
/opt/tomcat ← CATALINA_HOME(bin + lib)
├── bin/
└── lib/
/opt/tomcat-instances/
├── app1/ ← CATALINA_BASE=app1(conf + logs + webapps + work)
│ ├── conf/server.xml ← 端口 8081
│ └── webapps/
└── app2/ ← CATALINA_BASE=app2(端口 8082)
├── conf/server.xml
└── webapps/启动时指定:
CATALINA_BASE=/opt/tomcat-instances/app1 /opt/tomcat/bin/catalina.sh start多实例的价值:同一台机器上运行多个版本/多个隔离的应用,资源相互独立,端口互不冲突。
4.2 Web 应用标准结构
一个标准的 Web 应用目录(WAR 解压后):
webapps/myapp/
├── index.jsp # 欢迎页
├── static/ # 静态资源(HTML/CSS/JS/图片)
├── META-INF/
│ └── context.xml # 应用级 Context 配置(数据源等)
└── WEB-INF/ # 受保护目录,浏览器无法直接访问
├── web.xml # 应用描述符(Servlet 映射、过滤器、监听器)
├── classes/ # 应用类字节码
└── lib/ # 应用专属 JarWEB-INF 是部署的核心:classes/ 与 lib/ 的类由 Webapp 类加载器优先加载,web.xml 定义了 Servlet 与 URL 的映射关系。
五、部署应用的方式
| 方式 | 操作 | 特点 |
|---|---|---|
| 拷贝 WAR | WAR 放入 webapps 自动解压部署 | 最简单,支持热部署 |
| 解压目录 | 直接把解压后的目录放入 webapps | 便于调试 |
| Manager 界面 | 通过管理后台上传 WAR | 远程操作,需配置用户 |
| 外部 Context | server.xml 或 conf/Catalina 下配置 docBase 指向外部目录 | 应用目录与 Tomcat 解耦 |
六、常见安装问题排查
| 现象 | 原因 | 解决 |
|---|---|---|
启动报 Cannot find ./catalina.sh | 未在 bin 目录执行或 CATALINA_HOME 未配置 | 使用绝对路径执行脚本 |
端口被占用 BindException: Address already in use | 8080 被其他进程占用 | 检查占用并更换端口或关闭冲突进程 |
JAVA_HOME is not defined correctly | JAVA_HOME 指向错误 | 校验 java -version 与变量一致性 |
| 启动慢 / 卡住 | 随机数熵不足、DNS 反查慢 | 加 -Djava.security.egd=file:/dev/./urandom |
| 403 Access Denied 访问管理页 | Manager 应用默认无授权用户 | 在 tomcat-users.xml 配置 role 与 user |
| 中文乱码 | 字符编码未设置 | 连接器加 URIEncoding="UTF-8" |
七、生产部署建议
- 专用用户运行:禁止 root 运行 Tomcat,降低提权风险。
- 统一版本:全环境统一 Tomcat 主版本(如 10.1.x),避免环境差异。
- 目录权限收紧:conf 与 bin 只读,logs/work/webapps 可写。
- 时区与编码统一:
-Duser.timezone=Asia/Shanghai,连接器URIEncoding="UTF-8"。 - 独立日志目录:将 logs 软链到统一日志盘,便于采集与轮转。
- 多实例规划:多应用部署时用 CATALINA_BASE 隔离,而不是单实例堆应用。
八、内嵌模式:Spring Boot 中的 Tomcat
Spring Boot 内嵌 Tomcat 的本质是以 Jar 方式运行、用代码装配组件树:
// Spring Boot 通过 TomcatServletWebServerFactory 创建内嵌容器
TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory();
factory.setPort(8080);
factory.setContextPath("/myapp");内嵌模式的目录结构与独立部署不同——不再有 conf/webapps/logs,配置通过 application.properties 与代码注入:
| 独立部署 | 内嵌模式 |
|---|---|
| server.xml | server.tomcat.* 配置项 |
| web.xml | ServletRegistrationBean / 注解 |
| conf/catalina.properties | server.tomcat.threads.* |
| logs/catalina.out | logging.file.name |
| webapps 部署 WAR | Fat Jar 内嵌依赖 + 代码注册 |
理解独立部署的目录结构,再看内嵌模式的配置项,会发现处处是映射关系——server.tomcat.max-threads 对应连接器的 maxThreads,server.tomcat.accept-count 对应 acceptCount。
参考链接: