在AWS EC2实例部署Spring Boot WAR包至Tomcat遇解压失败问题
我之前部署Spring Boot WAR包到EC2的Tomcat时也踩过类似的坑,给你几个实用的排查方向,应该能解决问题:
先盯紧权限问题(EC2最常见的坑):
EC2上的Tomcat一般是用tomcat系统用户运行的,你通过SSH上传WAR包到webapps目录后,默认所有者是你的登录用户(比如ec2-user),Tomcat没有读写权限自然没法解压。
先执行ls -l /path/to/tomcat/webapps看WAR包的权限信息,如果所有者不是tomcat,就用命令sudo chown tomcat:tomcat your-app.war把权限转过去,之后重启Tomcat试试。检查Tomcat的自动部署配置:
打开Tomcat的conf/server.xml,找到<Host>标签,确认有没有开启autoDeploy="true"和deployOnStartup="true"这两个属性。虽然默认是开启的,但有些EC2上的自定义Tomcat镜像可能会把这些配置关掉,加上之后重启服务。
另外可以看看conf/context.xml里的antiResourceLocking配置,如果它设为true,有时候会干扰WAR包解压,暂时改成false试试。扒日志找具体错误:
直接去Tomcat的logs目录看catalina.out或者localhost.log,里面肯定有部署失败的具体原因——比如依赖缺失、Spring Boot配置问题、甚至是Tomcat版本兼容的细节。比如日志里如果出现Failed to deploy application at context path '/your-app',后面跟着的异常栈就是定位问题的关键。再确认Spring Boot的WAR包配置:
虽然本地能运行,但还是要核对下打包配置:- Maven的
pom.xml里要把打包方式设为war,并且把内置Tomcat依赖设为provided:<packaging>war</packaging> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> <scope>provided</scope> </dependency> - 启动类必须继承
SpringBootServletInitializer并重写configure方法:@SpringBootApplication public class YourAppApplication extends SpringBootServletInitializer { @Override protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { return application.sources(YourAppApplication.class); } public static void main(String[] args) { SpringApplication.run(YourAppApplication.class, args); } }
- Maven的
核对EC2和本地的环境细节:
虽然都是Java 1.8,但要确认EC2上是Oracle JDK还是OpenJDK,有些Spring Boot依赖对JDK的细节有要求。用java -version和javac -version和本地对比下;另外Tomcat的temp目录权限也要检查,解压WAR包会用到这个目录,执行sudo chown -R tomcat:tomcat /path/to/tomcat/temp确保权限正确。
按这个顺序排查,大概率能找到问题根源。我当时就是因为WAR包的所有者不是Tomcat用户,折腾了半天,改完权限就正常解压了。
内容的提问来源于stack exchange,提问作者Raj Chauhan

