스프링 부트 셧다운 훅
Spring Boot 어플리케이션이 셧다운되었을 때 발생하는 커스텀셧다운 루틴을 등록/추가하려면 어떻게 해야 합니까?
시나리오:Spring Boot 어플리케이션을 Jetty 서블릿컨테이너(내장 Jetty 없음)에 전개합니다.응용 프로그램에서 로그백을 로그백에 사용하고 있으며 실행 시 로그백의 MBean JMX 컨피규레이터를 사용하여 로그 레벨을 변경하려고 합니다.이 문서에는 메모리 누수를 피하기 위해 셧다운 시 특정 Logger Context 셧다운 방식을 호출해야 한다고 기재되어 있습니다.
Spring Boot 셧다운 이벤트를 청취하는 좋은 방법은 무엇입니까?
시도했습니다.
public static void main(String[] args) throws Exception {
ConfigurableApplicationContext cac = SpringApplication.run(Example.class, args);
cac.addApplicationListener(new ApplicationListener<ContextClosedEvent>() {
@Override
public void onApplicationEvent(ContextClosedEvent event) {
logger.info("Do something");
}
});
}
단, 어플리케이션이 셧다운되어도 이 등록된 리스너는 호출되지 않습니다.
각 Spring Application은 종료 시 ApplicationContext가 정상적으로 닫히도록 하기 위해 JVM에 셧다운 후크를 등록합니다.모든 표준 Spring 라이프 사이클 콜백(DisposableBean 인터페이스 또는 @PreDestroy 주석 등)을 사용할 수 있습니다.
또한 콩은 org.springframework.boot를 구현할 수 있습니다.응용 프로그램 종료 시 특정 종료 코드를 반환하는 경우 ExitCodeGenerator 인터페이스.
@syclick이 말한 대로 이것을 시도해 본 적이 있습니까?
@SpringBootApplication
@Slf4j
public class SpringBootShutdownHookApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootShutdownHookApplication.class, args);
}
@PreDestroy
public void onExit() {
log.info("###STOPing###");
try {
Thread.sleep(5 * 1000);
} catch (InterruptedException e) {
log.error("", e);;
}
log.info("###STOP FROM THE LIFECYCLE###");
}
}
리스너가 너무 늦게 등록되었습니다(콘텍스트가 이미 닫힐 때까지 이 회선은 도달하지 않습니다).이 정도면 충분할 거야@Bean.
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletListenerRegistrationBean;
import org.springframework.boot.web.support.SpringBootServletInitializer;
import org.springframework.context.annotation.Bean;
@SpringBootApplication
@EnableAutoConfiguration
public class Application extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@NotNull
@Bean
ServletListenerRegistrationBean<ServletContextListener> myServletListener() {
ServletListenerRegistrationBean<ServletContextListener> srb =
new ServletListenerRegistrationBean<>();
srb.setListener(new ExampleServletContextListener());
return srb;
}
}
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
public class ExampleServletContextListener implements ServletContextListener {
@Override
public void contextInitialized(
ServletContextEvent sce) {
// Context Initialised
}
@Override
public void contextDestroyed(
ServletContextEvent sce) {
// Here - what you want to do that context shutdown
}
}
서버의 셧다운 프로세스를 몇 분간 보류해야 하는 유사한 사용 사례가 있습니다.질문에 기재된 것과 같은 접근방식을 사용하고 있습니다.다만 변경된 것은 서비스를 부팅한 후에 리스너를 추가하는 대신 리스너를 추가하는 것입니다.(ContextClosedEvent응용 프로그램을 실행하기 전에)
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication application = new SpringApplication(Application.class);
application.addListeners((ApplicationListener<ContextClosedEvent>) event -> {
log.info("Shutdown process initiated...");
try {
Thread.sleep(TimeUnit.MINUTES.toMillis(5));
} catch (InterruptedException e) {
log.error("Exception is thrown during the ContextClosedEvent", e);
}
log.info("Graceful Shutdown is processed successfully");
});
application.run(args);
}
}
언급URL : https://stackoverflow.com/questions/26678208/spring-boot-shutdown-hook
'sourcecode' 카테고리의 다른 글
| MockMvc는 더 이상 스프링 부트 2.2.0에서 UTF-8 문자를 처리하지 않습니다.풀어주다 (0) | 2023.03.19 |
|---|---|
| Jest 테스트 실패: TypeError: window.matchMedia가 함수가 아닙니다. (0) | 2023.03.19 |
| mongodb에서 여러 어레이 요소를 업데이트하는 방법 (0) | 2023.03.19 |
| 빈 배열을 입력으로 사용하는 'useCallback'과 두 번째 매개 변수를 사용하지 않는 'useCallback'의 차이점은 무엇입니까? (0) | 2023.03.19 |
| AngularJS: $resource 요청과 함께 인증 토큰을 보내려면 어떻게 해야 합니까? (0) | 2023.03.19 |