Tomcat安装配置与部署完整指南:从JDK匹配到生产环境调优

发布时间:2026/9/29 5:36:53
Tomcat安装配置与部署完整指南:从JDK匹配到生产环境调优 Tomcat 可能是 Java Web 开发里被提起最多、又被低估最多的组件。刚接触 Java Web 时总觉得它就是解压、启动、部署三步结果真到自己在公司配环境、在服务器上部署项目才发现从下载到稳定跑起来中间藏着不少容易忽略的细节。这两年 Spring Boot 内置 Tomcat 用得太顺手很多人甚至忘了传统 Web 项目仍然要面对独立 Tomcat 的安装配置。这篇文章不是把官方文档翻译一遍而是我这些年配了无数台 Tomcat 环境之后整理的完整流程和踩坑记录2024 年版本把下载、安装配置、项目部署、常见报错全部串起来讲一遍适合刚学 JavaWeb 的学生、需要在服务器上手动部署项目的运维或后端开发也适合想在 IDEA 里把 Tomcat 配明白的人。1. 安装前的版本选择先解决 JDK 和 Tomcat 的匹配问题很多人的第一步就错了。下载 Tomcat 之前完全不看自己的 JDK 版本随手装了最新版结果启动时报UnsupportedClassVersionError或者各种奇怪的类加载异常排查半天才发现是版本不匹配。1.1 Tomcat 版本与 JDK 的兼容关系Tomcat 本身是用 Java 写的 Servlet 容器它跑在 JVM 上所以它对 JDK 版本有硬性要求。我用一张表把常见版本说清楚Tomcat 主版本当前状态最低 JDK 版本Servlet 规范包名Tomcat 8.5.x维护期JDK 73.1javax.*Tomcat 9.0.x广泛使用JDK 84.0javax.*Tomcat 10.0.x已停止维护JDK 85.0jakarta.*Tomcat 10.1.x当前稳定版JDK 116.0jakarta.*Tomcat 11.0.x最新发布JDK 176.1jakarta.*这里有个关键转折点Tomcat 10 开始Servlet API 的包名从javax.servlet改成了jakarta.servlet。这不是小事。如果你手上是个老项目代码里全是import javax.servlet.http.HttpServlet那扔到 Tomcat 10 以上版本里基本跑不起来启动时会直接抛java.lang.NoClassDefFoundError: javax/servlet/http/HttpServlet。1.2 生产环境到底该选哪个版本根据我这几年在不同项目里的实操经验建议这么选如果是学习 JavaWeb、用 SSM 或 SpringMVC 的老教程、维护老项目选 Tomcat 9.0.x。它基于 javax 命名空间兼容性最好资料最多踩坑也最少。如果做新项目用 Spring Boot 3.x 拉出来的传统 WAR 包或者打算用最新规范选 Tomcat 10.1.x。这是当前官方主推的稳定版本基于 jakarta 命名空间。Tomcat 11 太新生产环境里用的还不多想尝鲜可以但别在核心业务上冒险。另外注意Tomcat 已经是开源项目你完全可以下载老版本但别用 Tomcat 7 及以下版本了那些连 JDK 8 的新特性都撑不住安全补丁也没人管。1.3 JDK 安装与环境变量检查安装 Tomcat 之前先确认 JDK 装好、JAVA_HOME 配好。先执行这三条命令java -version javac -version echo $JAVA_HOMEWindows 上如果没配过环境变量按下面的流程操作下载并安装 JDK 8、11 或 17记住安装路径比如C:\Program Files\Java\jdk-17.0.10打开系统环境变量设置新建JAVA_HOME值就是 JDK 安装路径在Path中新增%JAVA_HOME%\bin重开一个命令行窗口执行java -version验证Linux 上一般是编辑/etc/profile或者~/.bashrcexport JAVA_HOME/usr/local/jdk-17.0.10 export PATH$JAVA_HOME/bin:$PATH然后source /etc/profile让它生效。还有一点我特别强调不要只装 JRE。虽然 Tomcat 启动本身用 JRE 就行但 JSP 在运行期需要编译成 Servlet编译要依赖 JDK 里的javac。只装 JRE 的机器上部署 JSP 项目十有八九会报编译类找不到到时候又得回来装 JDK何必绕这一圈。2. 下载与安装Windows 和 Linux 两条线完整走一遍2.1 Windows 上最稳的安装方式解压版Tomcat 官方提供两种 Windows 安装包一种是.zip的解压版一种是.exe的安装版。我的建议是直接用解压版原因很简单解压版不受 Windows 服务机制干扰环境变量、目录结构、启动方式完全可控出问题也方便定位。下载时认准官网tomcat.apache.org进入对应版本页面在 “Core” 区域选择 64-bit Windows zip。解压到目录时有个容易踩的坑路径里尽量不要有中文和空格。比如解压到D:\dev\apache-tomcat-10.1.30而不要放到D:\Program Files\Tomcat 10这种带空格的路径。虽然 Tomcat 在大多数情况下能处理空格但有些老项目或者命令行脚本会在路径解析上出问题别给自己找麻烦。解压完成后进入bin目录双击startup.bat。如果环境变量配好了会弹出一个新窗口里面打印 Tomcat 启动日志最后显示一行Server startup in [xxx] milliseconds这时打开浏览器访问http://localhost:8080能看到 Tomcat 默认首页页面左上角有个小猫图标说明安装成功。2.2 Linux 服务器部署用 tar 包别用包管理器Linux 上安装 Tomcat有人习惯用yum install tomcat或者apt install tomcat。我实测过多次系统仓库里的 Tomcat 版本往往很旧而且目录结构和官方 tar 包不一样后面配路径、配部署目录时容易混乱。生产环境我习惯用官方 tar 包手动部署步骤很固定# 创建专用用户不要用 root 跑 Tomcat sudo groupadd tomcat sudo useradd -s /bin/false -g tomcat -d /opt/tomcat tomcat # 下载并解压 cd /tmp wget https://dlcdn.apache.org/tomcat/tomcat-10/v10.1.30/bin/apache-tomcat-10.1.30.tar.gz sudo mkdir -p /opt/tomcat sudo tar xzf apache-tomcat-10.1.30.tar.gz -C /opt/tomcat --strip-components1 # 设置目录权限 sudo chown -R tomcat:tomcat /opt/tomcat sudo chmod x /opt/tomcat/bin/*.sh # 启动 sudo -u tomcat /opt/tomcat/bin/startup.sh启动后验证一下日志和端口tail -f /opt/tomcat/logs/catalina.out ss -lntp | grep 8080如果系统开启了防火墙还需要放行 8080 端口这个后面在报错部分会详细说。2.3 目录结构必须搞清楚Tomcat 解压出来后里面有一堆目录很多新手分不清webapps和work的区别。我把核心目录的作用整理一下目录作用注意事项bin启动、关闭脚本Windows 下是 .batLinux 下是 .shconf核心配置文件包括 server.xml、web.xml、tomcat-users.xml 等libTomcat 自身依赖的 jar这里的 jar 被所有应用共享别乱放logs日志目录catalina.out 是最重要的日志文件webapps默认部署目录把 war 包丢进来Tomcat 自动解压部署workJSP 编译后的临时文件清理缓存时删除这个目录下的内容temp临时文件一般不用管有个常见坑有些人把项目依赖的 jar 直接扔进lib目录这是非常危险的操作。lib里的 jar 是全局共享的一旦你的项目用的某个第三方包和另一个项目版本冲突就会引发各种诡异的ClassNotFoundException或者方法找不到的报错。项目自己的依赖应该打进 war 包不要丢到全局lib里。3. 核心配置server.xml 和 tomcat-users.xml 的逐项说明安装完 Tomcat下一步绝对不是直接部署项目而是先了解配置文件。90% 的启动问题和部署问题根源都在conf/server.xml和conf/tomcat-users.xml上。3.1 server.xml 里的端口和连接器打开conf/server.xml你会看到几个关键节点Server port8005 shutdownSHUTDOWN这是 Tomcat 的控制端口用来接收关闭命令。理论上这个端口不对外网开放但如果有安全要求建议修改默认值。Connector port8080 protocolHTTP/1.1 connectionTimeout20000 redirectPort8443这是 HTTP 访问入口默认端口 8080。Connector port8009 protocolAJP/1.3AJP 端口用来和 Apache 或 Nginx 做集成。如果不用 AJP 协议建议直接注释掉减少攻击面。修改端口时直接改port属性就行。比如我想把 HTTP 端口改成 8081Connector port8081 protocolHTTP/1.1 connectionTimeout20000 redirectPort8443 /改完端口后必须重启 Tomcat。这里有个细节修改端口前先用命令检查那个端口是否被占用。Windows 下用netstat -ano | findstr 8081Linux 下用ss -lntp | grep 8081。我之前遇到过有同事把端口改成 8080结果那台机器上已经跑了一个 Nginx 占着 8080改完一启动直接报地址冲突本来就该先检查环境再动手。3.2 Host 配置与多站点部署默认配置里有一个 HostHost namelocalhost appBasewebapps unpackWARstrue autoDeploytrueappBase指定了这个虚拟主机的应用存放目录默认是webapps。unpackWARstrue表示 WAR 包部署时自动解压成目录autoDeploytrue表示在运行期间如果 webapps 目录下新增了 war 包会自动部署开发环境下很方便但生产环境建议把autoDeploy设成false避免误操作导致线上应用被覆盖或者重启。如果你需要在一台 Tomcat 上跑多个域名可以新增 Host 节点Host namedemo.example.com appBase/data/webapps unpackWARstrue autoDeploytrue /Host每个 Host 对应一个独立的域名和独立的应用目录。需要注意的是新增 Host 后还要去 DNS 解析对应域名到这台服务器否则访问不了。3.3 配置 Manager 的用户和权限Tomcat 自带一个管理后台路径是http://localhost:8080/manager/html可以用来在线部署和热更新 WAR 包。但默认情况下 Manager 没有任何可用账号需要手动在conf/tomcat-users.xml里配置tomcat-users role rolenamemanager-gui/ role rolenamemanager-script/ user usernameadmin passwordadmin123 rolesmanager-gui,manager-script/ /tomcat-users配置完重启 Tomcat就能用这个账号登录 Manager 界面了。注意角色区分manager-gui是网页管理界面的角色manager-script是给脚本远程调用用的角色。如果只想用网页管理配置manager-gui就够了。这里提醒一句Manager 默认只允许本机访问也就是Remote Address会被限制为127.0.0.1。如果要从其他机器访问需要编辑webapps/manager/META-INF/context.xml把Valve节点的 allow 规则放宽或者直接用 Nginx 做反向代理再加认证生产环境不要裸奔。4. 部署 Web 项目三种常用方式与 IDEA 联动Tomcat 装好、配置好后真正的工作才开始——把项目部署进去。我按使用频率和数据量来介绍这几种方式。4.1 直接丢 war 包到 webapps这是最原始也最可靠的部署方式。打包好的 WAR 包往webapps目录一放Tomcat 会自动解压并部署。例如你把myapp.war放进webappsTomcat 解压后会自动生成myapp目录访问路径是http://localhost:8080/myapp/如果你想让它作为根路径访问也就是访问http://localhost:8080/直接进入应用有两种方式一种是把 war 包改名为ROOT.war另一种是删掉原有的ROOT目录把你的应用解压后改成ROOT目录。部署过程中有个细节值得注意更新应用时先停 Tomcat再删除旧的 war 和解压目录然后丢进新 war 包最后启动。有人图省事直接在运行状态下把新的 war 包覆盖进去结果 Tomcat 解压逻辑混乱有可能解压一半失败导致应用起不来。生产环境这一步千万不能图快。另外work目录下会缓存 JSP 编译后的 class 文件。如果你修改了 JSP 文件但访问时还是旧页面多半是缓存问题。稳妥做法是停止 Tomcat删除work目录下对应项目的缓存再启动。4.2 通过 Manager 在线部署如果 Tomcat 在远程服务器上你不想每次用命令上传文件可以用 Manager 界面。登录http://ip:8080/manager/html后在 “WAR file to deploy” 区域选择本地 WAR 包点击 DeployTomcat 会自动完成部署。这个方式适合测试环境验证包是否正常但生产环境我还是建议走脚本化部署把 WAR 包先推到服务器再用命令移动到webapps减少人为操作带来的风险。4.3 IDEA 里配置 Tomcat开发调试最常用如果你用 IntelliJ IDEA 做 JavaWeb 开发可以把 Tomcat 集成到 IDE 里这样启动、断点调试、热部署都方便。配置步骤如下打开Run - Edit Configurations左上角点选择Tomcat Server - Local在Application server那里点击Configure选择 Tomcat 解压路径JRE选择你本机的 JDK 版本切到Deployment标签点选择Artifact然后选项目的war exploded方式在Application context里设置访问路径例如/myapp点运行IDEA 会启动 Tomcat 并自动打开浏览器这里有个新手很容易理解错的地方war和war exploded的区别。war是打包成压缩包再部署war exploded是直接解压后的目录结构。开发调试时选war exploded因为这样可以支持热部署改 JSP 或静态资源不用重启war适合最终部署到服务器时用。4.4 javax 和 jakarta 的兼容性判断这节是给老项目准备的。如果你的项目还依赖javax.servlet但在 Tomcat 10.1 上部署启动时大概率报类似下面的错误java.lang.NoClassDefFoundError: javax/servlet/http/HttpServlet原因就是前面说的Tomcat 10 开始 Servlet API 改名了。遇到这种情况最省事的解决办法是换回 Tomcat 9。想用新 Tomcat 的话就得把代码里的import javax.servlet.*全部改成import jakarta.servlet.*同时还要检查第三方依赖是否已经兼容 Jakarta 命名空间改动量不小。所以我在公司里遇到老项目一律建议先锁死 Tomcat 9不要为了用新版本而给自己挖坑。5. 常见报错与完整排查链路从启动闪退到 404这一节是文章的重头戏。我按实际出现的频率排列这些报错并且不是直接丢答案而是给出排查思路——因为真正的生产环境报错往往不会和教科书上一模一样掌握了定位方法才能举一反三。5.1 双击 startup.bat 闪退这是最常见的入门问题。双击startup.bat后弹出一个黑色窗口一闪而过就消失了Tomcat 没启动。排查思路不要双击打开 cmd手动进入 Tomcat 的bin目录执行startup.bat这样错误信息就会留在当前命令行窗口里不闪退。绝大多数情况下你看到的错误是The JAVA_HOME environment variable is not defined correctly意思是JAVA_HOME没配或者配错了。检查系统环境变量里是否设置了JAVA_HOME指向的是 JDK 安装目录而不是bin目录设置完后重新开一个 cmd 窗口再执行。还有一种情况是 JAVA_HOME 配置正确但提示Cannot find .\bin\catalina.bat这说明你执行脚本的当前目录不对。解决办法先cd到 Tomcat 的bin目录再执行startup.bat。Linux 上也有对应的现象但报错形式不同。如果启动时报Permission denied说明脚本没有执行权限执行chmod x /opt/tomcat/bin/*.sh5.2 端口被占用启动日志里出现SEVERE: Failed to initialize end point associated with ProtocolHandler Caused by: java.net.BindException: Address already in use: bind这表示 8080 端口被其他进程占用了。排查链路Windows 下netstat -ano | findstr :8080 tasklist | findstr [PID] taskkill /PID [PID] /FLinux 下lsof -i:8080 # 或者 ss -lntp | grep 8080 kill -9 [PID]如果这个端口确实被其他业务占用不想杀进程那就修改server.xml中的端口改完重启。改完新端口后记得检查防火墙是否放行了新端口。5.3 内存溢出OOM 的两种典型形态Tomcat 跑一段时间后日志里出现java.lang.OutOfMemoryError: Java heap space这是堆内存不足常见于项目并发量大或者应用本身存在内存泄漏。还有一种是java.lang.OutOfMemoryError: PermGen space这是老版本 JDK 7 及以下常见的永久代内存不足。JDK 8 之后永久代被元空间 Metaspace 取代报错变成了Metaspace溢出。解决思路是在启动脚本里加大 JVM 内存。不建议直接改catalina.batWindows或catalina.shLinux而是新建一个setenv.bat或setenv.sh放在bin目录下Tomcat 启动时会自动读取。Linux 下我一般这么写export CATALINA_OPTS-Xms512m -Xmx1024m -XX:MaxMetaspaceSize256mWindows 下新建setenv.batset CATALINA_OPTS-Xms512m -Xmx1024m -XX:MaxMetaspaceSize256m参数解析-Xms512mJVM 初始堆内存大小-Xmx1024mJVM 最大堆内存-Xmx和-Xms建议设置成一样避免运行期动态伸缩带来性能损耗-XX:MaxMetaspaceSize256m元空间上限不是越大越好根据应用实际情况调设置的大小要综合考虑服务器物理内存。比如服务器只有 2G 内存你给 Tomcat 设置-Xmx1536m系统还要留内存给操作系统和其他进程跑不了多久就会触发系统 OOM Killer直接把进程杀了。5.4 项目部署后访问 404部署 war 包后访问http://localhost:8080/myapp/出现 404。排查链路按顺序来检查 war 包是否解压成功看webapps目录下有没有生成myapp目录检查访问路径大小写Linux 下路径严格区分大小写类名、资源路径、URL 的大小写必须和实际一致检查work目录缓存清理work目录后重启检查项目日志logs/localhost.2024-xx-xx.log会记录应用部署时的详细异常比 catalina.out 更容易定位问题如果访问的是 Tomcat 根路径出现 404基本就是ROOT应用没有了或者没部署成功。还有一个容易混淆的 404JSP 或 Servlet 路径配置问题。比如 Servlet 上的注解是WebServlet(/user/list)你必须访问http://localhost:8080/myapp/user/list前面要带项目上下文路径。新手经常漏掉/myapp这一段访问http://localhost:8080/user/list自然 404。5.5 访问 Manager 界面被拒绝或 403登录 Manager 时提示 403 Access Denied。排查思路确认tomcat-users.xml里配置的用户和角色是否正确确认角色名称写对没有网页界面需要manager-gui不是manager-script也不是admin那是老版本 Tomcat 的角色名确认是不是从远程访问Manager 默认只允许本机访问远程访问需要修改webapps/manager/META-INF/context.xml把Valve标签里的allow127\.\d\.\d\.\d|::1|0:0:0:0:0:0:0:1放宽实际工作中Manager 界面远程访问的情况我基本不推荐直接开放的更稳妥的方式是用 Nginx 做一层反向代理然后再加一层访问认证。5.6 日志中文乱码Windows 下运行 Tomcat日志里中文全是乱码这是控制台编码和 JVM 编码不一致导致的。常见的解决方法是把conf/logging.properties里java.util.logging.ConsoleHandler.encoding从 UTF-8 改成 GBK或者反过来。更通用的做法是在setenv.bat里强制指定 JVM 文件编码set CATALINA_OPTS-Dfile.encodingUTF-8另外Web 应用自身的响应乱码不是 Tomcat 的问题是应用代码里页面编码没设置对。JSP 页面头部要写pageEncodingUTF-8Servlet 里 response 要设置response.setCharacterEncoding(UTF-8)。6. 生产环境调优连接器线程数、JVM 参数与日志切割Tomcat 跑起来只是第一步真正上线后要面对的是并发、日志、稳定性这些实际问题。这里分享几个我常用的调优配置。6.1 连接器参数调整默认的连接器配置只保证了“能跑”没考虑“跑得好”。我一般在server.xml里这样调整Connector port8080 protocolHTTP/1.1 maxThreads400 acceptCount200 minSpareThreads50 connectionTimeout20000 compressionon compressionMinSize2048 compressibleMimeTypetext/html,text/xml,text/plain,text/css,application/json/参数含义maxThreadsTomcat 能处理请求的最大线程数默认 200。并发高可以往上调但不是越大越好线程多了 CPU 上下文切换开销也大要根据机器核数来定acceptCount请求队列的长度。当所有线程都忙时新的请求会进入队列等待默认 100minSpareThreads最小空闲线程数相当于常驻线程池的大小避免高峰期临时创建线程的延迟compression开启 HTTP 压缩对文本类内容效果明显connectionTimeout连接超时时间单位毫秒默认 20000 就是 20 秒如果前面有 Nginx 做反向代理Tomcat 的maxThreads不需要设置太大。Nginx 会吃掉大部分静态资源请求排队也可以由 Nginx 的proxy_buffering机制缓冲Tomcat 后端线程数给到 200 到 400 通常足够了压得太高反而拖垮数据库连接池。6.2 使用 setenv.sh 集中管理 JVM 参数前面说过建议用setenv.sh而不是直接改catalina.sh这是有工程化原因的。catalina.sh是 Tomcat 自带的启动脚本每次升级 Tomcat 都可能被覆盖setenv.sh是约定俗成的外部配置入口Tomcat 启动时自动加载升级时不会被覆盖。你在服务器上配置的话应该是这样的# ${CATALINA_BASE}/bin/setenv.sh export JAVA_HOME/usr/local/jdk-17.0.10 export CATALINA_OPTS-Xms1g -Xmx1g -XX:MaxMetaspaceSize256m -Djava.awt.headlesstrue再加几个我常用的 JVM 参数-XX:UseG1GC -XX:HeapDumpOnOutOfMemoryError -XX:HeapDumpPath/opt/tomcat/logs/heapdump.hprofUseG1GC是 JDK 9 之后的默认垃圾回收器不用额外设置也行HeapDumpOnOutOfMemoryError这个参数强烈建议加上一旦发生 OOMJVM 会自动把堆内存快照写到指定目录线上排查内存泄漏全靠这个快照文件。6.3 日志切割catalina.out 无限增大的问题Linux 下 Tomcat 的catalina.out默认会无限增长跑上几个月能到几十个 G直接把磁盘撑爆。我之前接过一个生产事故就是磁盘被 catalina.out 写满导致整个服务宕机。从那以后我在每台服务器上都会配置日志切割。用logrotate是最省事的方式。创建/etc/logrotate.d/tomcat/opt/tomcat/logs/catalina.out { daily rotate 7 copytruncate compress missingok }含义是每天切割一次保留 7 份历史日志切割后压缩copytruncate保证不中断 Tomcat 正在写入的日志句柄。配置完后可以用logrotate -f /etc/logrotate.d/tomcat手动验证。另外Tomcat 自身通过logging.properties生成的日志是按天滚动的不用额外处理只有catalina.out因为是被控制台输出重定向的才需要借助外部工具切割。6.4 一点实操习惯最后聊几个我在实际运维中总结的习惯不要用 root 账号跑 Tomcat。用 root 启动 Tomcat 意味着一旦 Web 应用有漏洞被攻破对方直接拿到了服务器的 root 权限。我在前面 Linux 安装部分已经建了专门的 tomcat 用户。修改配置文件后先校验 XML 合法性。server.xml和web.xml都是 XML 文件一个标签没闭合Tomcat 直接启动失败。Linux 上可以用xmllint --noout server.xml快速校验。上线前看日志的时间点。启动初期重点看catalina.out里的Deploying web application archive和Server startup in两行前者代表 war 包解压部署成功后者代表容器整体启动完成。妥善设置 Linux 主机名解析。如果你的 Tomcat 启动日志里有警告Unable to use directly registered FDs或者Server startup failed这种信息先把/etc/hosts里主机名映射配置好。这个问题在容器环境尤其常见别看它不起眼会浪费你半小时排查时间。线上环境 Tomcat 的问题80% 都能在catalina.out和localhost.*.log这两个日志文件里找到答案。遇到报错先沉下心看日志而不是盲目重启或者回滚代码这是我从新手到老手最大的转变。Tomcat 作为 Java Web 生态里最经典的容器掌握它的安装、配置和排错思路对后端开发和运维来说永远不会过时。

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询