springboot 优雅停机实现
为了更好的实现服务资源释放,包括数据库连接池,线程池,注销微服务等,因此要实现优雅停服,springboot actuator 开放了shutdown端口,可以自定义实现优雅停服,案例如下
public class GracefulShutDown implements TomcatConnectorCustomizer, ApplicationListener<ContextClosedEvent> {
private static final Logger logger = LoggerFactory.getLogger(GracefulShutDown.class);
private volatile Connector connector;
private final int waitTime = 1800;
@Override
public void customize(Connector connector) {
this.connector = connector;
}
/**
* 关闭资源
*/
@Override
public void onApplicationEvent(ContextClosedEvent contextClosedEvent) {
// tomcat 暂停对外服务
logger.info("暂停tomcat处理http请求...");
this.connector.pause();
logger.info("关闭容器资源...");
// 获取tomcat 线程池
Executor executor = this.connector.getProtocolHandler().getExecutor();
try {
if (executor instanceof ThreadPoolExecutor) {
ThreadPoolExecutor threadPoolExecutor = (ThreadPoolExecutor) executor;
// 关闭tomcat 线程池
threadPoolExecutor.shutdown();
if (!threadPoolExecutor.awaitTermination(waitTime, TimeUnit.SECONDS)) {
logger.warn("Tomcat 进程在 " + waitTime + " 秒内无法结束,尝试强制结束");
}
}
} catch (Exception e) {
logger.error("关闭资源异常 {}", e);
Thread.currentThread().interrupt();
}
}
}
/**
*
* @ClassName: ContextFinalizer
* @Description: 关闭tomcat时,同时关闭数据库链接超时检测线程
* @author eno
* @date :2019年12月20日 下午12:20:36
*/
@WebListener
public class ContextFinalizer implements ServletContextListener {
private static final Logger logger = LoggerFactory.getLogger(ContextFinalizer.class);
@Override
public void contextInitialized(ServletContextEvent sce) {
ServletContextListener.super.contextInitialized(sce);
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
Enumeration<Driver> drivers = DriverManager.getDrivers();
while (drivers.hasMoreElements()) {
Driver driver = drivers.nextElement();
try {
DriverManager.deregisterDriver(driver);
} catch (SQLException e) {
logger.error("ContextFinalizer: deregisterDriver failed,{}", e);
}
}
try {
AbandonedConnectionCleanupThread.shutdown();
} catch (InterruptedException e) {
logger.error("ContextFinalizer: server problem cleaning up :{}", e);
}
}
}
2.在配置停服配置类注入connecter
/**
* 注入connecter
* @param gracefulShutDown
* @return
*/
@Bean
public ServletWebServerFactory servletContainer(GracefulShutDown gracefulShutDown) {
TomcatServletWebServerFactory tomcatServletWebServerFactory = new TomcatServletWebServerFactory();
tomcatServletWebServerFactory.addConnectorCustomizers(gracefulShutDown);
return tomcatServletWebServerFactory;
}
@Bean
public GracefulShutDown gracefulShutDown() {
return new GracefulShutDown();
}
