Tomcat核心架构与生产部署指南
一、Tomcat核心架构与工作原理
-
核心组件
-
Server:顶层容器,管理所有Service实例,监听8005端口(shutdown命令)
-
Service:包含Connector(接收请求)和Engine(处理请求)的组合,支持多协议集成
-
Connector:分HTTP/1.1(8080端口)和AJP(8009端口),负责将字节流转换为ServletRequest对象
-
Container:分Engine→Host→Context→Wrapper四级,逐层解析请求
-
-
工作流程
二、零基础部署指南(生产环境配置)
1. 环境准备
1.1 jdk25介绍:
https://www.cnblogs.com/javastack/p/19097137
可用的 OpenJDK JDK 版本(按版本号排序):
版本 | 状态 | 说明 |
---|---|---|
OpenJDK 8 | 可用 | 兼容旧系统 |
OpenJDK 11 | 可用 | 兼容旧系统 |
OpenJDK 17 | 可用 | 企业稳定环境(已有系统) |
OpenJDK 21 | 可用 | LTS(2023 年发布),功能较新,企业稳定环境、长期维护 |
OpenJDK 25 | 可用 | 最新LTS,(2025年9月16日发布),功能最新 新项目、长期维护 |
1.2 Alibaba Dragonwell JDK 介绍:
https://help.aliyun.com/zh/ecs/user-guide/deploy-alibaba-dragonwell-jdk#695822a319ejn
1.3tomcat11 介绍
https://tomcat.apache.org/tomcat-11.0-doc/index.html
1.4 环境搭建
# 1 JDK安装(必须Java 8+)
# 1.1apt源更新
apt update
apt list -a openjdk-*-jdk# 1.2 安装以及核实版本
apt install openjdk-25-jdk -y
java --version# 1.3 设置JAVA_HOME
readlink -f $(which java) | sed "s:bin/java::"
echo "export JAVA_HOME=/usr/lib/jvm/java-25-openjdk-amd64" | sudo tee -a /etc/environme
nt
export JAVA_HOME=/usr/lib/jvm/java-25-openjdk-amd64
source /etc/environment
echo $JAVA_HOME# 1.4 Tomcat安装(以Linux为例)
wget https://dlcdn.apache.org/tomcat/tomcat-11/v11.0.13/bin/apache-tomcat-11.0.13.tar.gz
tar zxvf apache-tomcat-11.0.13.tar.gz -C /opt
ln -s /opt/apache-tomcat-11.0.13 /opt/tomcat# 1.5 创建专用用户并设置权限
root@D-3PGMZJ3-0948:/opt/tomcat# useradd -r -m -U -d /opt/tomcat -s /bin/false tomcat
useradd: warning: the home directory /opt/tomcat already exists.
useradd: Not copying any file from skel directory into it.
chown -R tomcat:tomcat /opt/tomcat
chown -R tomcat:tomcat /opt/apache-tomcat-11.0.13
chmod -R 750 /opt/apache-tomcat-11.0.13# 1.6 配置 systemd 服务(便于管理)
tee /etc/systemd/system/tomcat.service << EOF
[Unit]
Description=Apache Tomcat 11 Web Application Container
After=network.target[Service]
Type=forking# 指定 JDK 25 路径
Environment=JAVA_HOME=/usr/lib/jvm/java-25-openjdk-amd64
Environment=CATALINA_PID=/opt/tomcat/temp/tomcat.pid
Environment=CATALINA_HOME=/opt/tomcat
Environment=CATALINA_BASE=/opt/tomcat
# 合并 JVM 参数
Environment='CATALINA_OPTS=\-Xms2g -Xmx2g \-XX:MetaspaceSize=256m \-XX:MaxMetaspaceSize=512m \-XX:+UseG1GC \-XX:MaxGCPauseMillis=200 \-Djava.awt.headless=true \-Djava.security.egd=file:/dev/./urandom \-Duser.timezone=Asia/Shanghai'
Environment='JAVA_OPTS=-Djava.awt.headless=true'# 内存参数 -Xms2g -Xmx2g 可根据你的服务器内存调整(如 1G、4G 等)。# 直接调用 catalina.sh 而非 startup.sh
ExecStart=/opt/tomcat/bin/catalina.sh start
ExecStop=/opt/tomcat/bin/catalina.sh stopUser=tomcat
Group=tomcat
UMask=0007
RestartSec=10
Restart=always# 增加超时时间(根据应用启动时间调整)
TimeoutStartSec=180
TimeoutStopSec=180# 确保 temp 目录存在(可选但推荐)
ExecStartPre=/bin/mkdir -p /opt/tomcat/temp
ExecStartPre=/bin/chown -R tomcat:tomcat /opt/tomcat# ... 其他配置 ...
LimitNOFILE=65536
LimitNPROC=65536[Install]
WantedBy=multi-user.targetEOF# 1.7 启动tomcat
systemctl daemon-reload
systemctl enable --now tomcat
systemctl status tomcat
2. 安全加固
1. 删除示例应用(生产环境不需要)
rm -rf /opt/tomcat/webapps/{docs,examples,host-manager,manager}
⚠️ 如果你需要使用 Manager App,请保留
manager
,但务必限制访问(见下文)。
2. (可选)启用 Manager 并限制 IP
若需保留 Manager:
sudo cp -r /opt/tomcat/webapps.dist/manager /opt/tomcat/webapps/
编辑访问控制:
vim /opt/tomcat/webapps/manager/META-INF/context.xml
修改 <Valve>
部分,仅允许本地或指定 IP:
<Context antiResourceLocking="false" privileged="true"><Valve className="org.apache.catalina.valves.RemoteAddrValve"allow="127\.0\.0\.1|::1|192\.168\.1\.\d+"denyStatus="403" />
</Context>
3. 设置 Manager 用户(如启用)
vim /opt/tomcat/conf/tomcat-users.xml
在 <tomcat-users>
标签内添加:
<role rolename="manager-gui"/>
<user username="admin" password="StrongPassword123!" roles="manager-gui"/>
🔒 务必使用强密码!
3. 性能优化(Tomcat 11 + JDK 25)
1.server.xml
优化(位于 $CATALINA_HOME/conf/server.xml
)
替换 <Service name="Catalina">
内容为以下配置:
<Service name="Catalina"><!-- 高性能线程池 --><Executor name="tomcatThreadPool"namePrefix="catalina-exec-"maxThreads="500"minSpareThreads="50"maxIdleTime="60000"prestartminSpareThreads="true"threadPriority="5" /><!-- NIO2 协议 + 压缩 + 安全优化 --><Connector executor="tomcatThreadPool"port="8080"protocol="org.apache.coyote.http11.Http11Nio2Protocol"connectionTimeout="20000"maxConnections="10000"acceptorThreadCount="2"keepAliveTimeout="60000"maxKeepAliveRequests="100"disableUploadTimeout="true"enableLookups="false"URIEncoding="UTF-8"compression="on"compressionMinSize="2048"compressibleMimeType="text/html,text/xml,text/plain,text/css,text/javascript,application/json,application/javascript" /><!-- Engine 和 Host 保持默认即可 --><Engine name="Catalina" defaultHost="localhost"><Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true" /></Engine></Service>
示例:
#备份元配置文件
cp /opt/tomcat/conf/server.xml /opt/tomcat/conf/server.xml.bakvim /opt/tomcat/conf/server.xml
<?xml version="1.0" encoding="UTF-8"?>
<!--Licensed to the Apache Software Foundation (ASF) under one or morecontributor license agreements. See the NOTICE file distributed withthis work for additional information regarding copyright ownership.The ASF licenses this file to You under the Apache License, Version 2.0(the "License"); you may not use this file except in compliance withthe License. You may obtain a copy of the License athttp://www.apache.org/licenses/LICENSE-2.0Unless required by applicable law or agreed to in writing, softwaredistributed under the License is distributed on an "AS IS" BASIS,WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.See the License for the specific language governing permissions andlimitations under the License.
-->
<!-- Note: A "Server" is not itself a "Container", so you may notdefine subcomponents such as "Valves" at this level.Documentation at /docs/config/server.html-->
<Server port="8005" shutdown="SHUTDOWN"><Listener className="org.apache.catalina.startup.VersionLoggerListener" /><!-- Security listener. Documentation at /docs/config/listeners.html<Listener className="org.apache.catalina.security.SecurityListener" />--><!-- OpenSSL support using Tomcat Native --><Listener className="org.apache.catalina.core.AprLifecycleListener" /><!-- OpenSSL support using FFM API from Java 22 --><!-- <Listener className="org.apache.catalina.core.OpenSSLLifecycleListener" /> --><!-- Prevent memory leaks due to use of particular java/javax APIs--><Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" /><Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" /><Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" /><!-- Global JNDI resourcesDocumentation at /docs/jndi-resources-howto.html--><GlobalNamingResources><!-- Editable user database that can also be used byUserDatabaseRealm to authenticate users--><Resource name="UserDatabase" auth="Container"type="org.apache.catalina.UserDatabase"description="User database that can be updated and saved"factory="org.apache.catalina.users.MemoryUserDatabaseFactory"pathname="conf/tomcat-users.xml" /></GlobalNamingResources><!-- A "Service" is a collection of one or more "Connectors" that sharea single "Container" Note: A "Service" is not itself a "Container",so you may not define subcomponents such as "Valves" at this level.Documentation at /docs/config/service.html--><Service name="Catalina"><!--The connectors can use a shared executor, you can define one or more named thread pools--><!--<Executor name="tomcatThreadPool" namePrefix="catalina-exec-"maxThreads="150" minSpareThreads="4"/>--><!-- 高性能线程池 --><Executor name="tomcatThreadPool"namePrefix="catalina-exec-"maxThreads="500"minSpareThreads="50"maxIdleTime="60000"prestartminSpareThreads="true"threadPriority="5" /><!-- A "Connector" represents an endpoint by which requests are receivedand responses are returned. Documentation at :HTTP Connector: /docs/config/http.htmlAJP Connector: /docs/config/ajp.htmlDefine a non-SSL/TLS HTTP/1.1 Connector on port 8080--><Connector port="8080" protocol="HTTP/1.1"connectionTimeout="20000"redirectPort="8443" /><!-- A "Connector" using the shared thread pool--><!--<Connector executor="tomcatThreadPool"port="8080" protocol="HTTP/1.1"connectionTimeout="20000"redirectPort="8443" />--><!-- NIO2 协议 + 压缩 + 安全优化 --><Connector executor="tomcatThreadPool"port="8080"protocol="org.apache.coyote.http11.Http11Nio2Protocol"connectionTimeout="20000"maxConnections="10000"acceptorThreadCount="2"keepAliveTimeout="60000"maxKeepAliveRequests="100"disableUploadTimeout="true"enableLookups="false"URIEncoding="UTF-8"compression="on"compressionMinSize="2048"compressibleMimeType="text/html,text/xml,text/plain,text/css,text/javascript,application/json,application/javascript" /><!-- Define an SSL/TLS HTTP/1.1 Connector on port 8443 with HTTP/2This connector uses the NIO implementation. The defaultSSLImplementation will depend on the presence of the APR/nativelibrary and the useOpenSSL attribute of the AprLifecycleListener.Either JSSE or OpenSSL style configuration may be used regardless ofthe SSLImplementation selected. JSSE style configuration is used below.--><!--<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"maxThreads="150" SSLEnabled="true"><UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol" /><SSLHostConfig><Certificate certificateKeystoreFile="conf/localhost-rsa.jks"certificateKeystorePassword="changeit" type="RSA" /></SSLHostConfig></Connector>--><!-- Define an AJP 1.3 Connector on port 8009 --><!--<Connector protocol="AJP/1.3"address="::1"port="8009"redirectPort="8443" />--><!-- An Engine represents the entry point (within Catalina) that processesevery request. The Engine implementation for Tomcat stand aloneanalyzes the HTTP headers included with the request, and passes themon to the appropriate Host (virtual host).Documentation at /docs/config/engine.html --><!-- You should set jvmRoute to support load-balancing via AJP ie :<Engine name="Catalina" defaultHost="localhost" jvmRoute="jvm1">--><Engine name="Catalina" defaultHost="localhost"><!--For clustering, please take a look at documentation at:/docs/cluster-howto.html (simple how to)/docs/config/cluster.html (reference documentation) --><!--<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>--><!-- Use the LockOutRealm to prevent attempts to guess user passwordsvia a brute-force attack --><Realm className="org.apache.catalina.realm.LockOutRealm"><!-- This Realm uses the UserDatabase configured in the global JNDIresources under the key "UserDatabase". Any editsthat are performed against this UserDatabase are immediatelyavailable for use by the Realm. --><Realm className="org.apache.catalina.realm.UserDatabaseRealm"resourceName="UserDatabase"/></Realm><Host name="localhost" appBase="webapps"unpackWARs="true" autoDeploy="true"><!-- SingleSignOn valve, share authentication between web applicationsDocumentation at: /docs/config/valve.html --><!--<Valve className="org.apache.catalina.authenticator.SingleSignOn" />--><!-- Access log processes all example.Documentation at: /docs/config/valve.htmlNote: The pattern used is equivalent to using pattern="common" --><Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"prefix="localhost_access_log" suffix=".txt"pattern="%h %l %u %t "%r" %s %b" /></Host></Engine></Service>
</Server>
✅ 说明:
- 使用
Http11Nio2Protocol
(基于 Linux epoll 的异步非阻塞 IO),性能优于 BIO/NIO。maxThreads=500
足够应对高并发;实际值应根据压测调整。- 启用
compression
减少带宽,提升前端加载速度。enableLookups="false"
禁用 DNS 反查,避免延迟。
2. 调整系统文件描述符(高并发需要)
echo -e "* soft nofile 65536\n* hard nofile 65536" | sudo tee -a /etc/security/limits.conf
echo "session required pam_limits.so" | sudo tee -a /etc/pam.d/common-session
3. context.xml
清理(位于 $CATALINA_HOME/conf/context.xml
)
确保 不要包含以下已废弃的缓存属性:
<!-- ❌ 错误:Tomcat 11 中已完全移除这些属性 -->
<Resources cachingAllowed="true" cacheMaxSize="100000" />
4.操作系统调优:
# 提高文件描述符限制(/etc/security/limits.conf)
tomcat soft nofile 65536
tomcat hard nofile 65536# 调整内核网络参数(/etc/sysctl.conf)
net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 65535
4.验证安装与优化
# 检查服务状态
systemctl daemon-reload
systemctl restart tomcat
systemctl status tomcat# 测试 HTTP 响应
curl -I http://localhost:8080# 查看 JVM 参数
ps -ef | grep tomcat# 查看监听端口
ss -tuln | grep 8080# 查看日志
sudo journalctl -u tomcat -f