简介:Linux版Tomcat 8.5.35压缩包面向需要在Linux服务器上运行Java Web应用的开发与运维人员,封装了Catalina、Jasper、Coyote等核心组件,可直接解压用于部署Servlet/JSP项目,免去手动编译配置。资源共645个文件,约9.2MB,以HTML页面、Java/JSP源文件、class类文件为主,还包含sh启动脚本、jar依赖库、XML配置文件等,能够完整支撑从服务启停、连接器配置到应用发布的常见需求。压缩包目录结构清晰,bin、conf、lib、webapps、logs等关键目录随包提供,便于快速掌握各模块用途,也方便结合SSL配置、访问控制等开展二次安全加固。目前已有548人学习下载,适合作为本地测试或生产环境的轻量级部署基础,可直接将WAR包放入webapps完成热部署,帮助使用者减少环境搭建时间,聚焦业务代码开发。 拿到一个“Linux版本tomcat8-8.5.35.tar.gz”安装包,看起来就是一个再普通不过的压缩包,但真把它部署到生产环境时,很多人的第一反应是“解压、启动、完事”。实际上这里面的门道不少,从校验压缩包完整性、选JDK版本、配置JAVA_HOME,到调整内存参数、注册systemd服务,每一步都可能影响你后面几个月的运维体验。这篇文章我就从零开始,把Tomcat 8.5.35在Linux上的部署流程完整拆开,把我踩过的坑、验证过的方案、排查过的故障一并写清楚,希望对正在折腾这台服务器的你有点实际帮助。
1. 部署前的环境准备与软件包校验
1.1 这台机器到底适不适合跑Tomcat
动手解压之前,先确认操作系统环境。Tomcat本身是纯Java写的,理论上有JDK就能跑,但不同Linux发行版、不同内核版本带来的差异还是存在的。至少你要搞清楚三件事:
- 系统是CentOS 7、CentOS 8、Ubuntu还是Debian,包管理器和防火墙操作方式完全不同;
- 机器架构是x86_64还是ARM,这决定了你下载的JDK安装包是哪一份;
- 系统内存、磁盘空间多大,Tomcat虽然轻量,但JVM启动默认就占几百MB内存,太小了跑不动。
我用uname -a和cat /etc/os-release确认过环境后,再看磁盘空间,df -h /opt确保至少预留2GB以上空间。很多人的Tomcat部署到后面出问题,最根本的原因就是一开始在不合适的系统上硬装,装完各种诡异故障,还以为是Tomcat的锅。
1.2 校验tar.gz完整性的两种方式
这一步是安全底线,可惜大多数人直接跳过了。拿到apache-tomcat-8.5.35.tar.gz之后,先别急着解压,花一分钟做完整性校验。官网会同时提供.sha512和.asc两个校验文件,对应两种校验思路。
校验SHA512哈希,确认文件在下载过程中没有损坏或被篡改。命令很简单:
echo "从官网复制的sha512值 apache-tomcat-8.5.35.tar.gz" | sha512sum -c -输出OK就说明文件没问题。如果提示FAILED,直接删掉重新下载,不要犹豫。
更高阶的校验方式是用GPG验证签名,确认这个包确实是Apache官方发布的。做法是先导入Apache Tomcat的官方公钥,再执行:
gpg --verify apache-tomcat-8.5.35.tar.gz.asc apache-tomcat-8.5.35.tar.gz平时自己实验室里部署,校验SHA512基本够用了。生产环境建议两步都做,尤其是从镜像站下载的包,镜像同步出错的情况真的碰到过。
2. 解压安装与目录结构深度解读
2.1 tar.gz解压命令的“隐性坑”
解压Tomcat这种tar.gz压缩包,标准命令就一个:
tar -zxvf apache-tomcat-8.5.35.tar.gz -C /opt/这里有个细节值得注意:-C /opt/指定了解压目标目录,如果你不写,它会直接解压到当前目录。很多人习惯先cd到某个目录再解压,这没问题,但解压出来的文件夹名字是apache-tomcat-8.5.35,又长又啰嗦。我通常的做法是先解压,再软链一个短名字:
ln -s /opt/apache-tomcat-8.5.35 /opt/tomcat后续所有路径都用/opt/tomcat,配置文件里写绝对路径也清爽很多。升级版本时,只需要把软链切到新目录,回滚就是一条命令的事,这个习惯帮我省了不少时间。
解压时还有一个容易忽略的点:tar.gz在解压过程中会保留文件的属主和权限信息。你用什么用户解压,得到的文件属主就是谁。我建议用专门的tomcat用户来部署和运行,而不是直接用root,这样即使Tomcat被攻破,攻击者拿到的也只是tomcat用户的权限,影响面小很多。
创建tomcat用户:
useradd -r -s /sbin/nologin tomcat chown -R tomcat:tomcat /opt/apache-tomcat-8.5.352.2 Tomcat目录结构逐层拆解
解压完之后,很多人看着一堆文件夹就懵了,不知道哪个是干嘛的。我整理过一份目录速查表,对照着看就清晰了:
| 目录/文件 | 作用说明 |
|---|---|
| bin/ | 存放启动、关闭脚本,包括startup.sh、shutdown.sh、catalina.sh |
| conf/ | 核心配置文件目录,server.xml、web.xml、context.xml都在这里 |
| lib/ | Tomcat运行所需的jar包,以及你额外补充的JDBC驱动等 |
| logs/ | 运行日志、访问日志、GC日志的输出目录 |
| temp/ | 临时文件目录,Tomcat自动管理,不用手动干预 |
| webapps/ | 存放你的Web应用,把war包扔进来就能自动部署 |
| work/ | JSP编译后的class文件存放目录,缓存作用,可清理但别删除 |
| LICENSE、NOTICE、RELEASE-NOTES | 版本信息和许可证文件 |
这里面最重要的就是conf/server.xml,Tomcat所有网络相关的配置都在这一个文件里。默认监听8080端口、HTTP/1.1协议,连接池参数等等都可以在这里调整。
还有一个很多人不知道的细节:Tomcat 8.5.x默认开启了org.apache.catalina.startup.ContextConfig的JAR扫描,这会导致启动慢,尤其在lib目录下jar包很多的时候。如果不需要扫描注解,可以在conf/context.xml里配置JarScanner关闭扫描,启动速度能有明显提升。
3. JDK版本选择与Java环境配置
3.1 8.5.35对JDK版本的硬性要求
Tomcat 8.5.x这一代有点特殊,它横跨了Java 7到Java 11的演进。具体到8.5.35这个版本,官方Release Notes写得很清楚:运行环境要求Java 7及以上版本,但如果你要完整支持HTTP/2、TLS 1.3这些新特性,建议至少用Java 8。
我的实际建议是:生产环境直接上Java 8,不要用Java 7,更不要用Java 11(除非你明确测试过兼容性)。原因有三个:
- Java 8是目前Tomcat 8.5.x用户中占比最高的组合,社区踩坑案例最多,遇到问题最好搜到答案;
- Java 8的JVM参数和GC调优资料最丰富,方便你做后续优化;
- Tomcat 8.5.35发布时Java 11刚出来不久,官方对这个组合的测试覆盖度不如Java 8充分。
JDK选择上,OpenJDK 8或者Auth的JDK 8都可以。注意架构别选错,x86_64就下x86_64的包,ARM就下ARM的包,下载错了解压就报错。
3.2 JAVA_HOME配置的三种方式
Tomcat启动脚本靠JAVA_HOME环境变量找到JDK,这一步配置不好,后面启动时铁定报Neither the JAVA_HOME nor the JRE_HOME environment variable is defined错误。
配置JAVA_HOME有三种方式,适用场景不同:
第一种,写入/etc/profile,全系统生效:
export JAVA_HOME=/usr/local/jdk1.8.0_202 export PATH=$JAVA_HOME/bin:$PATH改完执行source /etc/profile让配置立即生效。这种方式适合一台机器只跑一个Java版本的情况。
第二种,写在setenv.sh里,只对Tomcat生效:
vim /opt/tomcat/bin/setenv.sh内容这样写:
JAVA_HOME=/usr/local/jdk1.8.0_202 JRE_HOME=$JAVA_HOME/jre这个文件默认不存在,需要手动创建。这种方式最推荐,因为它不会影响机器上其他Java程序,而且后面调整JVM内存参数也在这同一个文件里加,管理起来很集中。
第三种,改catalina.sh,直接在启动脚本里写死。不推荐,因为升级Tomcat版本时这个文件会被覆盖,你的配置就白写了。
我会很明确地说:生产环境用第二种,配合systemd服务一起用,这是最干净、最可控的方案。
4. 启动前的关键调整与性能参数
4.1 端口冲突、内存参数、启动权限,三个先头兵
启动之前,先检查8080端口是否被占用:
ss -lntp | grep 8080如果端口被占用,要么杀掉占用的进程,要么修改conf/server.xml里的<Connector port="8080",改成你想要的端口。
然后是内存参数。Tomcat默认的JVM内存设置偏保守,-Xms和-Xmx默认只有几百MB,并发上来之后频繁GC,性能会非常难看。我的建议是根据机器实际内存调整,在setenv.sh里添加:
JAVA_OPTS="-Xms512m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=256m -Djava.security.egd=file:/dev/./urandom"解释一下这些参数的含义:
-Xms512m:JVM初始堆内存512MB,启动时直接分配,避免运行时动态扩容带来的性能损耗;-Xmx1024m:JVM最大堆内存1GB,超过这个值就会抛出OutOfMemoryError;-XX:MetaspaceSize和-XX:MaxMetaspaceSize:Java 8里方法区(存放类元数据)的大小限制,默认无上限,但设置一个合理值可以避免内存被无限制吃光;-Djava.security.egd=file:/dev/./urandom:这行很关键,Tomcat在生成Session ID时会用到SecureRandom,如果用/dev/random,在高并发或系统熵不足的情况下会阻塞很久,改成/dev/urandom后启动速度和响应速度都会正常。
还有一个每次新装Tomcat都会踩的坑:权限。如果你用root解压后直接启动,Tomcat以root身份运行,这在生产环境是很危险的事。但我前面已经创建了tomcat用户,再改一下目录属主:
chown -R tomcat:tomcat /opt/tomcat su -s /bin/bash tomcat -c "/opt/tomcat/bin/startup.sh"这样Tomcat就是tomcat用户身份下运行的,后顾之忧少了很多。
4.2 通过systemd管理Tomcat,告别裸启动
用startup.sh启动Tomcat最大的痛点是:关掉终端窗口,进程可能被挂断,而且开机不会自动启动,进程崩溃了也不会自动拉起。生产环境一定要用systemd来管理。
创建一个service文件/etc/systemd/system/tomcat.service:
[Unit] Description=Apache Tomcat 8.5.35 After=network.target [Service] Type=forking User=tomcat Group=tomcat Environment="JAVA_HOME=/usr/local/jdk1.8.0_202" 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启动后会立即返回,真正的Tomcat进程是fork出来的子进程,这是Tomcat启动脚本的默认行为;Environment变量要在service文件里写清楚,避免Tomcat找不到JAVA_HOME;Restart=on-failure是核心配置,进程异常退出后10秒自动拉起,这个容错机制在生产环境太重要了。
配置完成后执行:
systemctl daemon-reload systemctl enable tomcat systemctl start tomcat启用开机自启,今后机器重启后Tomcat会自动起来,不用再手动去执行startup.sh了。
5. 启动验证与常见故障排查
5.1 三位一体验证启动状态
服务启动之后,别只看“Active: active (running)”就完了,完整验证要覆盖三个层面。
第一层,确认进程存在:
ps -ef | grep tomcat第二层,确认端口在监听:
ss -lntp | grep 8080第三层,确认应用真正响应了:
curl -I http://localhost:8080看到HTTP/1.1 200 OK,才说明Web层面是通的。只看端口监听就以为成功了,有时候会漏掉Tomcat能启动但应用加载失败的情况。
访问http://服务器IP:8080验证更直观,如果IP访问不通,原因大概率是防火墙没放行8080端口。CentOS 7用firewalld,命令是:
firewall-cmd --permanent --add-port=8080/tcp firewall-cmd --reloadUbuntu用的是ufw:
ufw allow 8080/tcp这些基础网络检查往往比Tomcat本身的配置更耗时间,我排查过很多“Tomcat启动不了”最终都是防火墙或者安全组规则的问题。
5.2 从实际报错到解决方案:一份排查速查表
把部署过程中经常遇到的报错信息、排查思路和解决办法整理成了一张表:
| 报错/现象 | 可能原因 | 解决办法 |
|---|---|---|
| Neither the JAVA_HOME nor the JRE_HOME... | 没有正确配置JAVA_HOME | 在setenv.sh或service文件中设置JAVA_HOME |
| The JRE_HOME environment variable is not defined correctly | JRE_HOME指向的路径不存在或错误 | 检查$JAVA_HOME/jre目录是否存在,确认JDK安装完整 |
| Port 8080 required by Tomcat 8.5.35 is already in use | 8080端口被占用 | ss -lntp看占用进程,换端口或杀进程 |
| java.net.BindException: Permission denied | 绑定了1024以下端口,非root用户无权限 | 要么改用高位端口,要么用authbind或setcap授权 |
| Access denied for user 'root'@'localhost' | 数据源配置的用户名密码错误 | 检查context.xml或JNDI数据源配置 |
| SEVERE: Error deploying web application... | 应用本身的web.xml或jar包冲突 | 解压war包看详细异常,检查lib目录下是否有重复/冲突jar |
| 启动极慢,日志卡在“Creation of SecureRandom instance” | JVM使用/dev/random,熵不足导致阻塞 | JAVA_OPTS里加-Djava.security.egd=file:/dev/./urandom |
| 内存溢出OutOfMemoryError: Java heap space | 堆内存不够 | 调整-Xmx参数,排查应用是否内存泄漏 |
| 看不到应用,manager页面403 | 未配置manager-gui角色用户 | 在conf/tomcat-users.xml里添加对应角色和用户 |
| 中文乱码 | URI编码或JVM默认编码不对 | Connector加URIEncoding="UTF-8",确保JVM使用UTF-8 |
这张表基本覆盖了我这几年部署Tomcat遇到的大部分问题。遇到报错,第一反应应该是去看logs/catalina.out和logs/localhost.log,不要瞎猜。Tomcat日志信息算给得相当详细了,把异常堆栈看明白,问题就已经解决了一半。
5.3 一次实际的部署排错记录
有一次我部署一个老系统到新服务器,Tomcat起来后进程正常、端口也在监听,但访问就是404。我查看logs/catalina.out没有任何报错,logs/localhost.log里也没有异常。后来想了一下,把webapps里的ROOT目录删了,重新把war包丢进去,访问就正常了。
原因是旧服务器上ROOT目录里残留了旧版本的静态文件,Tomcat启动时直接读取了已有解压目录,没有用新war包重新解压。遇到应用没更新、访问还是旧内容的情况,先清理webapps下对应的解压目录和work目录下的缓存,再把war包重新放进去,这个问题就解决了。
6. 部署完成后还需要做的事
6.1 多实例部署的思路
如果你要在一台机器上跑多个Tomcat实例,比如测试环境和预发布环境共用一台服务器,最优雅的方案不是把安装包复制好几份,而是用一份程序文件配上多个独立的运行目录。
做法是保留一个/opt/tomcat作为程序目录,然后创建多个CATALINA_BASE目录,每个目录里包含conf、logs、webapps、tmp、work这几个目录。启动时用:
/opt/tomcat/bin/startup.sh -Dcatalina.base=/opt/instance1这种方式的好处是程序文件只维护一份,升级时只更新/opt/tomcat下的bin和lib目录,各实例的配置和部署内容互不干扰。多实例之间通过不同的端口和不同的server.xml隔离。
6.2 版本升级的一点个人建议
Tomcat 8.5.35这个版本说实话是2019年发布的,到现在已经积累了不少安全补丁和bug修复。如果你是在生产环境使用,我真心建议你关注一下官方发布的安全公告,在条件允许的情况下升级到8.5系列的最新版本。
升级的方式很简单,下载新版本tar.gz,解压后替换掉旧版本的bin和lib目录,conf目录单独备份出来,对比一下配置差异后复用。因为8.5.x系列内部的配置结构基本没有变化,这种原地升级方式我用过很多次,没有出过问题。
如果你还在用Tomcat 7或者更老的版本,那更值得找个时间升级到8.5系列,至少协议、安全加密、性能方面都有明显的提升。JDK版本也尽量保持到8或以上,别让老旧的运行环境成为系统的短板。
本文还有配套的精品资源,点击获取