You need to enable JavaScript to run this app. Spring Boot JAR包部署AWS EC2 Ubuntu后启动即触发extShutdownHook自动停止问题
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot JAR包部署AWS EC2 Ubuntu后启动即触发extShutdownHook自动停止问题

EC2环境下Spring Boot应用启动后自动停止故障排查

项目基本信息

  • 技术栈构成:Spring Boot + AWS 服务组件(EC2、S3、RDS(MariaDB))
  • 部署方式:在Ubuntu系统的EC2实例上,通过命令 java -jar *.jar 运行打包完成的Spring Boot JAR包

故障表现

通过JAR包启动应用后,服务可以走完全部启动流程,但启动完成后立刻自动退出。最初排查方向聚焦于聊天功能的WebSocket配置,已做如下调整但故障未解决:

  • 添加ThreadPoolTaskScheduler线程池任务调度配置
  • 配置STOMP跨域允许规则setAllowedOrigins
    多轮自行排查未定位问题根因。

相关WebSocket配置代码

private static final Logger LOGGER = LoggerFactory.getLogger(WebsocketBrokerConfig.class);

@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {

    //for subscribe prefix
    registry.enableSimpleBroker("/user");
    //for publish prefix
    registry.setApplicationDestinationPrefixes("/app");
    //user destination provides ability to have unique user queue
    //registry.setUserDestinationPrefix("/user");
    
}

@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
    
    registry.addEndpoint("/broadcast")
        .setAllowedOrigins("http://ec2....amazonaws.com")   
        .withSockJS()
        .setHeartbeatTime(60_000);
}

启动与自动退出日志

.   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::                (v2.4.3)

