在实际的业务场景中,我们经常会遇到如下异常提示:“Process finished with exit code x “。通常表现为:创建好的 Spring Boot 微服务项目,启动时无异常,却立马自动退出,无论基于何种方式启动均无效且控制台无任何有效信息。此类异常的处理往往较为繁琐,尤其是在无任何 Log 、无明显关键字输出的场景下,尤为让人摸不着头脑。
那么,针对此类问题,如何能够快速定位、分析?有没有相应的针对性解决方案呢?
其实,针对每一种可能出现的场景都有其独特的处理方式,常见的案例场景,具体如下所示:
1、 无 Spring 框架日志输出
此类异常往往无任何线索,没有相关的日志产生
解决策略:
针对此类型场景,若我们直接通过启动脚本或者 java -jar 命令行启动,且无任何 Spring 相关日志。此时,需要检测启动脚本文件,启动时定义 Java 虚拟机相关内存参数及垃圾回收策略,检查其语法:内存的适配性、回收算法的匹配性、命令行正确性以及完整性等。
举一个简单的示例,例如:当部署的 Spring Boot 微服务 运行在 4C 8G 的虚拟机之上,若我们给应用程序分配的堆内存大小超过操作系统所分配的物理内存 8G时,则其是无法启动起来的。除此之外,若启动脚本文件中所定义的年轻代与年老代 GC 策略或模型不匹配,基于特定的环境约束,也有可能是无法启动成功的。当然,命令行正确性及完整性同样也会导致如上场景异常。
2、 Process finished with exit code 1
此类异常通常仅输出 Spring 框架日志,即输出框架版本信息,再无其他可用信息,或者借助 Debug 可打印更多信息。具体如下所示:
(1)引用包异常
解决策略:
针对此类问题,往往建议强制异常捕获并打印出来,然后再次启动,可用的信息将会显示出来,通常可能因配置文件少了某一些组件的配置,导致项目启动过程中初始化组件失败。
(2)Yaml、POM 及 XML 文件配置异常
解决策略:
针对此类问题,着重检查文件内容“格式”的规范性、“参数”的正确性以及可能存在的组件依赖性缺失。针对版本参数正确性问题,往往在 Maven下面的 Dependencies 中的Spring Boot 的版本与 pom.xml 文件中所定义的 Spring Boot 的版本不一致,导致启动异常。针对组件依赖性,可参考如下所示:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<!-- 移除对Tomcat的内置依赖 -->
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
或如下,
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
(3)日志框架冲突异常
解决策略:
针对此类问题,往往因 Log4j 和 Common-logs 日志包冲突,为此,我们可通过以下方式解决,具体如下所示:
方式1:解决冲突,排除掉 Slf4j、Common-logs 其中一方,Spring 使用 slf4j,那可以排除掉 Common-logs
方式2: 打通Log4j 和 Common-logs,Maven 相关依赖如下所示:
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
</dependency>
此依赖可以有效将 Log4j 输出到 Slf4j,从而从 Slf4j输出。
(4)环境变量异常
解决策略:
针对此类异常,往往因程序启动过程中找不到对应的环境变量,无法正确加载环境配置,导致服务启动异常。此时,需要检测 Active Profiles 等相关参数正确性。具体如下所示:
#日志配置-选择一个日志输出环境
spring.profiles.active=dev
3、 Process finished with exit code 0 针对此类问题,主要表现为“兼容性”问题,程序往往能够正常运行,但同时出现自动退出现象,具体如下:
(1)项目中组件依赖兼容性异常
解决策略:
针对此类异常,往往需要清除 Maven 工程下面的依赖,具体如下所示:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
若我们的环境不是基于 Maven工程,则需要将 spring-boot-starter-tomcat 这个包去除掉即可。
(2)Spring Boot 不同版本兼容性异常
解决策略:
针对此类异常,往往需要对高版本的 Spring Boot 相关 pom.xml 进行调整,需要注意的时,以下依赖必须至少包含:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
或
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</dependency>
综上所述,基于Spring Boot 应用自动退出的相关场景案例,本文简要剖析到此为止,其他不常见的场景以及解决策略暂未在本文中描述,大家有任何问题或建议,可以随时留言、沟通。