tomcat原理与安装

参考:tomcat下载jdk1.8下载

一、前言

  • Tomcat 是一款开源的 Java Servlet 容器(同时支持 JSP、EL、WebSocket 等 Java EE 规范),核心作用是运行 Java Web 应用,本质是一个基于 TCP 协议的服务器(底层处理网络通信)+ Java Web 规范的实现(管理 Servlet/JSP 生命周期、处理请求响应)。
  • 要理解 Tomcat 原理,核心围绕「请求如何从客户端到达 Web 应用,再返回响应」展开,需拆解其架构、核心组件、请求处理流程三大核心部分。

二、Tomcat 整体架构

2.1、架构层级

Tomcat 采用「分层架构」,从底层到上层依次解决「网络通信」「协议解析」「请求分发」「应用运行」的问题,核心组件按功能可分为 4 层:

层级核心组件作用
网络层(底层)Endpoint(Connector 内置)处理 TCP 连接(监听端口、接收请求字节流),是 Tomcat 与客户端的网络入口。
协议层Processor(Connector 内置)将 TCP 字节流解析为 HTTP 协议格式(请求行、请求头、请求体),或反向封装响应。
连接 / 线程层Executor(线程池)管理线程资源,通过线程池处理并发请求(避免频繁创建销毁线程)。
应用层Engine/Host/Context/Wrapper按层级分发请求到具体 Web 应用,管理 Servlet 生命周期(核心业务层)。
  • 关键组件详解

    1. Connector(连接器):对外通信入口

      • 作用:监听端口(如 8080)、接收客户端 TCP 连接,将网络字节流解析为 HTTP 协议请求,最终转为 Servlet 规范的 ServletRequest,转交给容器。
      • 关键子组件
        • Endpoint:底层网络通信,监听指定端口(如 8080),处理 TCP 连接。
        • Processor:协议解析,将 Endpoint 读取的字节流解析 HTTP 协议。
    2. Container(容器):对内处理核心

      • Container 是 Tomcat 的「内部处理核心」,负责接收 Connector 转发的请求,按层级分发到具体 Web 应用,并调用 Servlet 处理。容器是一个「层级结构」,从顶到下依次为:
        • Engine‌:Tomcat的引擎组件,负责管理多个虚拟站点(Host)。
        • Host‌:代表一个虚拟主机或站点,可以配置多个Context来处理不同的Web应用程序。
        • Context‌:表示一个Web应用程序的上下文环境,是Web应用程序的运行环境。
        • Wrapper‌:表示一个Servlet,是容器中最底层的组件,直接处理请求并返回响应。
    3. 辅助组件

      • Executor(线程池):Tomcat 的线程管理组件,核心参数:最大线程数、核心线程数、队列容量。
      • 类加载器:避免不同 Web 应用类冲突;

2.2、工作流程

  • 启动初始化: Tomcat 启动时,解析配置文件,创建连接器、容器、线程池等组件;
  • 接收请求: 连接器监听端口,接收客户端请求,完成 TCP 连接、协议解析与请求对象转换;
  • 处理请求: 按 Engine→Host→Context→Wrapper 层级分发请求,调用目标 Servlet 处理业务(已初始化则直接复用,未初始化则完成加载 - 实例化 - 初始化流程);
  • 响应请求: 连接器将 ServletResponse 转为网络字节流,通过 TCP 连接返回给客户端。

2.3、tomcat目录结构

目录核心作用
bin存放启动(startup)、关闭(shutdown)等可执行文件
conf核心配置目录:server.xml(全局配置如端口)、web.xml(默认应用配置)等
webappsWeb 应用部署目录:放 WAR 包或应用文件夹,自动部署(含默认 ROOT 应用)
logs日志目录:catalina.out 等核心日志,用于问题排查
lib全局依赖库:所有 Web 应用共享的 JAR 包(如数据库驱动)
workJSP 编译缓存目录:JSP 转 Servlet 的.class 文件存放地,修改 JSP 未生效可删除

