【框架】Spring Boot: 實現優雅退出

2018.11.18

前言

要求某個基於Spring Boot的調度器,能實現優雅退出,使得退出時正在運行時的作業能進行必要的回滾操作。爲此,翻譯某技術博客的總結1

方法

每個Spring應用都會在JVM裏註冊一個shutdown hook1,以保證ApplicationContext能實現優雅退出。以下的方法都是基於這一原理進行實現的。

方法一:Actuator的Endpoint機制1

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

默認配置下,shutdown端點是關閉的,需要在application.properties裏配置:

management.endpoint.shutdown.enabled=true

Actuator的端點,支持通過JMX或HTTP進行遠程訪問。而shutdown默認配置下是不支持HTTP進行Web訪問的,所以使用HTTP請求進行關閉,還需要配置:

management.endpoints.web.exposure.include=shutdown

最後,配合使用對應的URL就能讓Spring Boot應用優雅退出:

curl -X POST localhost:port/actuator/shutdown

方法二:使用ApplicationContext#close()方法

ApplicationContext#close()亦能實現優雅退出,但要使得當前application context退出,就需要一個入口,從外部接收到退出的信號。一種方法就是上述的Endpoint端點,另一種方法適用於Spring MVC的Web應用,就是定製一個Controller實現ApplicationContextAware接口如下:

@RestController
public class ShutdownController implements ApplicationContextAware {
    private ApplicationContext context;
    
    @PostMapping("/shutdownContext")
    public void shutdownContext() {
        ((ConfigurableApplicationContext) context).close();
    }
    @Override
    public void setApplicationContext(ApplicationContext ctx) throws BeansException {
        this.context = ctx;    
    }
}

同樣地,配合使用對應的URL就能讓Spring Boot應用優雅退出:

curl -X POST localhost:port/shutdownContext

方法三:@PreDestroy + kill <pid>

如果項目不是Spring MVC,又不想引入Actuator,可以直接採用ctrl + c或kill <pid>的方式。因爲Spring應用在JVM裏註冊了一個shutdown hook,所以只要能接收到退出的信號(ctrl + c或kill <pid>,而kill -9 <pid>不行),那麼應用就能正常地優雅退出。如果項目是通過nohup java -jar project.jar &方式啓動的,那麼就建議使用kill <pid>命令,給應用發送一個TERM信號,就能正常優雅退出。@PreDestroy註解允許方法完成必要的退出工作。

獲取pid的方式可使用如下兩種:

  1. Bash shell
ps -ef | grep project.jar | awk '{print $2}'
  1. Java代碼
SpringApplicationBuilder app = new SpringApplicationBuilder(Application.class).web(WebApplicationType.NONE);
app.build().addListeners(new ApplicationPidFileWriter("./bin/shutdown.pid"));
app.run();

  1. Baeldung about Spring Boot shutdown ↩︎ ↩︎ ↩︎

  2. Actuator Endpoints
    Actuator提供了Endpoint端點,可能用於對Spring Boot應用進行監控和交互。其中有一個shutdown端點,就是用於優雅退出的。使用Actuator的端點,首先需要配置Actuator相關依賴2↩︎

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章