2021-03-03 00:44:34.278  INFO 5898 --- [           main] com.example.salle.SalleApplication       : Starting SalleApplication v0.0.1-SNAPSHOT using Java 1.8.0_282 on ip-172-31-46-33 with PID 5898 (/home/ubuntu/salle/salle/target/test-0.0.1-SNAPSHOT.jar started by ubuntu in /home/ubuntu/salle/salle)
2021-03-03 00:44:34.283  INFO 5898 --- [           main] com.example.salle.SalleApplication       : No active profile set, falling back to default profiles: default
2021-03-03 00:44:36.435  INFO 5898 --- [           main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
2021-03-03 00:44:36.489  INFO 5898 --- [           main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 31 ms. Found 0 JPA repository interfaces.
2021-03-03 00:44:38.298  INFO 5898 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8080 (http)
2021-03-03 00:44:38.330  INFO 5898 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2021-03-03 00:44:38.330  INFO 5898 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.43]
2021-03-03 00:44:39.363  INFO 5898 --- [           main] org.apache.jasper.servlet.TldScanner     : At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time.
2021-03-03 00:44:39.969  INFO 5898 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2021-03-03 00:44:39.969  INFO 5898 --- [           main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 5536 ms
2021-03-03 00:44:41.016  INFO 5898 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
2021-03-03 00:44:41.247  INFO 5898 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
2021-03-03 00:44:41.408  INFO 5898 --- [           main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
2021-03-03 00:44:41.600  INFO 5898 --- [           main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 5.4.28.Final
2021-03-03 00:44:41.900  INFO 5898 --- [           main] org.hibernate.annotations.common.Version   : HCANN000001: Hibernate Commons Annotations {5.1.2.Final}
2021-03-03 00:44:42.217  INFO 5898 --- [           main] org.hibernate.dialect.Dialect            : HHH000400: Using dialect: org.hibernate.dialect.MariaDB103Dialect
2021-03-03 00:44:43.125  INFO 5898 --- [           main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000490: Using JtaPlatform implementation: [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform]
2021-03-03 00:44:43.155  INFO 5898 --- [           main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
2021-03-03 00:44:45.786  INFO 5898 --- [           main] o.s.s.c.ThreadPoolTaskScheduler          : Initializing ExecutorService
2021-03-03 00:44:45.860  INFO 5898 --- [           main] o.s.s.c.ThreadPoolTaskScheduler          : Initializing ExecutorService 'messageBrokerTaskScheduler'
2021-03-03 00:44:46.023  INFO 5898 --- [           main] o.s.s.concurrent.ThreadPoolTaskExecutor  : Initializing ExecutorService 'clientInboundChannelExecutor'
2021-03-03 00:44:46.025  INFO 5898 --- [           main] o.s.s.concurrent.ThreadPoolTaskExecutor  : Initializing ExecutorService 'clientOutboundChannelExecutor'
2021-03-03 00:44:46.035  INFO 5898 --- [           main] o.s.s.concurrent.ThreadPoolTaskExecutor  : Initializing ExecutorService 'brokerChannelExecutor'
2021-03-03 00:44:46.140  WARN 5898 --- [           main] JpaBaseConfiguration$JpaWebConfiguration : spring.jpa.open-in-view is enabled by default. Therefore, database queries may be performed during view rendering. Explicitly configure spring.jpa.open-in-view to disable this warning
2021-03-03 00:44:47.221  INFO 5898 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''
2021-03-03 00:44:47.227  INFO 5898 --- [           main] o.s.m.s.b.SimpleBrokerMessageHandler     : Starting...
2021-03-03 00:44:47.227  INFO 5898 --- [           main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [DefaultSubscriptionRegistry[cache[0 destination(s)], registry[0 sessions]]]]
2021-03-03 00:44:47.233  INFO 5898 --- [           main] o.s.m.s.b.SimpleBrokerMessageHandler     : Started.
2021-03-03 00:44:47.252  INFO 5898 --- [           main] com.example.salle.SalleApplication       : Started SalleApplication in 14.288 seconds (JVM running for 15.469)
2021-03-03 00:45:00.256  INFO 5898 --- [extShutdownHook] o.s.m.s.b.SimpleBrokerMessageHandler     : Stopping...
2021-03-03 00:45:00.258  INFO 5898 --- [extShutdownHook] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=false, SimpleBrokerMessageHandler [DefaultSubscriptionRegistry[cache[0 destination(s)], registry[0 sessions]]]]
2021-03-03 00:45:00.258  INFO 5898 --- [extShutdownHook] o.s.m.s.b.SimpleBrokerMessageHandler     : Stopped.
2021-03-03 00:45:00.284  INFO 5898 --- [extShutdownHook] o.s.s.concurrent.ThreadPoolTaskExecutor  : Shutting down ExecutorService 'brokerChannelExecutor'
2021-03-03 00:45:00.284  INFO 5898 --- [extShutdownHook] o.s.s.concurrent.ThreadPoolTaskExecutor  : Shutting down ExecutorService 'clientOutboundChannelExecutor'
2021-03-03 00:45:00.284  INFO 5898 --- [extShutdownHook] o.s.s.concurrent.ThreadPoolTaskExecutor  : Shutting down ExecutorService 'clientInboundChannelExecutor'
2021-03-03 00:45:00.284  INFO 5898 --- [extShutdownHook] o.s.s.c.ThreadPoolTaskScheduler          : Shutting down ExecutorService 'messageBrokerTaskScheduler'
2021-03-03 00:45:00.296  INFO 5898 --- [extShutdownHook] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'
2021-03-03 00:45:00.299  INFO 5898 --- [extShutdownHook] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown initiated...

问题根因定位

从日志中可看到,所有应用组件初始化流程全部正常完成,WebSocket相关的任务调度器、消息处理器、线程池均无报错。触发应用停止的执行线程为[extShutdownHook],这是Spring Boot内置的JVM外部信号关闭钩子,故障和WebSocket配置完全无关。
根因是部署方式存在问题:直接在SSH会话中执行java -jar启动的进程,会完全绑定当前SSH终端的会话生命周期。一旦SSH连接断开(包含连接超时自动断开、手动退出、网络波动中断),终端会向关联的进程组发送SIGHUP挂断信号,触发JVM执行关闭流程,对应日志里启动完成13秒后自动退出的现象。

解决方案

  • 临时调试场景:改用后台脱离会话的方式启动进程,执行命令替换为 nohup java -jar *.jar > app.log 2>&1 &。该命令会让进程脱离SSH会话绑定,即使SSH断开也不会触发关闭,同时将日志输出到指定文件便于排查。
  • 生产部署场景:推荐将应用注册为系统级systemd服务,实现进程生命周期托管。配置完成后可实现开机自启、异常自动重启、日志统一收集,不受SSH会话状态影响,是EC2环境部署Java应用的标准实践。

注:现有WebSocket配置存在两个非致命的可优化点,后续可调整:

  1. 若后续需要实现点对点单用户消息推送,需要取消代码中setUserDestinationPrefix("/user")的注释,否则用户维度的消息路由会失效
  2. setAllowedOrigins配置的域名不完整,需替换为实际的前端访问域名,避免跨域拦截

内容的提问来源于stack exchange,提问作者baekho

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.31 20:54:05