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 环境搭建

bash 复制代码
# 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 stop

User=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.target

EOF



# 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>

示例:

XML 复制代码
#备份元配置文件
cp /opt/tomcat/conf/server.xml /opt/tomcat/conf/server.xml.bak


vim /opt/tomcat/conf/server.xml
<?xml version="1.0" encoding="UTF-8"?>
<!--
  Licensed to the Apache Software Foundation (ASF) under one or more
  contributor license agreements.  See the NOTICE file distributed with
  this 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 with
  the License.  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed 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 and
  limitations under the License.
-->
<!-- Note:  A "Server" is not itself a "Container", so you may not
     define 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 resources
       Documentation at /docs/jndi-resources-howto.html
  -->
  <GlobalNamingResources>
    <!-- Editable user database that can also be used by
         UserDatabaseRealm 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 share
       a 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 received
         and responses are returned. Documentation at :
         HTTP Connector: /docs/config/http.html
         AJP  Connector: /docs/config/ajp.html
         Define 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/2
         This connector uses the NIO implementation. The default
         SSLImplementation will depend on the presence of the APR/native
         library and the useOpenSSL attribute of the AprLifecycleListener.
         Either JSSE or OpenSSL style configuration may be used regardless of
         the 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 processes
         every request.  The Engine implementation for Tomcat stand alone
         analyzes the HTTP headers included with the request, and passes them
         on 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 passwords
           via a brute-force attack -->
      <Realm className="org.apache.catalina.realm.LockOutRealm">
        <!-- This Realm uses the UserDatabase configured in the global JNDI
             resources under the key "UserDatabase".  Any edits
             that are performed against this UserDatabase are immediately
             available 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 applications
             Documentation at: /docs/config/valve.html -->
        <!--
        <Valve className="org.apache.catalina.authenticator.SingleSignOn" />
        -->

        <!-- Access log processes all example.
             Documentation at: /docs/config/valve.html
             Note: 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 &quot;%r&quot; %s %b" />

      </Host>
    </Engine>
  </Service>
</Server>

✅ 说明:

  • 使用 Http11Nio2Protocol(基于 Linux epoll 的异步非阻塞 IO),性能优于 BIO/NIO。
  • maxThreads=500 足够应对高并发;实际值应根据压测调整。
  • 启用 compression 减少带宽,提升前端加载速度。
  • enableLookups="false" 禁用 DNS 反查,避免延迟。

2. 调整系统文件描述符(高并发需要)

bash 复制代码
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

确保 不要包含以下已废弃的缓存属性:

bash 复制代码
<!-- ❌ 错误:Tomcat 11 中已完全移除这些属性 -->
<Resources cachingAllowed="true" cacheMaxSize="100000" />

4.操作系统调优

bash 复制代码
# 提高文件描述符限制(/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.验证安装与优化

bash 复制代码
# 检查服务状态
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
相关推荐
灰灰老师2 小时前
在Ubuntu22.04和24.04中安装Docker并安装和配置Java、Mysql、Tomcat
java·mysql·docker·tomcat
二宝1522 小时前
黑马商城day1-MyBatis-Plus
java·开发语言·mybatis
235162 小时前
【MQ】RabbitMQ:架构、工作模式、高可用与流程解析
java·分布式·架构·kafka·rabbitmq·rocketmq·java-rabbitmq
Porunarufu2 小时前
JAVA·类和对象③封装及包
java·开发语言
霍小毛3 小时前
Kubernetes云平台管理实战:滚动升级与秒级回滚
java·容器·kubernetes
代码充电宝3 小时前
LeetCode 算法题【简单】20. 有效的括号
java·算法·leetcode·面试·职场和发展
祈祷苍天赐我java之术3 小时前
Redis 的原子性操作
java·redis
wdfk_prog3 小时前
klist 迭代器初始化:klist_iter_init_node 与 klist_iter_init
java·前端·javascript
凸头3 小时前
Collections.synchronizedList()详解
java