三、安装部署

  • 环境准备

    ip地址系统tomcatjdk
    192.168.189.134麒麟v10 x868.5.100jdk-8u461-linux-x64
  • 软件下载 在参考链接,自行下载最新包, 8.5.100是8.5的最终章:2025年11月16日

  • jdk准备

    mkdir /data/
    tar xf jdk-8u461-linux-x64.tar.gz 
    mv jdk1.8.0_461/ /data/
    cd /data/
    ln -sv jdk1.8.0_461/ jdk1.8
    chmod 777 jdk1.8 -R
    
    # 增加 JAVA_HOME环境变量
    [root@localhost data]# tail -2 /etc/profile
    export JAVA_HOME=/data/jdk1.8
    export PATH=$JAVA_HOME/bin:$PATH
    
    [root@localhost data]# java -version   <--- 测试
    java version "1.8.0_461"
    Java(TM) SE Runtime Environment (build 1.8.0_461-b11)
    Java HotSpot(TM) 64-Bit Server VM (build 25.461-b11, mixed mode)
    
  • tomcat准备

    • 部署

      # 将apache-tomcat-8.5.100.zip放到/data/目录
      unzip apache-tomcat-8.5.100.zip 
      mv apache-tomcat-8.5.100 tomcat
      chmod 777 tomcat/ -R
      
    • 优化

      1. tomcat/bin/jvm.properties <–新增

        # 根据现场需求自定义  Xms跟Xmx 大小需要保持一致 如4G
        -Xms2G -Xmx2G -Xmn512m -XX:MetaspaceSize=512m -XX:MaxMetaspaceSize=1024m
        
      2. tomcat/bin/javahome.properties <–新增

        /data/jdk1.8     <--- 添加这一行
        
      3. tomcat/bin/log.properties <–新增

        # 说明: 隐藏 catalina.out日志 
        /dev/null
        
      4. tomcat/config/logging.propertie

        # 删除这几行
        2localhost.org.apache.juli.AsyncFileHandler.level = FINE
        2localhost.org.apache.juli.AsyncFileHandler.directory = ${catalina.base}/logs
        2localhost.org.apache.juli.AsyncFileHandler.prefix = localhost.
        2localhost.org.apache.juli.AsyncFileHandler.encoding = UTF-8
        
        3manager.org.apache.juli.AsyncFileHandler.level = FINE
        3manager.org.apache.juli.AsyncFileHandler.directory = ${catalina.base}/logs
        3manager.org.apache.juli.AsyncFileHandler.prefix = manager.
        3manager.org.apache.juli.AsyncFileHandler.encoding = UTF-8
        
        4host-manager.org.apache.juli.AsyncFileHandler.level = FINE
        4host-manager.org.apache.juli.AsyncFileHandler.directory = ${catalina.base}/logs
        4host-manager.org.apache.juli.AsyncFileHandler.prefix = host-manager.
        4host-manager.org.apache.juli.AsyncFileHandler.encoding = UTF-8
        
        添加这一行
        1catalina.org.apache.juli.AsyncFileHandler.maxDays = 30
        
      5. tomcat隐藏版本号

        • 进入tomcat的lib目录找到catalina.jar文件

          unzip catalina.jar之后会多出两个文件夹
          
          • 进入cd org/apache/catalina/util 编辑配置文件ServerInfo.properties

            # 修改成下面这样,隐藏版本号
            #server.info=Apache Tomcat/8.5.100
            #server.number=8.5.100.0
            #server.built=Mar 19 2024 13:54:42 UTC
            #server.built.iso=2024-03-19
            
            server.info=server
            server.number=0.0.0.0
            server.built=2025/11/16   <-- 最好时间也改成0000/00/00
            
          • 压缩回文件

            # 将解压并修改的文件在打回文件内
            jar uvf catalina.jar org/apache/catalina/util/ServerInfo.properties
            正在添加: org/apache/catalina/util/ServerInfo.properties(输入 = 975) (输出 = 551)(压缩了 43%)
            
      6. 服务启动路径修改

        vi /data/tomcat/bin/startup.sh 
        #!/bin/sh
        cd /data/tomcat/bin   <--- startup.sh 第二行新增 如下路径,路径需是实际路径
        
      7. tomcat/bin/catalina.sh

        #!/bin/sh 下面添加就行
        CATALINA_HOME=/data/tomcat
        JAVA_HOME=`cat ${CATALINA_HOME}/conf/javahome.properties`
        JRE_HOME=`cat ${CATALINA_HOME}/conf/javahome.properties`/jre
        JVM=`cat  ${CATALINA_HOME}/conf/jvm.properties`
        JAVA_OPTS="-Djava.awt.headless=true -Dfile.encoding=UTF-8 -Dsun.jnu.encoding=UTF-8 -server $JVM  -XX:+DisableExplicitGC"
        CATALINA_OUT=`cat  ${CATALINA_HOME}/conf/log.properties`
        
      8. tomcat/conf/server.xml

        <?xml version='1.0' encoding='utf-8'?>
        <Server port="-1" shutdown="SHUTDsdfasdfOWN">
          <Listener className="org.apache.catalina.startup.VersionLoggerListener" />
          <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
          <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
          <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
          <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />
        
          <GlobalNamingResources>
            <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>
        
          <Executor name="tomcatThreadPool" 
            namePrefix="catalina-exec-"
            maxThreads="20000"
            minSpareThreads="100"
            maxQueueSize="100"
            prestartminSpareThreads="true"/>
        
          <Service name="Catalina">
              <Connector executor="tomcatThreadPool" port="8090"  protocol="HTTP/1.1"
                allowUnsafeRenegotiation="false"
                connectionTimeout="30000"
                connectionUploadTimeout="150000"
                relaxedQueryChars="[]|{}^&#x5c;&#x60;&quot;&lt;&gt;"
                relaxedPathChars="|{}[],%\"
                keepAliveTimeout="120000"
                enableLookups="false"
                maxPostSize="10485760"
                URIEncoding="UTF-8"
                acceptCount="100"
                maxKeepAliveRequests="1"
                acceptorThreadCount="2"
                disableUploadTimeout="false"
                maxConnections="10000"
                compression="on"
                compressionMinSize="2048"
                noCompressionUserAgents="gozilla, traviata"
                compressableMimeType="text/html,text/xml,text/javascript,text/css,text/plain,image/gif,image/jpg,image/png"
                />
        
            <Engine name="Catalina" defaultHost="localhost">
              <Realm className="org.apache.catalina.realm.LockOutRealm">
                <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
                       resourceName="UserDatabase"/>
              </Realm>
        
              <Host name="localhost"  appBase="webapps"
                    unpackWARs="true" autoDeploy="true">
        	    <Valve className="org.apache.catalina.valves.ErrorReportValve" showReport="false" showServerInfo="false" />
              </Host>
            </Engine>
          </Service>
        </Server>
        
      9. tomcat/conf/context.xml

        <Context>
            <WatchedResource>WEB-INF/web.xml</WatchedResource>
            <WatchedResource>${catalina.base}/conf/web.xml</WatchedResource>
        
            # 这里几行是添加的内容,上面两行是默认的
            <Resources
                cachingAllowed="true"
                cacheMaxSize="102400"
            />
        </Context>
        
      10. 删除多余的应用 <— 等服务启动完访问ok之后,给它清掉

        在 tomcat/webapps 里面执行
        rm -rf  tomcat/webapps/*
        
      11. 配置自启

        vim /usr/lib/systemd/system/tomcat.service  <-- 自已定义名称  服务名称.service
        [Unit]
        Description=securedoc
        
        [Service]
        Type=forking
        ExecStart=/data/tomcat/bin/startup.sh
        ExecStop=/data/tomcat/bin/shutdown.sh
        PrivateTmp=true
        LimitNOFILE=65535
        LimitNPROC=65535
        
        [Install]
        WantedBy=multi-user.target
        
      12. 配置启动

        systemctl daemon-reload
        systemctl start tomcat
        systemctl status tomcat
        
      13. 最后访问

        [root@localhost conf]# curl -i http://192.168.189.134:8090/
        HTTP/1.1 200 
        Content-Type: text/html;charset=UTF-8
        Transfer-Encoding: chunked
        Date: Sun, 16 Nov 2025 13:53:14 GMT
        
        <!DOCTYPE html>   <--- 会打印一堆html页面, 确认ok之后操作第10步 然后重启
        <html lang="en"><head><meta charset="UTF-8" />
        
      14. 整包要压缩好,容器、prometheus或者其它情况下还要用。

Logo

中国智能体开发者社区,聚焦智能体与大模型开发,提供前沿资讯、实用工具链、开源项目及行业案例。通过技术沙龙、开发者大赛等活动,促进经验交流与协作,助力开发者快速构建创新智能应用。

更多推荐