Tomcat-基础架构
官网地址:https://tomcat.apache.org/
简介
Tomcat是Apache软件基金会(Apache Software Foundation)的Jakarta项目中的一个核心项目,由Apache,Sun和其他一些公司及个人共同开发而成。Tomcat服务器是一个免费的开放源代码的Web应用服务器,属于轻量级应用服务器,在中小型系统和并发访问用户不是很多的场合下被普遍使用,是开发和调试JSP程序的首选。Tomcat和Nginx,APache(httpd),lighttpd等Web服务器一样,具有处理HTML页面的功能,另外它还是一个Servlet和JSP容器,独立的Servlet容器是Tomcat的默认模式。不过,Tomcat处理静态HTML的能力不如Nginx/Apache服务器。
核心特性
- 轻量级 Servlet/JSP 容器
- 实现 Java Servlet 和 JSP 规范(如 Tomcat 10 支持 Servlet 6.0 和 JSP 3.0),但不支持完整 Java EE 规范(如 EJB)。
- 相比 JBoss、WebLogic 等全功能应用服务器,Tomcat 更轻量,适合中小型项目。
- 跨平台与开源
- 基于 Java 开发,支持 Windows、Linux、macOS 等系统,可免费使用和修改。
- 基础 HTTP 服务能力
- 内置 Coyote 连接器处理 HTTP 请求,但静态资源处理性能弱于 Nginx/Apache,常作为动态请求处理器与反向代理配合。
核心组件
Tomcat 采用分层容器设计,核心模块包括:
- Connector(连接器)
- 监听网络端口(如 HTTP 8080、AJP 8009),将请求解析为
ServletRequest对象传递给 Container。 - 支持 BIO/NIO/APR 等 I/O 模型,可通过线程池优化并发处理能力。
- 监听网络端口(如 HTTP 8080、AJP 8009),将请求解析为
- Container(容器)
- Engine:顶级容器,管理多个虚拟主机(Host)。
- Host:代表虚拟主机(如域名),包含多个 Web 应用(Context)。
- Context:对应一个 Web 应用(如 WAR 包),包含 Servlet 和静态资源。
- Wrapper:管理单个 Servlet 的生命周期(初始化、执行、销毁)。
- 其他关键组件
- Catalina:Servlet 容器实现,处理请求调度。
- Jasper:JSP 编译器,将 JSP 动态编译为 Servlet 执行。
- Cluster:支持会话复制,实现多实例负载均衡与高可用。
主流Java Web容器
| 服务器 | 开发厂商 | 开源情况 | 核心定位 | 主要特性 | 适用场景 |
|---|---|---|---|---|---|
| Tomcat | Apache基金会 | ✅ 开源 | Servlet/JSP容器 | 轻量级、易配置、社区生态完善,支持Servlet/JSP规范 | 中小型Web应用、Spring Boot项目、开发测试环境 |
| Resin | Caucho公司 | ✅ 开源 | 高性能JSP/Servlet引擎 | 静态资源处理能力媲美Nginx,动态内容处理速度比Tomcat快3倍,内置负载均衡 | 高并发网站(如163、ku6)、商业级应用 |
| Jetty | Eclipse基金会 | ✅ 开源 | 嵌入式轻量服务器 | 启动快(秒级)、内存占用低(~50MB),原生支持HTTP/2和WebSocket | 微服务、IoT设备、云原生架构 |
| JBoss/WildFly | Red Hat | ✅ 开源 | 全栈Java EE服务器 | 支持EJB/JMS/JPA等企业规范,集成Tomcat作为Web容器,集群管理能力强 | 金融/电信等复杂企业系统 |
| WebLogic | Oracle | ❌ 商业 | 企业级Java EE服务器 | 高可靠性、强事务支持,与Oracle数据库深度集成 | 大型分布式系统(银行、电信核心业务) |
| WebSphere | IBM | ❌ 商业 | 集成式中间件平台 | 支持全栈Java EE,扩展性强,配套IBM生态工具链 | 大型企业混合云架构 |
- 轻量级/微服务:Jetty或Undertow(内存占用低于Tomcat 60%)。
- 企业级全栈需求:WildFly(开源)或WebLogic(商业高可用)。
- 高并发Web站点:Resin(性能最优)或Nginx+Tomcat组合(静态分离)。
- 云原生开发:Spring Boot默认Tomcat,资源敏感场景可替换为Jetty/Undertow。
Tomcat与JDK关系
graph TD
%% Tomcat在Java运行环境中的位置
subgraph Java_Runtime_Environment
JDK["JDK (开发工具包)"] --> JRE
JRE["JRE (运行环境)"] --> JVM
JVM["JVM (Java虚拟机)"] --> OS
end
OS["OS (操作系统)"] --> Tomcat
Tomcat["Tomcat"] --> Web_App["Servlet/JSP Web应用"]
%% 开发工具依赖关系
IDE["Java开发工具
(Eclipse/IntelliJ等)"] --> JDK
%% 样式定义
classDef jdk fill:#F5B7B1,stroke:#333
classDef jre fill:#A9DFBF,stroke:#333
classDef jvm fill:#F9E79F,stroke:#333
classDef os fill:#F4D03F,stroke:#333
classDef tomcat fill:#5DADE2,stroke:#333,color:white
classDef ide fill:#1F618D,stroke:#333,color:white
classDef app fill:#7D3C98,stroke:#333,color:white
class JDK jdk
class JRE jre
class JVM jvm
class OS os
class Tomcat tomcat
class IDE ide
class Web_App appJDK→JRE→JVM→OS:Tomcat运行在Java运行时环境之上JRE提供核心类库,JVM执行字节码,OS提供底层资源管理
运行原理:
bash[浏览器请求] → OS接收网络请求 → Tomcat(Java进程) → JVM加载Servlet类 → JRE执行字节码 → 返回HTML响应
Tomcat-目录结构
核心目录概览
apache-tomcat-10.1.x/
├── bin/ # 控制脚本
├── conf/ # 全局配置
├── lib/ # 共享类库
├── logs/ # 运行日志
├── webapps/ # 应用部署
├── work/ # 运行时缓存
├── temp/ # 临时文件
├── LICENSE # 许可证
└── NOTICE # 版权声明关键目录解析
bin/ - 控制中心
- 核心脚本:
startup.sh/startup.bat:启动服务(内部调用catalina)shutdown.sh/shutdown.bat:安全停止服务catalina.sh/catalina.bat:核心控制脚本,支持调试/运行参数(如debug、version)configtest.sh/configtest.bat:配置文件语法检查工具
- 环境配置:
setenv.sh/setenv.bat:自定义 JVM 参数(如CATALINA_OPTS="-Xms512m -Xmx1024m")
conf/ - 配置中枢
server.xml:主配置文件- 定义端口(
<Connector port="8080">)、线程池、虚拟主机(<Host>) - 修改需重启生效
- 定义端口(
web.xml:全局 Servlet 配置(默认 MIME 类型、会话超时)context.xml:数据源(JDBC)、JNDI 资源定义tomcat-users.xml:管理角色配置(如manager-gui、admin-gui)logging.properties:日志级别(FINE/INFO)和输出格式控制
webapps/ - 应用仓库
- 默认应用:
ROOT/:根路径应用(http://localhost:8080)manager/:管理控制台(需权限)examples/:官方示例(JSP/Servlet)
- 部署方式:
- 直接放置 WAR 包(自动解压)
- 创建应用目录(含
WEB-INF/classes)
lib/ - 共享类库
- 核心 JAR:
servlet-api.jar:Servlet 规范实现jsp-api.jar:JSP 编译支持tomcat-jdbc.jar:数据库连接池
- 扩展性:第三方 JAR 放入此目录可被所有应用共享
logs/ - 监控与诊断
- 关键日志:
catalina.out:标准输出(启动/运行时信息)localhost_access_log.[date].txt:访问日志(格式:IP - - [时间] "请求" 状态码 响应大小)manager.[date].log:管理操作审计
- 排查技巧:
tail -f catalina.out实时监控启动问题
work/ - 运行时缓存
- JSP 编译:
- 存放 JSP 转换后的 Servlet 源文件和
.class文件(路径示例:work/Catalina/localhost/ROOT/org/apache/jsp/index_jsp.class)
- 存放 JSP 转换后的 Servlet 源文件和
- 故障处理:修改 JSP 未生效时,清理此目录强制重新编译
temp/ - 临时文件
- 存储上传文件、会话持久化数据等,Tomcat 自动管理,无需手动干预
核心配置文件解析
server.xml - 服务器全局配置
Tomcat的主配置文件,定义服务器架构和核心组件:
<Server port="8005" shutdown="SHUTDOWN">
<Service name="Catalina">
<!-- HTTP连接器配置 -->
<Connector
port="8080"
protocol="HTTP/1.1"
maxThreads="200" <!-- 最大工作线程数 -->
minSpareThreads="10" <!-- 最小空闲线程 -->
acceptCount="100" <!-- 等待队列长度 -->
connectionTimeout="20000"
redirectPort="8443" />
<!-- AJP连接器(用于集成Apache) -->
<Connector port="8009" protocol="AJP/1.3" />
<Engine name="Catalina" defaultHost="localhost">
<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true">
<!-- 上下文参数 -->
<Context path="/myapp" docBase="myapp" reloadable="true" />
</Host>
</Engine>
</Service>
</Server>关键组件说明:
<Connector>:定义请求处理协议(HTTP/AJP)及并发参数<Executor>:线程池配置(需在<Connector>中通过executor属性引用)<Host>:虚拟主机配置,支持多域名部署<Context>:应用级配置(也可在独立context.xml中定义)
常用Connector参数:
| 参数 | 默认值 | 作用 |
|---|---|---|
maxThreads | 200 | 最大并发线程数 |
acceptCount | 100 | 等待队列容量 |
compression | off | 启用GZIP压缩 |
SSLEnabled | false | 启用HTTPS加密 |
web.xml - 应用部署描述符
位于conf/(全局)或应用WEB-INF/(应用级),定义Servlet规范相关配置:
<web-app>
<!-- Servlet定义 -->
<servlet>
<servlet-name>MyServlet</servlet-name>
<servlet-class>com.example.MyServlet</servlet-class>
<load-on-startup>1</load-on-startup> <!-- 启动顺序 -->
</servlet>
<!-- URL映射 -->
<servlet-mapping>
<servlet-name>MyServlet</servlet-name>
<url-pattern>/api/*</url-pattern>
</servlet-mapping>
<!-- 过滤器配置 -->
<filter>
<filter-name>EncodingFilter</filter-name>
<filter-class>com.example.UTF8Filter</filter-class>
</filter>
<filter-mapping>
<filter-name>EncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 会话超时(分钟) -->
<session-config>
<session-timeout>30</session-timeout>
</session-config>
</web-app>context.xml - 应用上下文配置
分三个作用域:
- 全局 (
conf/context.xml):影响所有应用 - Host级 (
conf/Catalina/localhost/context.xml):影响单虚拟主机 - 应用级 (
webapps/myapp/META-INF/context.xml):仅影响当前应用
典型配置:
<Context>
<!-- 数据源配置 -->
<Resource
name="jdbc/TestDB"
type="javax.sql.DataSource"
maxTotal="100" <!-- 连接池最大连接数 -->
maxIdle="30" <!-- 最大空闲连接 -->
username="dbuser"
password="dbpass"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/test" />
<!-- 监控资源变更 -->
<WatchedResource>WEB-INF/web.xml</WatchedResource>
</Context>tomcat-users.xml - 权限管理
定义管理界面(如Manager App)的访问角色:
<tomcat-users>
<role rolename="manager-gui"/> <!-- 控制台GUI权限 -->
<role rolename="admin-gui"/> <!-- 管理员GUI权限 -->
<user username="admin" password="s3cret" roles="admin-gui,manager-gui"/>
</tomcat-users>安全建议:生产环境限制
manager-gui角色的IP访问。
Tomcat-优化
Gzip压缩
在Tomcat的server.xml文件中,找到对应http-nio-8080的<Connector>标签,添加或修改以下参数以启用Gzip压缩
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443"
compression="on"
compressionMinSize="2048"
compressableMimeType="text/html,text/xml,text/javascript,text/css,text/plain,application/json"
noCompressionUserAgents="gozilla, traviata" />参数说明:
compression:可选值on(开启)、off(关闭)、force(强制压缩所有数据)。compressionMinSize:默认2KB,过小的文件压缩可能适得其反。compressableMimeType:需根据实际响应类型调整,例如动态内容如JSON需显式添加application/jsonnoCompressionUserAgents:不压缩的浏览器代理
静态资源缓存
在web.xml中配置缓存大小,减轻磁盘I/O压力
<Resources cachingAllowed="true" cacheMaxSize="102400" />线程池优化
在server.xml中独立配置<Executor>提升并发能力
<Executor
name="tomcatThreadPool"
namePrefix="catalina-exec-"
maxThreads="500"
minSpareThreads="50"
maxQueueSize="100" />
<!-- 引用线程池 -->
<Connector executor="tomcatThreadPool" port="8080" />核心参数:
maxThreads:建议设为CPU核心数的2-4倍(IO密集型应用)。minSpareThreads:保持最小空闲线程(如50)以减少创建开销。acceptCount:队列长度建议为maxThreads的50%-100%
JVM调优参数
Tomcat最吃内存,只要内存足够,这只猫就跑的很快。如果系统资源有限,那就需要进行调优,提高资源使用率。
catalina.sh的路径为:/usr/local/tomcat/bin/catalina.sh,声明位置,不要放在后边
JAVA_OPTS="-Djava.awt.headless=true -Dfile.encoding=UTF-8 -server -Xms1024m -Xmx1024m -XX:NewSize=512m -XX:MaxNewSize=512m -XX:PermSize=512m -XX:MaxPermSize=512m"内存设置:
-Xms和-Xmx:设为相同值(如4G)避免动态扩展开销。-XX:MetaspaceSize:调整元空间初始大小(如256m)
GC策略:
- 吞吐量优先:
-XX:+UseParallelGC。 - 低延迟优先:
-XX:+UseG1GC并设置-XX:MaxGCPauseMillis=200
JVM核心参数优化表
| 参数类型 | 参数名 | 作用说明 | 推荐值 | 注意事项 |
|---|---|---|---|---|
| 堆内存设置 | -Xms | 初始堆大小(JVM启动时分配) | 与-Xmx相同,设为物理内存的50%-70% | 避免运行时动态扩容产生性能波动,例如-Xms4g -Xmx4g |
-Xmx | 最大堆大小(JVM可扩展上限) | |||
-Xmn | 新生代大小(Young Generation) | 占堆内存的1/3~1/4(如堆4G时设1G) | 过小易引发Minor GC频繁,过大会压缩老年代空间 | |
| 垃圾回收策略 | -XX:+UseG1GC | 启用G1垃圾回收器(低延迟) | JDK9+默认,堆>6G时首选 | 配合-XX:MaxGCPauseMillis=200设置目标停顿时间 |
-XX:+UseConcMarkSweepGC | 启用CMS回收器(并发标记清除) | JDK8及以下老年代低延迟方案 | 需搭配-XX:CMSInitiatingOccupancyFraction=75设定触发阈值 | |
-XX:+PrintGCDetails | 打印详细GC日志 | 生产环境必开,配合-Xloggc:/path/gc.log | 用于诊断GC频率与停顿时间 | |
| 永久代/元空间 | -XX:PermSize | 永久代初始大小(JDK7-) | JDK8+已废弃 | JDK8+使用元空间替代,参数改为-XX:MetaspaceSize=256m |
-XX:MaxPermSize | 永久代最大大小 | |||
-XX:MaxMetaspaceSize | 元空间最大大小(JDK8+) | 建议1GB~2GB | 不受堆内存限制,但需监控防止泄漏 | |
| 线程与栈配置 | -Xss | 单个线程栈大小 | 128k~1M(默认1M) | 过小导致栈溢出,过大限制总线程数(经验上限5000线程) |
-XX:ParallelGCThreads | 并行GC线程数 | 等于CPU核心数 | 仅影响并行/并发回收器 | |
| 高级调优参数 | -XX:SurvivorRatio | Eden区与Survivor区比例(如8表示Eden:S0:S1=8:1:1) | 默认8,可微调至6~10 | 影响对象晋升老年代速度 |
-XX:NewRatio | 新生代与老年代比例(如2表示新生代:老年代=1:2) | 默认2,高临时对象场景可调至1 | 与-Xmn冲突时以-Xmn优先 | |
-XX:+DisableExplicitGC | 禁用System.gc()手动触发 | 生产环境建议启用 | 防止外部调用引发Full GC | |
-XX:+HeapDumpOnOutOfMemoryError | OOM时自动生成堆转储文件 | 必开,配合-XX:HeapDumpPath=/path/ | 用于事后分析内存泄漏 |
安全加固
- 禁用自动部署:
<Host autoDeploy="false"> - 关闭目录列表:在
web.xml中设置<init-param><param-name>listings</param-name><param-value>false</param-value></init-param> - 启用HSTS:在
server.xml的<Connector>中添加hstsEnabled="true" - 删除示例应用:清理
webapps/examples/和webapps/docs/减少攻击面 - 修改关闭指令:避免默认
SHUTDOWN指令(server.xml中的<Server port="8005" shutdown="NEW_PASSWORD">) - 限制管理界面:在
tomcat-users.xml限制manager-gui角色的IP访问
日志管理
- 定期轮转日志(如 Log4j 配置),避免
catalina.out过大占满磁盘
安装配置与部署
Oracle下载地址:https://www.oracle.com/cn/java/technologies/downloads/
安装JDK
# 解压
tar xvf jdk-8u281-linux-x64.tar.gz -C /usr/local
chown root:root /usr/local/jdk1.8.0_281
# 设置环境变量
cat >> /etc/profile << "EOF"
export JAVA_HOME=/usr/local/jdk1.8.0_281
export JRE_HOME=${JAVA_HOME}/jre
export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib:$CLASSPATH
export JAVA_PATH=${JAVA_HOME}/bin:${JRE_HOME}/bin
export PATH=$PATH:${JAVA_PATH}
EOF
source /etc/profile
# 查看版本
java -version安装 Tomcat
# Tomcat下载:
https://dlcdn.apache.org/tomcat/tomcat-9/v9.0.108/bin/apache-tomcat-9.0.108.tar.gz
# 解压
tar xf apache-tomcat-9.0.108.tar.gz -C /usr/local/
mv /usr/local/apache-tomcat-9.0.108 /usr/local/tomcat
# 可选的操作
echo 'export TOMCAT_HOME=/usr/local/tomcat' >>/etc/profile
source /etc/profileTomcat 操作
# 启动程序
/usr/local/tomcat/bin/startup.sh
# 关闭程序
/usr/local/tomcat/bin/shutdown.shTomcat-管理war包
基础单实例
# 上传war包到tomcat管理目录中,tomcat会自动解压memtest目录
/usr/local/tomcat/webapps/memtest.war
# 浏览器请求
http://192.168.148.101:8080/memtest/meminfo.jspTomcat多实例
复制Tomcat目录
# 比如8080单独的服务,8090单独的服务
cp -a /usr/local/tomcat /usr/local/tomcat_8080
cp -a /usr/local/tomcat /usr/local/tomcat_8090修改服务配置文件
vi /usr/local/tomcat_8090/conf/server.xml
# 修改tomcat服务端口
<Server port="8006" shutdown="SHUTDOWN">
# 对外提供服务的端口
<Connector port="8090" protocol="HTTP/1.1"
# 网站域名及网页根目录路径
<Host name="localhost" appBase="webapps"启动多实例
/usr/local/tomcat_8080/bin/startup.sh
/usr/local/tomcat_8090/bin/startup.sh
# 检测端口
ss -antup | grep javaTomcat集群
nginx 负载均衡
upstream tomcats{
ip_hash;
server 192.168.148.101:8080;
server 192.168.148.102:8080;
}
server {
listen 8080;
server_name localhost;
location / {
proxy_pass http://tomcats;
# 核心头设置
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# 连接优化
proxy_http_version 1.1;
proxy_set_header Connection "";
}
}