Tomcat技术详解
目录
Tomcat简介
什么是Tomcat
Apache Tomcat是一个开源的Java Servlet容器,实现了Java Servlet、JavaServer Pages (JSP)、Java Expression Language (EL)和WebSocket技术规范。它是Apache软件基金会的一个项目,是目前最流行的Java Web应用服务器之一。
核心特性
- Servlet容器:完全实现Java Servlet 4.0规范
- JSP支持:支持JavaServer Pages 2.3规范
- 轻量级:相比完整的应用服务器,Tomcat更加轻量
- 可扩展性:支持集群和负载均衡
- 跨平台:支持Windows、Linux、macOS等操作系统
- 开源免费:Apache许可证,完全免费使用
版本历史
| 版本 | 发布时间 | Java版本 | Servlet规范 | JSP规范 | 重要特性 |
|---|---|---|---|---|---|
| 10.x | 2021 | Java 8+ | 5.0 | 3.0 | Jakarta EE |
| 9.x | 2017 | Java 8+ | 4.0 | 2.3 | HTTP/2支持 |
| 8.x | 2014 | Java 7+ | 3.1 | 2.3 | WebSocket |
| 7.x | 2011 | Java 6+ | 3.0 | 2.2 | 注解支持 |
Tomcat架构
整体架构
层次结构图
Tomcat Server
├── Service 1
│ ├── Connector (HTTP:8080)
│ ├── Connector (AJP:8009)
│ └── Engine
│ ├── Host (localhost)
│ │ ├── Context (/app1)
│ │ ├── Context (/app2)
│ │ └── Context (/manager)
│ └── Host (example.com)
│ └── Context (/)
└── Service 2 (可选)
├── Connector (HTTPS:8443)
└── Engine
└── Host (secure.example.com)
请求处理流程图
核心组件
| 组件 | 作用 | 说明 | 包含关系 |
|---|---|---|---|
| Server | Tomcat的顶级组件 | 代表整个Tomcat实例,负责启动和关闭整个服务器 | 包含一个或多个Service |
| Service | 服务组件 | 将Connector和Engine关联起来,提供完整的服务 | 包含多个Connector和一个Engine |
| Engine | 请求处理引擎 | 接收来自Connector的请求,进行路由和处理 | 包含一个或多个Host |
| Host | 虚拟主机 | 代表一个域名,处理特定域名的请求 | 包含一个或多个Context |
| Context | Web应用上下文 | 对应一个Web应用程序,管理应用的生命周期 | 包含多个Wrapper |
| Connector | 连接器 | 处理客户端连接,支持多种协议 | 独立组件,与Engine配合工作 |
| Wrapper | 包装器 | 包装单个Servlet,管理Servlet的生命周期 | 被Context包含 |
组件详细说明
Server(服务器)
- 职责:Tomcat的顶级容器,管理整个服务器的生命周期
- 配置:在
server.xml的根元素中定义 - 端口:默认监听8005端口用于关闭命令
Service(服务)
- 职责:将Connector和Engine组合成完整的服务
- 特点:一个Server可以包含多个Service
- 配置:在
server.xml中通过<Service>元素定义
Engine(引擎)
- 职责:请求处理的核心,负责请求路由和响应生成
- 特点:每个Service只能有一个Engine
- 配置:通过
defaultHost属性指定默认主机
Host(虚拟主机)
- 职责:处理特定域名的请求
- 特点:支持多个虚拟主机,通过域名区分
- 配置:通过
appBase属性指定应用部署目录
Context(应用上下文)
- 职责:管理单个Web应用的生命周期
- 特点:每个Context对应一个Web应用
- 配置:可以独立配置,支持热部署
Connector(连接器)
- 职责:处理客户端连接,支持多种协议
- 协议:HTTP/1.1、HTTP/2、AJP、HTTPS
- 配置:可以配置多个Connector监听不同端口
Tomcat安装与配置
安装方式
1. 二进制安装
# 下载Tomcat
wget https://archive.apache.org/dist/tomcat/tomcat-9/v9.0.xx/bin/apache-tomcat-9.0.xx.tar.gz
# 解压
tar -xzf apache-tomcat-9.0.xx.tar.gz
# 移动到目标目录
sudo mv apache-tomcat-9.0.xx /opt/tomcat
# 设置权限
sudo chown -R tomcat:tomcat /opt/tomcat
sudo chmod +x /opt/tomcat/bin/*.sh
2. 包管理器安装
# Ubuntu/Debian
sudo apt-get install tomcat9
# CentOS/RHEL
sudo yum install tomcat
# 使用systemd管理
sudo systemctl start tomcat
sudo systemctl enable tomcat
3. Docker安装
# Dockerfile
FROM tomcat:9.0-jdk11-openjdk
COPY myapp.war /usr/local/tomcat/webapps/
EXPOSE 8080
# 运行容器
docker run -d -p 8080:8080 --name my-tomcat tomcat:9.0
目录结构
tomcat/
├── bin/ # 可执行文件
│ ├── startup.sh # 启动脚本
│ ├── shutdown.sh # 关闭脚本
│ ├── catalina.sh # 核心脚本
│ └── setenv.sh # 环境变量设置
├── conf/ # 配置文件
│ ├── server.xml # 主配置文件
│ ├── web.xml # 全局Web配置
│ ├── context.xml # 上下文配置
│ └── logging.properties # 日志配置
├── lib/ # 共享库文件
├── logs/ # 日志文件
│ ├── catalina.out # 控制台输出
│ ├── localhost.log # 应用日志
│ └── manager.log # 管理日志
├── temp/ # 临时文件
├── webapps/ # Web应用目录
│ ├── ROOT/ # 根应用
│ ├── manager/ # 管理应用
│ └── host-manager/ # 主机管理
└── work/ # 工作目录
Tomcat使用方式
基本操作
1. 启动Tomcat
# 方式1:使用startup脚本
./bin/startup.sh
# 方式2:使用catalina脚本
./bin/catalina.sh start
# 方式3:后台启动
nohup ./bin/startup.sh &
# 方式4:使用systemd(如果已安装为服务)
sudo systemctl start tomcat
2. 停止Tomcat
# 方式1:使用shutdown脚本
./bin/shutdown.sh
# 方式2:使用catalina脚本
./bin/catalina.sh stop
# 方式3:强制停止
./bin/catalina.sh stop -force
# 方式4:使用systemd
sudo systemctl stop tomcat
3. 重启Tomcat
# 方式1:先停止再启动
./bin/shutdown.sh && ./bin/startup.sh
# 方式2:使用catalina脚本
./bin/catalina.sh restart
# 方式3:使用systemd
sudo systemctl restart tomcat
部署Web应用
1. 静态部署
# 将WAR文件复制到webapps目录
cp myapp.war /opt/tomcat/webapps/
# 或者解压到目录
mkdir /opt/tomcat/webapps/myapp
unzip myapp.war -d /opt/tomcat/webapps/myapp/
2. 动态部署
# 使用Tomcat Manager
curl -X PUT "http://localhost:8080/manager/text/deploy?path=/myapp" \
-F "deploy=@myapp.war"
# 使用Tomcat Manager Web界面
# 访问 http://localhost:8080/manager/html
3. 热部署
<!-- 在server.xml中配置 -->
<Context path="/myapp" docBase="/path/to/myapp" reloadable="true" />
配置文件管理
server.xml配置示例
<?xml version="1.0" encoding="UTF-8"?>
<Server port="8005" shutdown="SHUTDOWN">
<Service name="Catalina">
<!-- HTTP连接器 -->
<Connector port="8080"
protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443"
maxThreads="200"
minSpareThreads="10"
maxSpareThreads="50"
acceptCount="100" />
<!-- AJP连接器 -->
<Connector port="8009"
protocol="AJP/1.3"
redirectPort="8443" />
<!-- 引擎 -->
<Engine name="Catalina" defaultHost="localhost">
<Host name="localhost"
appBase="webapps"
unpackWARs="true"
autoDeploy="true">
<Context path="/myapp"
docBase="/path/to/myapp"
reloadable="true" />
</Host>
</Engine>
</Service>
</Server>
Tomcat参数调优
JVM参数调优
1. 内存设置
# 在setenv.sh中设置
export CATALINA_OPTS="$CATALINA_OPTS -Xms2g -Xmx4g"
export CATALINA_OPTS="$CATALINA_OPTS -XX:MetaspaceSize=256m"
export CATALINA_OPTS="$CATALINA_OPTS -XX:MaxMetaspaceSize=512m"
2. 垃圾回收优化
# G1垃圾回收器
export CATALINA_OPTS="$CATALINA_OPTS -XX:+UseG1GC"
export CATALINA_OPTS="$CATALINA_OPTS -XX:MaxGCPauseMillis=200"
export CATALINA_OPTS="$CATALINA_OPTS -XX:G1HeapRegionSize=16m"
# 或者使用Parallel GC
export CATALINA_OPTS="$CATALINA_OPTS -XX:+UseParallelGC"
export CATALINA_OPTS="$CATALINA_OPTS -XX:ParallelGCThreads=4"
3. 性能监控
# 启用JMX监控
export CATALINA_OPTS="$CATALINA_OPTS -Dcom.sun.management.jmxremote"
export CATALINA_OPTS="$CATALINA_OPTS -Dcom.sun.management.jmxremote.port=9999"
export CATALINA_OPTS="$CATALINA_OPTS -Dcom.sun.management.jmxremote.authenticate=false"
export CATALINA_OPTS="$CATALINA_OPTS -Dcom.sun.management.jmxremote.ssl=false"
连接器参数调优
1. HTTP连接器优化
<Connector port="8080"
protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443"
maxThreads="200" <!-- 最大工作线程数 -->
minSpareThreads="10" <!-- 最小空闲线程数 -->
maxSpareThreads="50" <!-- 最大空闲线程数 -->
acceptCount="100" <!-- 等待队列长度 -->
maxConnections="8192" <!-- 最大连接数 -->
compression="on" <!-- 启用压缩 -->
compressionMinSize="2048" <!-- 压缩最小大小 -->
compressableMimeType="text/html,text/xml,text/plain,text/css,text/javascript,application/javascript,application/json"
enableLookups="false" <!-- 禁用DNS查询 -->
URIEncoding="UTF-8" /> <!-- URI编码 -->
2. NIO连接器配置
<Connector port="8080"
protocol="org.apache.coyote.http11.Http11NioProtocol"
connectionTimeout="20000"
maxThreads="200"
minSpareThreads="10"
maxSpareThreads="50"
acceptCount="100"
maxConnections="8192"
acceptorThreadCount="2" <!-- 接收线程数 -->
pollerThreadCount="2" <!-- 轮询线程数 -->
selectorTimeout="1000" /> <!-- 选择器超时 -->
应用级优化
1. 会话管理优化
<!-- 在context.xml中配置 -->
<Context>
<Manager className="org.apache.catalina.session.StandardManager"
maxActiveSessions="1000"
maxInactiveInterval="1800"
sessionIdLength="32" />
</Context>
2. 静态资源优化
<!-- 在web.xml中配置 -->
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.css</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.js</url-pattern>
</servlet-mapping>
与其他容器对比
主流Java应用服务器对比
| 特性 | Tomcat | Jetty | Undertow | WildFly | WebLogic |
|---|---|---|---|---|---|
| 类型 | Servlet容器 | Servlet容器 | Servlet容器 | 完整应用服务器 | 商业应用服务器 |
| 大小 | 轻量级 | 极轻量级 | 轻量级 | 重量级 | 重量级 |
| 启动速度 | 快 | 很快 | 很快 | 慢 | 很慢 |
| 内存占用 | 中等 | 少 | 少 | 多 | 很多 |
| 配置复杂度 | 简单 | 简单 | 简单 | 复杂 | 复杂 |
| 集群支持 | 需要额外配置 | 需要额外配置 | 需要额外配置 | 内置 | 内置 |
| 管理界面 | 基础 | 基础 | 无 | 丰富 | 丰富 |
| 许可证 | Apache 2.0 | Apache 2.0 | Apache 2.0 | LGPL | 商业 |
| 学习曲线 | 平缓 | 平缓 | 平缓 | 陡峭 | 陡峭 |
详细对比分析
1. Tomcat vs Jetty
Tomcat优势:
- 更成熟稳定
- 社区支持更好
- 文档更完善
- 与Spring生态集成更好
Jetty优势:
- 启动更快
- 内存占用更少
- 嵌入式部署更简单
- 异步处理性能更好
// Jetty嵌入式示例
public class JettyServer {
public static void main(String[] args) throws Exception {
Server server = new Server(8080);
ServletContextHandler context = new ServletContextHandler();
context.setContextPath("/");
context.addServlet(HelloServlet.class, "/hello");
server.setHandler(context);
server.start();
}
}
2. Tomcat vs Undertow
Tomcat优势:
- 更广泛使用
- 配置更灵活
- 管理功能更丰富
Undertow优势:
- 性能更高
- 内存占用更少
- 支持HTTP/2
- 异步处理能力强
// Undertow配置示例
public class UndertowServer {
public static void main(String[] args) {
Undertow server = Undertow.builder()
.addHttpListener(8080, "localhost")
.setHandler(exchange -> {
exchange.getResponseHeaders().put(Headers.CONTENT_TYPE, "text/plain");
exchange.getResponseSender().send("Hello World");
}).build();
server.start();
}
}
3. 选择建议
选择Tomcat的情况:
- 传统Web应用
- 需要稳定可靠的服务
- 团队对Tomcat更熟悉
- 需要丰富的管理功能
选择Jetty的情况:
- 嵌入式应用
- 微服务架构
- 对启动速度要求高
- 资源受限环境
选择Undertow的情况:
- 高并发应用
- 对性能要求极高
- 需要HTTP/2支持
- 异步处理场景
Spring Boot集成Tomcat
默认集成
Spring Boot默认内嵌Tomcat,无需额外配置即可使用。
<!-- Maven依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
// Spring Boot应用
@SpringBootApplication
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
Tomcat配置
1. 基本配置
# application.yml
server:
port: 8080
servlet:
context-path: /myapp
tomcat:
threads:
max: 200
min-spare: 10
max-connections: 8192
accept-count: 100
connection-timeout: 20000
compression:
enabled: true
min-response-size: 2048
mime-types: text/html,text/xml,text/plain,text/css,text/javascript,application/javascript,application/json
2. 高级配置
server:
tomcat:
uri-encoding: UTF-8
max-http-form-post-size: 2MB
max-swallow-size: 2MB
processor-cache: 200
additional-tld-skip-patterns: "*.jar"
remote-ip-header: x-forwarded-for
protocol-header: x-forwarded-proto
port-header: x-forwarded-port
3. 自定义Tomcat配置
@Configuration
public class TomcatConfig {
@Bean
public TomcatServletWebServerFactory tomcatServletWebServerFactory() {
return new TomcatServletWebServerFactory() {
@Override
protected void postProcessContext(Context context) {
// 自定义上下文配置
context.setSessionTimeout(30);
context.setSessionCookieName("JSESSIONID");
}
};
}
@Bean
public WebServerFactoryCustomizer<TomcatServletWebServerFactory> tomcatCustomizer() {
return factory -> {
factory.addConnectorCustomizers(connector -> {
Http11NioProtocol protocol = (Http11NioProtocol) connector.getProtocolHandler();
protocol.setMaxThreads(200);
protocol.setMinSpareThreads(10);
protocol.setMaxSpareThreads(50);
protocol.setAcceptCount(100);
protocol.setMaxConnections(8192);
});
};
}
}
替换为其他容器
1. 替换为Jetty
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>
2. 替换为Undertow
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-undertow</artifactId>
</dependency>
性能优化配置
1. JVM参数优化
# 启动参数
java -Xms2g -Xmx4g -XX:+UseG1GC -XX:MaxGCPauseMillis=200 \
-jar myapp.jar
2. 应用配置优化
spring:
datasource:
hikari:
maximum-pool-size: 20
minimum-idle: 5
connection-timeout: 20000
idle-timeout: 300000
max-lifetime: 1200000
jpa:
hibernate:
ddl-auto: none
show-sql: false
properties:
hibernate:
jdbc:
batch_size: 20
order_inserts: true
order_updates: true
性能监控与故障排查
监控工具
1. JMX监控
@Configuration
public class JmxConfig {
@Bean
public MBeanServer mBeanServer() {
return ManagementFactory.getPlatformMBeanServer();
}
@Bean
public TomcatMetrics tomcatMetrics() {
return new TomcatMetrics();
}
}
2. Actuator监控
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
management:
endpoints:
web:
exposure:
include: health,info,metrics,prometheus
endpoint:
health:
show-details: always
metrics:
export:
prometheus:
enabled: true
3. 自定义监控
@Component
public class TomcatMonitor {
private final MeterRegistry meterRegistry;
public TomcatMonitor(MeterRegistry meterRegistry) {
this.meterRegistry = meterRegistry;
}
@EventListener
public void handleRequest(RequestEvent event) {
Timer.Sample sample = Timer.start(meterRegistry);
// 处理请求
sample.stop(Timer.builder("tomcat.request.duration")
.tag("method", event.getRequest().getMethod())
.register(meterRegistry));
}
}
常见问题排查
1. 内存泄漏
# 生成堆转储
jmap -dump:format=b,file=heap.hprof <pid>
# 分析堆转储
jhat heap.hprof
2. 线程问题
# 查看线程状态
jstack <pid>
# 查看线程CPU使用
top -H -p <pid>
3. 连接问题
# 查看网络连接
netstat -an | grep :8080
# 查看连接数
ss -tuln | grep :8080
日志配置
1. 访问日志
<!-- 在server.xml中配置 -->
<Valve className="org.apache.catalina.valves.AccessLogValve"
directory="logs"
prefix="localhost_access_log"
suffix=".txt"
pattern="%h %l %u %t "%r" %s %b %D" />
2. 应用日志
logging:
level:
org.apache.catalina: INFO
org.apache.coyote: INFO
org.apache.tomcat: INFO
pattern:
console: "%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n"
file: "%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n"
file:
name: logs/application.log
max-size: 100MB
max-history: 30
最佳实践
1. 生产环境配置
安全配置
<!-- 禁用不必要的方法 -->
<security-constraint>
<web-resource-collection>
<web-resource-name>Disable TRACE</web-resource-name>
<url-pattern>/*</url-pattern>
<http-method>TRACE</http-method>
</web-resource-collection>
<auth-constraint/>
</security-constraint>
性能配置
server:
tomcat:
threads:
max: 200
min-spare: 10
max-connections: 8192
accept-count: 100
connection-timeout: 20000
compression:
enabled: true
min-response-size: 2048
2. 集群配置
负载均衡配置
<!-- 在server.xml中配置 -->
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster">
<Manager className="org.apache.catalina.ha.session.DeltaManager"
expireSessionsOnShutdown="false"
notifyListenersOnReplication="true"/>
<Channel className="org.apache.catalina.tribes.group.GroupChannel">
<Membership className="org.apache.catalina.tribes.membership.McastService"
address="228.0.0.4"
port="45564"
frequency="500"
dropTime="3000"/>
<Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"
address="auto"
port="4000"
autoBind="100"
selectorTimeout="5000"
maxThreads="6"/>
<Sender className="org.apache.catalina.tribes.transport.ReplicationTransmitter">
<Transport className="org.apache.catalina.tribes.transport.nio.PooledParallelSender"/>
</Sender>
<Interceptor className="org.apache.catalina.tribes.group.interceptors.TcpFailureDetector"/>
<Interceptor className="org.apache.catalina.tribes.group.interceptors.MessageDispatch15Interceptor"/>
</Channel>
<Valve className="org.apache.catalina.ha.tcp.ReplicationValve"
filter=""/>
<Valve className="org.apache.catalina.ha.session.JvmRouteBinderValve"/>
<Deployer className="org.apache.catalina.ha.deploy.FarmWarDeployer"
tempDir="/tmp/war-temp/"
deployDir="/tmp/war-deploy/"
watchDir="/tmp/war-listen/"
watchEnabled="false"/>
<ClusterListener className="org.apache.catalina.ha.session.JvmRouteSessionIDBinderListener"/>
<ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/>
</Cluster>
3. 监控告警
健康检查
@Component
public class TomcatHealthIndicator implements HealthIndicator {
@Override
public Health health() {
try {
// 检查Tomcat状态
MBeanServer server = ManagementFactory.getPlatformMBeanServer();
ObjectName objectName = new ObjectName("Catalina:type=Server");
String state = (String) server.getAttribute(objectName, "stateName");
if ("STARTED".equals(state)) {
return Health.up()
.withDetail("tomcat", "running")
.withDetail("state", state)
.build();
} else {
return Health.down()
.withDetail("tomcat", "not running")
.withDetail("state", state)
.build();
}
} catch (Exception e) {
return Health.down()
.withDetail("tomcat", "error")
.withDetail("error", e.getMessage())
.build();
}
}
}
4. 部署策略
蓝绿部署
#!/bin/bash
# 蓝绿部署脚本
# 停止旧版本
./bin/shutdown.sh
# 备份当前版本
cp -r webapps/myapp webapps/myapp.backup.$(date +%Y%m%d_%H%M%S)
# 部署新版本
cp new-version.war webapps/myapp.war
# 启动新版本
./bin/startup.sh
# 健康检查
sleep 30
if curl -f http://localhost:8080/myapp/health; then
echo "Deployment successful"
else
echo "Deployment failed, rolling back"
./bin/shutdown.sh
rm -rf webapps/myapp
mv webapps/myapp.backup.$(date +%Y%m%d_%H%M%S) webapps/myapp
./bin/startup.sh
fi
总结
Tomcat作为最流行的Java Servlet容器,具有以下优势:
主要优势
- 成熟稳定:经过多年发展,非常稳定可靠
- 轻量级:相比完整应用服务器,资源占用较少
- 易于配置:配置简单,学习成本低
- 社区支持:活跃的社区和丰富的文档
- Spring集成:与Spring Boot完美集成
适用场景
- 传统Web应用
- 微服务架构
- 开发和测试环境
- 中小型企业应用
- Spring Boot应用
选择建议
- 新项目:推荐使用Spring Boot + 内嵌Tomcat
- 传统项目:可以继续使用独立Tomcat
- 高并发场景:考虑Undertow或Jetty
- 企业级应用:考虑WildFly或WebLogic
学习建议
- 从基础配置开始,逐步深入
- 关注性能调优和监控
- 了解集群和负载均衡
- 掌握故障排查技能
- 关注新版本特性和最佳实践
12万+

被折叠的 条评论
为什么被折叠?



