简介: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.sh3.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.targetType=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这两步,能提前发现八成以上的配置问题。希望帮到你。
本文还有配套的精品资源,点击获取