news 2026/10/21 5:03:20

Tomcat 8.0.47 部署实战:从环境对齐到 systemd 托管与避坑排查

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Tomcat 8.0.47 部署实战:从环境对齐到 systemd 托管与避坑排查

简介:Apache Tomcat 8.0.47 是 Apache 软件基金会推出的开源 Java Web 应用容器,完整实现 Servlet、JSP 与 Java EE 规范,适合需要部署调试 Java Web 项目的开发者、运维人员及计算机专业学生使用。压缩包共 628 个文件,约 9.75MB,涵盖 html 文档、class 字节码、java 源码、jsp 页面、jar 依赖包、xml 配置、sh/bat 启动脚本及 properties 配置等,基本覆盖 Tomcat 运行所需的目录结构与示例应用。资源包含 Catalina 容器、Jasper JSP 引擎、Coyote 连接器、JNDI 命名服务、JASPI 认证接口及 JK 连接器等核心模块,并附带 server.xml、context.xml、web.xml 等关键配置文件,便于理解端口、虚拟主机、上下文路径与安全约束的设置方式。目前已有 122 人学习下载,适合用于本地环境搭建、源码研读与 Web 应用部署练习。

1. Tomcat 8.0.47 部署:为什么老版本反而更难装

上周帮一个朋友处理他公司内网的老项目,Java 7 编译的,Spring 3.x,跑在一台 CentOS 7 的虚拟机上。项目本身没什么问题,但部署环境卡了整整一个下午——他下载了最新的 Tomcat 10,启动直接报NoClassDefFoundError,换 Tomcat 9 又提示 Servlet 版本不兼容。最后我让他退回到 apache-tomcat-8.0.47,十分钟跑通。这不是个例,很多遗留系统、教学环境、老版本中间件依赖的项目,就是绑死在 Tomcat 8.0.x 这条线上。Tomcat 8.0.47 是 8.0 分支的最后一个版本,2018 年发布,支持 Servlet 3.1、JSP 2.3、EL 3.0,同时兼容 Java 7 和 Java 8。装不好它的典型症状是:启动闪退、端口占用、JAVA_HOME找不到、manager页面 403。这篇笔记按我实际部署的顺序来,从环境确认到启动验证,中间穿插几个我踩过的坑,适合正在给老项目配环境的开发者。

2. 安装前先把环境对齐:JDK 版本和目录规划

2.1 JDK 版本选择:别用 Java 11 去跑 Tomcat 8.0.47

Tomcat 8.0.47 官方要求 Java 7 及以上,但“及以上”有边界。我实测 Java 11 启动会报Unsupported major.minor version或者java.lang.NoClassDefFoundError: javax/xml/bind/DatatypeConverter,因为 Java 11 移除了 JAXB 模块。Java 17 更不行,SecurityManager相关 API 已经废弃。稳妥的选择是 JDK 8,如果项目本身是 Java 7 编译的,用 JDK 8 跑也没问题,向下兼容。查看当前 JDK 版本:

java -version # 输出示例: # java version "1.8.0_202" # Java(TM) SE Runtime Environment (build 1.8.0_202-b08) # Java HotSpot(TM) 64-Bit Server VM (build 25.202-b08, mixed mode)

如果输出是1.7.0_80也可以,但建议至少升到 8u151 以上,避免旧版 JDK 的 TLS 问题。JAVA_HOME必须指向 JDK 根目录,不是bin目录,也不是 JRE 目录。我一般这样配:

# 编辑 /etc/profile 或 ~/.bashrc export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.202.b08-1.el7_6.x86_64 export PATH=$JAVA_HOME/bin:$PATH export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar

改完执行source /etc/profile,再用echo $JAVA_HOME确认路径没有多余空格或换行。常见错误是复制路径时带上了行尾空格,导致 Tomcat 启动脚本解析失败。

2.2 目录规划:别把 Tomcat 解压到/root下

我见过有人把 Tomcat 解压到/root/apache-tomcat-8.0.47,然后用tomcat用户去启动,结果logs目录写不进去,启动日志一片空白。正确的做法是单独建一个应用目录,比如/opt/tomcat或/usr/local/tomcat,把解压后的文件放进去,再把属主改成运行用户。假设你用tomcat用户跑服务:

# 创建目录并解压 sudo mkdir -p /opt/tomcat sudo tar -zxvf apache-tomcat-8.0.47.tar.gz -C /opt/tomcat --strip-components=1 # 创建 tomcat 用户(如果还没有) sudo useradd -r -s /sbin/nologin tomcat # 改属主 sudo chown -R tomcat:tomcat /opt/tomcat

--strip-components=1的作用是去掉压缩包自带的apache-tomcat-8.0.47这一层目录,直接把bin、conf、webapps放到/opt/tomcat下。这样后面配 systemd 服务时路径更干净。如果你只是本地测试,用当前用户跑也行,但生产环境别用 root 跑 Tomcat,这是基本的安全习惯。

2.3 端口检查:8080 被占用的两种处理方式

Tomcat 默认监听 8080(HTTP)、8005(SHUTDOWN)、8009(AJP)。启动前先确认端口没被占:

# 查看 8080 端口占用 ss -tlnp | grep 8080 # 或者 netstat -tlnp | grep 8080

如果被占,要么停掉占用进程,要么改 Tomcat 端口。改端口在conf/server.xml里:

<!-- 把 8080 改成 8081 --> <Connector port="8081" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />

注意redirectPort也要跟着改,否则 HTTPS 跳转会有问题。AJP 端口 8009 如果不用可以注释掉,减少暴露面。

3. 安装与配置:从解压到 systemd 托管

3.1 解压后的目录结构确认

解压完先看一眼目录,确认文件完整:

ls -lh /opt/tomcat # 应该看到: # bin/ conf/ lib/ logs/ temp/ webapps/ work/

bin下关键脚本是startup.sh、shutdown.sh、catalina.sh。conf下核心配置文件是server.xml、web.xml、context.xml、tomcat-users.xml。logs目录初始为空,启动后才会生成catalina.out。如果logs目录不存在,手动建一个并改属主,否则启动会报No such file or directory。

3.2 配置setenv.sh定制 JVM 参数

Tomcat 启动时会自动读取bin/setenv.sh(如果存在),用来设置 JVM 内存、编码、临时目录等。我一般会建这个文件,而不是直接改catalina.sh,这样升级 Tomcat 时配置不会丢:

# 创建 /opt/tomcat/bin/setenv.sh export CATALINA_OPTS="$CATALINA_OPTS -Xms512m -Xmx1024m" export CATALINA_OPTS="$CATALINA_OPTS -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=256m" export CATALINA_OPTS="$CATALINA_OPTS -Dfile.encoding=UTF-8" export CATALINA_OPTS="$CATALINA_OPTS -Djava.awt.headless=true" export CATALINA_PID="/opt/tomcat/tomcat.pid"

-Xms和-Xmx分别是最小和最大堆内存,老项目一般 512M 到 1G 够用。MetaspaceSize是 Java 8 用来替代永久代的,设太小会频繁 Full GC。CATALINA_PID指定 PID 文件路径,方便shutdown.sh精确杀进程,避免杀错。建完给执行权限:

chmod +x /opt/tomcat/bin/setenv.sh

3.3 配置tomcat-users.xml启用管理页面

默认情况下manager和host-manager页面是 403 的,因为没配用户。编辑conf/tomcat-users.xml,在<tomcat-users>标签内加:

<role rolename="manager-gui"/> <role rolename="manager-script"/> <role rolename="admin-gui"/> <user username="admin" password="YourStrongPassword" roles="manager-gui,manager-script,admin-gui"/>

注意manager-gui和manager-script要分开,前者给浏览器用,后者给脚本调用。密码别用admin或tomcat,这是被扫描的重点。另外 Tomcat 8.0.47 默认只允许本机访问管理页面,如果要远程访问,需要改webapps/manager/META-INF/context.xml,把allow的值改成你的 IP 段:

<Valve className="org.apache.catalina.valves.RemoteAddrValve" allow="127\.\d+\.\d+\.\d+|192\.168\.1\.\d+" />

改完重启生效。生产环境不建议开放远程管理页面,用 SSH 隧道或只在本机操作更安全。

3.4 用 systemd 托管 Tomcat 服务

手动startup.sh启动的缺点是终端一关进程就没了,而且开机不会自启。用 systemd 托管是标准做法:

# /etc/systemd/system/tomcat.service [Unit] Description=Apache Tomcat 8.0.47 After=network.target [Service] Type=forking User=tomcat Group=tomcat Environment=JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.202.b08-1.el7_6.x86_64 Environment=CATALINA_HOME=/opt/tomcat Environment=CATALINA_BASE=/opt/tomcat ExecStart=/opt/tomcat/bin/startup.sh ExecStop=/opt/tomcat/bin/shutdown.sh Restart=on-failure RestartSec=10 [Install] WantedBy=multi-user.target

Type=forking是因为startup.sh会 fork 一个后台进程。Environment里显式指定JAVA_HOME,避免 systemd 环境变量缺失导致启动失败。Restart=on-failure让 Tomcat 崩溃后自动拉起。写完执行:

sudo systemctl daemon-reload sudo systemctl start tomcat sudo systemctl enable tomcat

查看状态用systemctl status tomcat,看日志用journalctl -u tomcat -f或直接tail -f /opt/tomcat/logs/catalina.out。

4. 避坑排查:启动失败、403、乱码的常见原因

4.1 启动闪退,catalina.out只有一行Tomcat started

现象:执行startup.sh后提示Tomcat started,但ps查不到进程,catalina.out没有详细日志。原因通常是JAVA_HOME或JRE_HOME没配,或者setenv.sh里有语法错误导致脚本提前退出。解决:先手动执行bash -x /opt/tomcat/bin/catalina.sh run,看哪一行报错。如果是JAVA_HOME问题,在setenv.sh里显式export JAVA_HOME=...。如果是setenv.sh语法错误,检查有没有多余空格或中文引号。

4.2 管理页面 403,tomcat-users.xml配了也没用

现象:访问/manager/html返回 403,日志里没有报错。原因有两个:一是tomcat-users.xml改完没重启;二是 Tomcat 8.0.47 的manager应用默认有RemoteAddrValve限制,只允许127.0.0.1访问。解决:确认重启后,检查webapps/manager/META-INF/context.xml里的allow值,加上你的客户端 IP。如果还是 403,看logs/localhost.<日期>.log,里面会记录拒绝的 IP。

4.3 中文乱码,GET 请求参数变问号

现象:页面提交中文参数,后台收到???。原因:Tomcat 8 默认 URI 编码是 UTF-8,但server.xml里Connector没配URIEncoding时,某些系统环境会按 ISO-8859-1 解析。解决:在Connector标签加URIEncoding="UTF-8":

<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" URIEncoding="UTF-8" />

同时确认setenv.sh里有-Dfile.encoding=UTF-8。POST 请求的乱码一般用request.setCharacterEncoding("UTF-8")解决,或者配CharacterEncodingFilter。

4.4logs目录权限不对,启动报Permission denied

现象:用tomcat用户启动,catalina.out写不进去,启动失败。原因:解压时用的是 root,logs、temp、work目录属主是 root。解决:chown -R tomcat:tomcat /opt/tomcat,确保logs、temp、work可写。如果用了CATALINA_PID,PID 文件所在目录也要可写。

4.5 内存溢出OutOfMemoryError: Metaspace

现象:运行一段时间后报OutOfMemoryError: Metaspace,应用无响应。原因:MaxMetaspaceSize设太小,或者应用动态生成类太多(比如 JSP 频繁编译)。解决:在setenv.sh里调大-XX:MaxMetaspaceSize=512m,同时检查work目录有没有堆积大量编译后的 JSP 类。定期清理work/Catalina目录可以缓解。

5. 装完怎么验证:从端口到应用的完整检查链

装完别急着丢给开发,按这条链走一遍,确认每个环节都通。第一步,确认进程和端口:

ps -ef | grep tomcat ss -tlnp | grep -E '8080|8005|8009'

应该看到tomcat用户的 Java 进程,以及 8080、8005 处于 LISTEN 状态。如果 8009 没监听,说明 AJP 没启用,不影响 HTTP 访问。第二步,本地 curl 测试:

curl -I http://127.0.0.1:8080/ # 期望输出: # HTTP/1.1 200 OK # Content-Type: text/html;charset=UTF-8

如果返回 404,检查webapps/ROOT目录是否存在。第三步,部署一个测试 WAR 包,验证应用加载:

# 假设有一个 test.war cp test.war /opt/tomcat/webapps/ # 等几秒后查看日志 tail -f /opt/tomcat/logs/catalina.out # 看到 "Deployment of web application archive ... has finished in ... ms" 表示成功

