首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >SpringBoot优雅退出

SpringBoot优雅退出

作者头像
静儿
发布于 2026-11-03 08:35:48
发布于 2026-11-03 08:35:48
690
举报
文章被收录于专栏:编程一生编程一生

背景

我看了一些介绍SpringBoot源码的文章,里面都是从SpringApplication这个外部调用入口开始,重点介绍里面的listener监听器。今天我想想说说SpringBoot的优雅退出机制。

调用入口调用SpringApplication开始启动SpringBoot

代码语言:javascript
复制
@SpringBootApplication
public class Application {
    public static void main(String[] args) throws Exception {
        SpringApplication.run(Application.class, args);
    }
}

SpringApplication实例初始化时有以下操作

代码语言:javascript
复制
public SpringApplication(Object... sources) {
    this.bannerMode = Mode.CONSOLE;
    this.logStartupInfo = true;
    this.addCommandLineProperties = true;
    this.headless = true;
    this.registerShutdownHook = true;
    this.additionalProfiles = new HashSet();
    this.initialize(sources);
}

其中有一步this.registerShutdownHook注册jvm退出前的事件。

概念

jvm有shutdwonHook机制,中文习惯叫优雅退出。相当于在linux系统中执行SIGTERM(kill -15 或者 svc -d)时退出前执行的一些操作。

原理

以linux系统为例说明:

进程在响应kill -15 pid命令进行关闭操作时默认发送SIGTERM信号至指定进程/进程组。如果进程没有捕获该信号的逻辑,则SIGTERM的作用是终止进程。而registerShutdownHook=true说明有注册的事件需要捕获该信号,先执行相应的逻辑再进行终止。

代码语言:javascript
复制
/**
* Register a shutdown hook with the JVM runtime, closing this context
* on JVM shutdown unless it has already been closed at that time.
* <p>Delegates to {@code doClose()} for the actual closing procedure.
* @see Runtime#addShutdownHook
* @see #close()
* @see #doClose()
*/
@Override
public void registerShutdownHook() {
   if (this.shutdownHook == null) {
      // No shutdown hook registered yet.
      this.shutdownHook = new Thread() {
         @Override
         public void run() {
            synchronized (startupShutdownMonitor) {
               doClose();
            }
         }
      };
      Runtime.getRuntime().addShutdownHook(this.shutdownHook);
   }
}

如上面spring里registerShutdownHook的源码所示,就是注册一个jvm的shutdownHook钩子函数。jvm退出前会执行这个钩子函数。这个关闭操作在强制退出的时候不起作用。强制关闭范围详见下图

一个SpringBoot项目在优雅退出时做的事情可以通过log来感受一下

代码语言:javascript
复制
2019/06/20 20:47:20.405 Thread-29 [INFO] NettyHttpServer (NettyHttpServer.java:171) Close NettyHttpServer bind 0.0.0.0/0.0.0.0:5080

2019/06/20 20:47:20.405 Thread-36 [INFO] AnnotationConfigApplicationContext (AbstractApplicationContext.java:984) Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@a37aefe: startup date [Thu Jun 20 20:45:38 CST 2019]; root of context hierarchy

2019/06/20 20:47:20.406 Thread-32 [INFO] NettyServer (NettyServer.java:130) stopping netty server(XXX:9000), sleep 6 seconds!

2019/06/20 20:47:20.407 Thread-35 [INFO] ScheduleManager (ScheduleManager.java:373) Before taskNode quit,check executing task and callback result.

2019/06/20 20:47:20.407 Thread-35 [INFO] ScheduleManager (ScheduleManager.java:228) Destroy task node resources: zk and threadpool.

2019-06-20 20:47:20,430 Thread-35 WARN Unable to register Log4j shutdown hook because JVM is shutting down. Using SimpleLogger

总结

分析问题先找抓手

相关阅读

分布式架构之「 概念」

你看不懂的spring原理是因为不知道这几个概念

专治不会看源码的毛病--spring源码解析AOP篇(2017版)

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2026-11-02,如有侵权请联系 cloudcommunity@tencent.com 删除
目录
  • 分布式架构之「 概念」
  • 你看不懂的spring原理是因为不知道这几个概念
  • 专治不会看源码的毛病--spring源码解析AOP篇(2017版)
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档