SpringBoot优雅停机
优雅停机需要两个条件:
- serlvet容器支持
- 开启JMX或者endPoint
目前统一采用endpoint的http形式执行优雅停机,其依赖于Spring的监控组件spring-boot-starter-actuator
针对使用tomcat容器的SpringBoot项目,优雅停机步骤如下:
1.引入监控组件
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId><version>xx.xx.xx</version></dependency>
2.开启优雅停机功能
server.shutdown=gracefulspring.lifecycle.timeout-per-shutdown-phase=10smanagement.endpoints.web.exposure.include=shutdown #包含shutdown即可management.endpoint.shutdown.enabled=true
server.shutdown=graceful,优雅停机,
server.shutdown=immediate,表示立即停机�3.执行停机操作
curl -X POST http://localhost:3333/actuator/shutdown
线程池优雅停机
常用线程池有一下两个:
- ThreadPoolTaskScheduler
- �ThreadPoolTaskExecutor
参数配置
ThreadPoolTaskScheduler定时任务线程池,ThreadPoolTaskExecutor异步线程池,
两者都提供了
//表明等待所有线程执行完executor.setWaitForTasksToCompleteOnShutdown(true);//等待xx秒后强制停止executor.setAwaitTerminationSeconds(10);
�Bean销毁影响线程池执行
当springboot中存在线程池时,优雅停机后,可能线程池中的线程还在继续运行时,其依赖的逻辑处理bean已经消费,这个会导致线程处理异常发生,不能够保证数据完整性。
dubbo优雅停机
@BeanDubboShutdownListener dubboShutdownListener() {return new DubboShutdownListener();}public static class DubboShutdownListener implements ApplicationListener, PriorityOrdered {@Overridepublic void onApplicationEvent(ApplicationEvent event) {if (event instanceof ApplicationStartedEvent) {Runtime.getRuntime().removeShutdownHook(DubboShutdownHook.getDubboShutdownHook());log.info("dubbo default shutdown hook removed,will be managed by spring");} else if (event instanceof ContextClosedEvent) {log.info("start destroy dubbo on spring close event");DubboShutdownHook.getDubboShutdownHook().destroyAll();log.info("dubbo destroy finished");}}@Overridepublic int getOrder() {return 0;}}
容器关闭时,调用DubboShutdownHook.getDubboShutdownHook().destroyAll()方法,将当前服务注册在注册中心的服务撤销,保证当前节点不会被消费者调用。
MQ优雅停机
总结
优雅停机优先级,要遵循以下顺序:
RestFul>Dubbo>MQ>线程池