然后访问http://127.0.0.1:8080/test/,确认页面正常。第四步,检查管理页面:

curl -u admin:YourStrongPassword http://127.0.0.1:8080/manager/text/list # 应该返回 OK - Listed applications for virtual host localhost

如果返回 401,说明用户密码不对;返回 403,说明 IP 限制没放开。第五步,看日志有没有异常:

grep -i "SEVERE\|ERROR\|Exception" /opt/tomcat/logs/catalina.out

正常的启动日志里不应该有SEVERE级别的错误。如果有ClassNotFoundException,检查lib目录下有没有对应的 jar 包。第六步,模拟重启验证 systemd:

sudo systemctl restart tomcat sleep 5 curl -I http://127.0.0.1:8080/

重启后能正常访问,说明 systemd 配置没问题。我一般还会把catalina.out加到 logrotate 里,避免日志无限增长:

# /etc/logrotate.d/tomcat /opt/tomcat/logs/catalina.out { daily rotate 7 missingok notifempty copytruncate }

copytruncate是关键,因为 Tomcat 一直持有文件句柄,直接删文件不会释放空间。从那以后我每次部署完 Tomcat,都会把这条检查链完整走一遍,尤其是curl -I和grep SEVERE这两步,能提前发现八成以上的配置问题。希望帮到你。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/21 5:02:43

大地坐标转换原理与工程实践:椭球、基准、投影及换代避坑指南

简介&#xff1a;这份资源聚焦大地坐标转换&#xff0c;面向GIS数据处理、地图制图与定位服务方向的开发者及测绘相关专业学生&#xff0c;解决BJ54、Xian80与WGS84等坐标系之间以及平面坐标互转的问题。包内共12个文件&#xff0c;以5个m脚本、4个txt坐标数据与说明文件、3个a…

作者头像 李华
网站建设 2026/10/21 5:01:20

表格结构识别与问答:StrucTab两阶段方案详解与实践踩坑

表格解析这个方向&#xff0c;我前后折腾了快两年&#xff0c;从最开始被各种合并单元格折磨到想摔键盘&#xff0c;到后来慢慢摸到门道&#xff0c;再到这次工作被接收&#xff0c;算是把这个“小领域”的坑基本踩了一遍。这篇东西就是想把StrucTab这套方案从思路到落地完整梳…

作者头像 李华
网站建设 2026/10/21 5:01:11

iloader iOS 侧载快速上手:连接设备到装好应用的完整流程

iloader iOS 侧载快速上手&#xff1a;连接设备到装好应用的完整流程 【免费下载链接】iloader User friendly sideloader 项目地址: https://gitcode.com/GitHub_Trending/iloa/iloader iloader 是一款免费的 iOS 侧载桌面工具&#xff0c;把下载、签名、安装、配对文件…

作者头像 李华
网站建设 2026/10/21 5:00:45

从矢量瓦片到Canvas渲染:自研离线地图组件lingbot-map

提到“lingbot-map”这个名字&#xff0c;很多人的第一反应是&#xff1a;这不就是一个地图组件嘛&#xff0c;直接调现成的 SDK 不就行了&#xff1f;但实际做下来你会发现&#xff0c;地图这东西&#xff0c;往浅了做是调接口&#xff0c;往深了做是从坐标系到渲染、从数据切…

作者头像 李华
网站建设 2026/10/21 5:00:14

Qt流程图绘制方案:基于QGraphicsScene的图元视图架构与性能优化

简介&#xff1a;这是一份面向Qt开发初学者与UI设计人员的流程图绘制实战源码&#xff0c;围绕图形视图框架中的图元与视图两大核心概念展开&#xff0c;帮助读者理解如何用QGraphicsItem与QGraphicsScene构建可交互的图形编辑环境。资源包共36个文件&#xff0c;以9个cpp源文件…

作者头像 李华
网站建设 2026/10/21 5:00:12

对比学习CPC:预测未来隐表示与InfoNCE损失实战解析

对比学习这几年在自监督领域的热度一直没降过&#xff0c;但真正把"预测未来"这件事讲透的工作其实不多。Contrastive Predictive Coding&#xff08;CPC&#xff09;算是其中一个绕不开的节点——它没有走"重构像素"那条路&#xff0c;而是换了个思路&…

作者头像 李华