springboot 优雅停机实现

为了更好的实现服务资源释放,包括数据库连接池,线程池,注销微服务等,因此要实现优雅停服,springboot actuator 开放了shutdown端口,可以自定义实现优雅停服,案例如下

public class GracefulShutDown implements TomcatConnectorCustomizer, ApplicationListener {

	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 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();
	}

 

你可能感兴趣的:(java)