配置文件
management:
server:
port: 8889
endpoints:
web:
exposure:
#默认值访问health,info端点 用*可以包含全部端点
include: "shutdown,health,info"
endpoint:
shutdown:
enabled: true
health:
show-details: always
关闭 Tomcat
@Slf4j
public class CustomShutdown implements TomcatConnectorCustomizer,
ApplicationListener<ContextClosedEvent> {
private static final int TIME_OUT = 30;
private volatile Connector connector;
@Override
public void customize(Connector connector) {
this.connector = connector;
}
@Override
public void onApplicationEvent(ContextClosedEvent event) {
String displayName = "Web";
if (event.getSource() instanceof AnnotationConfigApplicationContext ){
displayName = ((AnnotationConfigApplicationContext) event.getSource()).getDisplayName();
}/* Suspend all external requests*/
this.connector.pause();
/* Get ThreadPool For current connector */
Executor executor = this.connector.getProtocolHandler().getExecutor();
if (executor instanceof ThreadPoolExecutor) {
log.warn("当前{}应用准备关闭",displayName);
try {
ThreadPoolExecutor threadPoolExecutor = (ThreadPoolExecutor) executor;
/* Initializes a shutdown task after the current one has been processed task*/
threadPoolExecutor.shutdown();
if (!threadPoolExecutor.awaitTermination(TIME_OUT, TimeUnit.SECONDS)) {
log.warn("当前{}应用等待超过最大时长{}秒,将强制关闭", displayName,TIME_OUT);
/* Try shutDown Now*/
threadPoolExecutor.shutdownNow();
if (!threadPoolExecutor.awaitTermination(TIME_OUT, TimeUnit.SECONDS)) {
log.error("强制关闭失败", TIME_OUT);
}
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
}
添加 Connector 回调
@Configuration
public class ShutdownConfig {
@Bean
public CustomShutdown customShutdown() {
return new CustomShutdown();
}
@Bean
public ConfigurableServletWebServerFactory webServerFactory(final CustomShutdown customShutdown) {
TomcatServletWebServerFactory tomcatServletWebServerFactory = new TomcatServletWebServerFactory();
tomcatServletWebServerFactory.addConnectorCustomizers(customShutdown);
return tomcatServletWebServerFactory;
}
}