linux服务-tomcat原理与安装
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 生命周期(核心业务层)。 |
-
关键组件详解
-
Connector(连接器):对外通信入口
- 作用:监听端口(如 8080)、接收客户端 TCP 连接,将网络字节流解析为 HTTP 协议请求,最终转为 Servlet 规范的
ServletRequest,转交给容器。 - 关键子组件
- Endpoint:底层网络通信,监听指定端口(如 8080),处理 TCP 连接。
- Processor:协议解析,将 Endpoint 读取的字节流解析 HTTP 协议。
- 作用:监听端口(如 8080)、接收客户端 TCP 连接,将网络字节流解析为 HTTP 协议请求,最终转为 Servlet 规范的
-
Container(容器):对内处理核心
- Container 是 Tomcat 的「内部处理核心」,负责接收 Connector 转发的请求,按层级分发到具体 Web 应用,并调用 Servlet 处理。容器是一个「层级结构」,从顶到下依次为:
- Engine:Tomcat的引擎组件,负责管理多个虚拟站点(Host)。
- Host:代表一个虚拟主机或站点,可以配置多个Context来处理不同的Web应用程序。
- Context:表示一个Web应用程序的上下文环境,是Web应用程序的运行环境。
- Wrapper:表示一个Servlet,是容器中最底层的组件,直接处理请求并返回响应。
- Container 是 Tomcat 的「内部处理核心」,负责接收 Connector 转发的请求,按层级分发到具体 Web 应用,并调用 Servlet 处理。容器是一个「层级结构」,从顶到下依次为:
-
辅助组件
- 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(默认应用配置)等 |
| webapps | Web 应用部署目录:放 WAR 包或应用文件夹,自动部署(含默认 ROOT 应用) |
| logs | 日志目录:catalina.out 等核心日志,用于问题排查 |
| lib | 全局依赖库:所有 Web 应用共享的 JAR 包(如数据库驱动) |
| work | JSP 编译缓存目录:JSP 转 Servlet 的.class 文件存放地,修改 JSP 未生效可删除 |
三、安装部署
-
环境准备
ip地址 系统 tomcat jdk 192.168.189.134 麒麟v10 x86 8.5.100 jdk-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 -
优化
-
tomcat/bin/jvm.properties <–新增
# 根据现场需求自定义 Xms跟Xmx 大小需要保持一致 如4G -Xms2G -Xmx2G -Xmn512m -XX:MetaspaceSize=512m -XX:MaxMetaspaceSize=1024m -
tomcat/bin/javahome.properties <–新增
/data/jdk1.8 <--- 添加这一行 -
tomcat/bin/log.properties <–新增
# 说明: 隐藏 catalina.out日志 /dev/null -
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-83manager.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-84host-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 -
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-19server.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%)
-
-
-
服务启动路径修改
vi /data/tomcat/bin/startup.sh #!/bin/sh cd /data/tomcat/bin <--- startup.sh 第二行新增 如下路径,路径需是实际路径 -
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` -
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="[]|{}^\`"<>"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> -
tomcat/conf/context.xml
<Context><WatchedResource>WEB-INF/web.xml</WatchedResource><WatchedResource>${catalina.base}/conf/web.xml</WatchedResource># 这里几行是添加的内容,上面两行是默认的<ResourcescachingAllowed="true"cacheMaxSize="102400"/> </Context> -
删除多余的应用 <— 等服务启动完访问ok之后,给它清掉
在 tomcat/webapps 里面执行 rm -rf tomcat/webapps/* -
配置自启
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 -
配置启动
systemctl daemon-reload systemctl start tomcat systemctl status tomcat -
最后访问
[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" /> -
整包要压缩好,容器、prometheus或者其它情况下还要用。
-
-
