第一章 Tomcat 基础认知
1.1 什么是Tomcat
Tomcat 是一款开源免费的轻量级Java Web容器(Servlet容器)+ HTTP Web服务器,由Apache基金会维护,是目前Java Web项目最主流的运行容器。
核心定位:
-
遵循 Servlet、JSP、EL、WebSocket 官方规范,能够运行Java Web程序
-
具备HTTP服务器能力,可直接处理HTTP/HTTPS请求
-
区别于Nginx:Nginx是静态服务器/反向代理,Tomcat是动态Java程序容器
-
SpringBoot内置的嵌入式容器,底层默认就是Tomcat
1.2 Tomcat 核心作用
-
接收客户端HTTP请求,解析请求协议、参数、头信息
-
匹配对应Web应用、Servlet,执行业务代码
-
封装响应结果,返回给浏览器
-
管理Servlet生命周期、Session管理、线程调度、资源隔离
1.3 主流版本区别
-
Tomcat8:最稳定企业版,支持Servlet3.1,JDK8+,生产使用最多
-
Tomcat9:小幅升级,优化线程池、IO模型,JDK8+,兼容8,推荐新业务使用
-
Tomcat10 :包名从javax.* 迁移为 jakarta.*,不兼容老项目,新项目可使用
1.4 核心名词解释
-
Web容器:专门用来运行Java Web程序的环境,负责管理程序生命周期
-
Servlet:Java动态资源核心接口,所有动态请求最终由Servlet处理
-
Context:Web应用上下文,一个Context对应一个独立项目
-
Connector:连接器,负责端口监听、IO读写、协议解析
-
Engine:请求调度引擎,Tomcat核心调度器
第二章 Tomcat 目录结构详解
解压后的Tomcat目录每一个文件夹都有固定作用。
html
tomcat-root/
├── bin/ # 启动、停止、脚本工具
├── conf/ # 所有核心配置文件
├── lib/ # Tomcat公共核心依赖包
├── logs/ # 日志文件目录
├── webapps/ # 默认项目部署目录
├── work/ # JSP编译缓存、运行临时文件
├── temp/ # 系统临时文件
└── LICENSE # 开源协议
2.1 bin 目录核心文件
-
startup.sh / startup.bat:启动Tomcat
-
shutdown.sh / shutdown.bat:停止Tomcat
-
catalina.sh:核心启动脚本,加载JVM参数、启动容器(禁止直接修改)
-
setenv.sh(自建):生产自定义JVM参数、环境变量,优先级最高
-
tomcat-native.tar.gz:高性能APR本地库压缩包
2.2 conf 核心配置文件(重中之重)
-
server.xml:Tomcat全局核心架构配置(端口、线程池、集群、虚拟主机)
-
web.xml:全局Web应用默认配置(编码、MIME类型、会话超时、默认页面)
-
context.xml:全局数据源、资源配置、会话管理
-
tomcat-users.xml:控制台账号权限配置
-
catalina.properties:类加载、Jar包扫描、系统参数配置
2.3 日志文件详解
-
catalina.out:最核心日志,控制台输出、程序异常、System.out打印全部在此
-
localhost_access_log:访问日志,记录每一次HTTP请求(IP、状态码、耗时、请求地址)
-
localhost.log:Tomcat容器内部运行日志
-
manager.log:后台管理控制台日志
第三章 Tomcat 核心架构与组件原理
Tomcat 采用分层组件架构,从上至下逐层调度,所有组件在 server.xml 中一一对应。
组件层级:Server > Service > Connector + Engine > Host > Context > Wrapper
整个Tomcat容器的顶层对象,一个JVM进程只能有一个Server。
核心配置:
html
<Server port="8005" shutdown="SHUTDOWN">
-
8005:关闭端口,默认通过发送SHUTDOWN指令关闭Tomcat
-
生产安全优化:可修改随机密码、或直接禁用远程关闭
3.2 Service(服务绑定器)
作用:绑定 多个Connector + 一个Engine,对外提供统一服务。默认只有一个Catalina服务。
html
<Service name="Catalina">
3.3 Connector(连接器,性能核心)
Tomcat对外的入口,负责监听端口、接收TCP连接、解析HTTP协议、线程调度。
三大默认端口:
-
8080:HTTP服务端口
-
8443:HTTPS加密端口
-
8009:AJP协议端口(生产必须关闭,高危漏洞)
AJP 协议仅用于 Apache httpd + Tomcat 联动,Nginx+Tomcat 架构完全用不到,关闭可修复文件读取漏洞(CVE-2020-1938)、减少端口暴露风险。
1、编辑配置文件:vim /usr/local/tomcat/conf/server.xml
2、找到配置项:
<!-- Define an AJP 1.3 Connector on port 8009 --> <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
3、直接注释掉该配置项:
<!-- Define an AJP 1.3 Connector on port 8009 --> <!-- <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" /> -->
- Tomcat 8.5.51 / 9.0.31 及以上:默认注释 AJP,无需手动关闭
- Tomcat 8.5.50、9.0.30 及更早:默认开启,必须注释关闭防漏洞
3.4 Engine(引擎,请求调度核心)
Service内部的总调度中心,接收所有Connector的请求,根据域名分发到对应虚拟主机Host。
html
<Engine name="Catalina" defaultHost="localhost">
3.5 Host(虚拟主机)
对应一个域名,实现单Tomcat部署多个不同域名项目,隔离站点资源。
html
<Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="false">
核心参数:
name:绑定域名
appBase:项目根目录
unpackWARs:是否自动解压war包
autoDeploy:是否开启自动热部署(生产关闭)
3.6 Context(应用上下文)
对应一个独立Java Web项目,是项目部署的核心单元,负责项目资源、Session、过滤器、Servlet管理。
3.7 Wrapper
最小单元,对应项目中的每一个Servlet,管理Servlet实例、初始化、销毁、请求调用。
第四章 Tomcat 请求完整执行流程
用户访问网址 → 完整链路:
-
客户端发起HTTP请求,经过TCP三次握手连接Tomcat Connector
-
Connector线程接收请求,解析HTTP协议(请求头、请求体、URL、参数)
-
将封装好的请求对象交给 Engine 引擎
-
Engine根据请求域名,匹配对应的 Host虚拟主机
-
Host根据请求路径,匹配对应的 Context项目应用
-
Context根据URL映射,找到对应的 Wrapper(Servlet)
-
执行过滤器链、Servlet业务代码,处理请求
-
生成响应结果,逐层返回,Connector返回HTTP响应给客户端
第五章 Tomcat 四大IO模型(性能调优核心)
IO模型直接决定Tomcat并发能力,是生产调优重中之重。
| IO模型 | 协议类名 | 特点 | 适用场景 |
|---|---|---|---|
| BIO 阻塞IO | Http11Protocol | 1连接1线程,阻塞等待,并发极低 | 老旧版本,生产禁用 |
| NIO 非阻塞IO | Http11NioProtocol | 多路复用,少量线程处理大量连接 | 默认模型,绝大多数生产业务 |
| NIO2/AIO 异步IO | Http11Nio2Protocol | 系统级异步读写,无需轮询 | 大文件上传、长连接业务 |
| APR 本地C库 | Http11AprProtocol | 调用本地C语言库,内核sendfile,性能最高 | 高吞吐、静态资源、HTTPS业务 |
第六章 Tomcat 三种部署方式(开发+生产)
6.1 自动部署(开发使用)
将war包直接放入 webapps 目录,Tomcat自动解压、启动项目。
缺点:生产不安全、热部署占用资源、容易报错,禁止生产使用。
6.2 server.xml 直接配置Context(简单生产)
在Host标签内添加自定义项目路径,脱离webapps目录。
html
<Context path="" docBase="/data/project/demo" reloadable="false" />
6.3 独立XML文件部署(企业生产首选)
在 conf/Catalina/localhost/ 新建ROOT.xml,内容如下:
html
<?xml version="1.0" encoding="UTF-8"?>
<Context docBase="/data/project/demo" reloadable="false" crossContext="false"/>
优势:不修改全局server.xml、部署灵活、多项目隔离、升级方便。
第七章 生产级核心配置详解(server.xml完整版)
以下为线上可直接落地的最优配置,包含线程池、压缩、防攻击、编码优化。
7.1 自定义线程池
html
<Executor name="tomcatThreadPool"
namePrefix="catalina-exec-"
maxThreads="300"
minSpareThreads="30"
maxIdleTime="60000"
prestartminSpareThreads="true"
maxQueueSize="200"/>
7.2 NIO高性能连接器
html
<Connector port="8080"
protocol="org.apache.coyote.http11.Http11NioProtocol"
executor="tomcatThreadPool"
connectionTimeout="20000"
redirectPort="8443"
URIEncoding="UTF-8"
useBodyEncodingForURI="true"
enableLookups="false"
acceptCount="100"
compression="on"
compressionMinSize="1024"
compressableMimeType="text/html,text/css,application/javascript,application/json,text/plain"
maxSwallowSize="10485760"
server="Server"/>
关键优化点:关闭DNS解析、开启Gzip压缩、防超大文件DOS攻击、隐藏版本号、解决中文乱码。
第八章 JVM生产调优(setenv.sh)
在 tomcat/bin 新建 setenv.sh,Tomcat启动自动加载,不修改原生脚本。
4核8G服务器标准最优
bash
#!/bin/bash
CATALINA_OPTS="-Xms4g -Xmx4g"
CATALINA_OPTS="$CATALINA_OPTS -XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=512m"
CATALINA_OPTS="$CATALINA_OPTS -XX:+UseG1GC -XX:MaxGCPauseMillis=200"
CATALINA_OPTS="$CATALINA_OPTS -XX:+HeapDumpOnOutOfMemoryError"
CATALINA_OPTS="$CATALINA_OPTS -XX:HeapDumpPath=/usr/local/tomcat/logs/heap.hprof"
CATALINA_OPTS="$CATALINA_OPTS -Xloggc:/usr/local/tomcat/logs/gc.log"
CATALINA_OPTS="$CATALINA_OPTS -Djava.security.egd=file:/dev/./urandom"
CATALINA_OPTS="$CATALINA_OPTS -Duser.timezone=Asia/Shanghai"
核心作用:固定堆内存、G1低延迟GC、OOM自动dump、解决随机数阻塞、统一时区。
第九章 虚拟主机多站点配置
单Tomcat运行多个域名网站,域名完全隔离,日志、项目目录独立。
html
<Engine name="Catalina" defaultHost="www.site1.com">
<Host name="www.site1.com" appBase="webapps/site1" unpackWARs="true" autoDeploy="false">
<Context path="" docBase="/data/site1"/>
</Host>
<Host name="www.site2.com" appBase="webapps/site2" unpackWARs="true" autoDeploy="false">
<Context path="" docBase="/data/site2"/>
</Host>
</Engine>
第十章 Nginx+Tomcat 集群负载均衡
企业标准高可用架构:Nginx反向代理+多Tomcat节点负载,实现分流、容错、高可用。
10.1 Nginx核心配置
bash
upstream tomcat_cluster {
server 192.168.1.10:8080 weight=3 max_fails=2 fail_timeout=10s;
server 192.168.1.11:8080 weight=3 max_fails=2 fail_timeout=10s;
keepalive 100;
}
server {
listen 80;
server_name demo.com;
location ~* \.(png|jpg|css|js|ico)$ {
expires 30d;
}
location / {
proxy_pass http://tomcat_cluster;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
第十一章 分布式Session共享(集群必备)
多Tomcat集群默认Session不共享,用户切换节点会掉线,两种解决方案:
11.1 Redis Session共享(生产首选)
将Session序列化存入Redis,所有节点共享,无广播风暴、性能优异。
11.2 Tomcat原生集群复制(小型测试使用)
节点之间互相广播同步Session,节点多会造成网络风暴,不推荐生产。
第十二章 Tomcat 安全加固(生产必做)
-
删除webapps默认自带项目:ROOT、docs、examples、manager等
-
关闭8009 AJP端口,杜绝文件读取漏洞
-
Connector配置server="自定义字段",隐藏Tomcat版本号
-
关闭autoDeploy、reloadable热部署
-
使用普通用户启动Tomcat,禁止root启动
-
开启HTTPS,禁用TLS1.0/1.1弱协议
-
配置访问日志,记录真实IP,防盗刷、溯源
第十三章 Tomcat 类加载机制(面试核心)
Tomcat 打破双亲委派模型,实现应用隔离,加载顺序:
-
优先加载当前应用:
WEB-INF/classes -
加载当前应用依赖:
WEB-INF/lib -
加载Tomcat公共依赖:
tomcat/lib -
最后委派父类加载JDK核心类
核心优势:不同项目可以使用不同版本Jar包,彻底解决依赖冲突。
第十四章 生产高频故障排查方案
14.1 内存溢出OOM
原因:内存泄漏、堆内存过小、大对象未释放 解决方案:查看dump文件、优化代码、调大堆内存、关闭无效缓存
14.2 接口卡顿、线程耗尽
使用 jstack 进程PID 查看线程阻塞,多为数据库、第三方接口超时阻塞,优化连接池与超时时间
14.3 URL中文乱码
Connector 添加 URIEncoding="UTF-8" 彻底解决
14.4 CPU 100%
死循环代码、频繁Full GC,通过jstack定位死循环线程、jstat分析GC频率
第十五章 Tomcat 监控体系
-
jps:查看Tomcat进程
-
jstat -gc:实时监控GC情况
-
jstack:排查线程死锁、阻塞
-
jmap:导出堆内存快照,分析泄漏
-
JMX/VisualVM:远程实时监控线程、堆、类加载
第十六章 终极生产优化总结
-
IO模型使用 NIO 或 APR,禁用BIO
-
自定义线程池,配置合理最大线程、队列数
-
JVM使用G1收集器,固定堆内存,开启OOMdump
-
关闭所有热部署、自动扫描功能
-
关闭AJP端口、隐藏版本号、权限隔离
-
Nginx静态资源拦截,动态请求转发Tomcat
-
集群使用Redis实现Session共享,保证高可用