优雅停机

主要应用在版本更新的时候,为了等待正在工作的线程全部执行完毕,然后再停止

2.3及以上版本

1.maven引入依赖

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

2.修改配置文件

management:endpoint:shutdown:enabled: trueendpoints:web:exposure:include: "shutdown"base-path: /monitor

2.1版本

除以上两步外尚需修改Application启动类

tomcat容器

package com.example;import org.apache.catalina.connector.Connector;
import org.mybatis.spring.annotation.MapperScan;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.web.embedded.tomcat.TomcatConnectorCustomizer;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.servlet.server.ServletWebServerFactory;
import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.Bean;
import org.springframework.context.event.ContextClosedEvent;import com.example.framework.datasource.DynamicDataSourceContextHolder;import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;/*** 启动程序*/
@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })
@MapperScan("com.example.*.mapper")
//@EnableScheduling
public class NumberoneApplication
{public static final Logger log = LoggerFactory.getLogger(DynamicDataSourceContextHolder.class);public static void main(String[] args){// System.setProperty("spring.devtools.restart.enabled", "false");SpringApplication.run(NumberoneApplication.class, args);log.info("----- Start Successful~启动成功   -----");}/*** 用于接受 shutdown 事件*/@Beanpublic GracefulShutdown gracefulShutdown() {return new GracefulShutdown();}/*** 配置tomcat** @return*/@Beanpublic ServletWebServerFactory servletContainer() {TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory();tomcat.addConnectorCustomizers(gracefulShutdown());return tomcat;}/*** 优雅关闭 Spring Boot。容器必须是 tomcat*/private class GracefulShutdown implements TomcatConnectorCustomizer, ApplicationListener<ContextClosedEvent> {private final Logger log = LoggerFactory.getLogger(GracefulShutdown.class);private volatile Connector connector;private final int waitTime = 10;@Overridepublic void customize(Connector connector) {this.connector = connector;}@Overridepublic void onApplicationEvent(ContextClosedEvent contextClosedEvent) {this.connector.pause();Executor executor = this.connector.getProtocolHandler().getExecutor();if (executor instanceof ThreadPoolExecutor) {try {ThreadPoolExecutor threadPoolExecutor = (ThreadPoolExecutor) executor;threadPoolExecutor.shutdown();if (!threadPoolExecutor.awaitTermination(waitTime, TimeUnit.SECONDS)) {log.warn("Tomcat 进程在" + waitTime + " 秒内无法结束,尝试强制结束");}} catch (InterruptedException ex) {Thread.currentThread().interrupt();}}}}}

Undertow容器

@SpringBootApplication
public class Application {public static void main(String[] args) {SpringApplication.run(Application.class, args);}/*** 优雅关闭 Spring Boot*/@Componentpublic class GracefulShutdown implements ApplicationListener<ContextClosedEvent> {@Autowiredprivate GracefulShutdownWrapper gracefulShutdownWrapper;@Autowiredprivate ServletWebServerApplicationContext context;@Overridepublic void onApplicationEvent(ContextClosedEvent contextClosedEvent){gracefulShutdownWrapper.getGracefulShutdownHandler().shutdown();try {UndertowServletWebServer webServer = (UndertowServletWebServer)context.getWebServer();Field field = webServer.getClass().getDeclaredField("undertow");field.setAccessible(true);Undertow undertow = (Undertow) field.get(webServer);List<Undertow.ListenerInfo> listenerInfo = undertow.getListenerInfo();Undertow.ListenerInfo listener = listenerInfo.get(0);ConnectorStatistics connectorStatistics = listener.getConnectorStatistics();while (connectorStatistics.getActiveConnections() > 0){}}catch (Exception e){// Application Shutdown}}}
}

测试验证

测试

通过postman或curl -X POST http://localhost:8080/*/shutdown
发送请求验证

control内添加方法

 @RequestMapping(value = "/a/testClose",method= RequestMethod.GET)@ResponseBodypublic String sayHi() throws InterruptedException {// 模拟复杂业务耗时处理流程Thread.sleep(10 * 1000L);return "success";}

启动项目,使用postman测试 ,会等待10s后显示请求成功,等待中…:

验证

2.1.1版本 Tomcat容器验证成功(无论是通过通过post方式调用接口或是程序命令窗口ctrl+c退出均优雅关闭程序)

参考网址

Spring boot 2.0 之优雅停机()
Spring Boot 内嵌容器 Tomcat / Undertow / Jetty 优雅停机实现
Spring Boot 2.0 实现优雅停机
再谈spring boot 优雅停机
使用actuator优雅地停止SpringBoot应用
curl 命令模拟 HTTP GET/POST 请求
Windows使用curl发送GET、POST请求

若依文档-集成actuator实现优雅关闭应用
spring文档

Spring boot 2.1版本、2.3及以上版本使用actuator实现优雅关闭程序相关推荐

  1. Spring Boot 3.0.0 发布第一个里程碑版本M1,你的 Java 升到 17 了吗?

    欢迎关注方志朋的博客,回复"666"获面试宝典 ‍ ‍文章来源:程序猿DD‍ ‍ 2022年1月20日,Spring官方发布了Spring Boot 3.0.0的第一个里程碑版本M ...

  2. Spring Boot 2.4.3、2.3.9 版本发布,你准备好了吗?

    新年上班第一天,Spring Boot 就发布了最新的2.4.3 .2.3.9 版本.心急的小伙伴现在可从 repo.spring.io 和 Maven Central 获得相关内容. <par ...

  3. spring boot / cloud (二十) 相同服务,发布不同版本,支撑并行的业务需求

    有半年多没有更新了,按照常规剧本,应该会说项目很忙,工作很忙,没空更新,吧啦吧啦,相关的话吧, 但是细想想,是真的么?,忙到这几个字都没时间打么?毕竟大家都很忙的,所以忙并不是啥理由. 那是因为啥呢? ...

  4. Spring Boot + OAuth2.0 实现微信扫码登录,这才叫优雅

    点击"终码一生",关注,置顶公众号 每日技术干货,第一时间送达! 微信开放平台:微信扫码登录功能 官方文档:https://developers.weixin.qq.com/doc ...

  5. Spring Boot + OAuth2.0 实现微信扫码登录,这才叫优雅!!

    微信开放平台:微信扫码登录功能 官方文档:https://developers.weixin.qq.com/doc/oplatform/Website_App/WeChat_Login/Wechat_ ...

  6. Spring Boot + MDC 实现全链路调用日志跟踪,这才叫优雅!

    欢迎关注方志朋的博客,回复"666"获面试宝典 1.简介: MDC(Mapped Diagnostic Context,映射调试上下文)是 log4j .logback及log4j ...

  7. 前瞻:Spring Boot 2.4.0 第二个里程碑版本发布

    点击上方蓝色"程序猿DD",选择"设为星标" 回复"资源"获取独家整理的学习资料! 来源 | https://www.oschina.net ...

  8. Spring Boot 1.0和Spring Boot 1.0.1错误修复版本

    Spring Boot团队最近宣布了Spring Boot 1.0版本 ,随后是Spring Boot 1.0.1.RELEASE ,这是一个错误修复版本,其中还包含一些新功能. Spring Boo ...

  9. Spring 应用开发框架 Spring Boot 2.3.0 最新版本发布

    Spring Boot 项目旨在简化创建产品级的 Spring 应用和服务.你可通过它来选择不同的 Spring 平台.可创建独立的 Java 应用和 Web 应用,同时提供了命令行工具来允许 'sp ...

  10. spring boot和spring cloud版本冲突解决方案

    spring cloud和springboot版本是需要匹配才能一起使用的.在新建项目的时候,如果两者版本不一致,很有可能会导致项目启动失败. spring cloud和springboot的版本对应 ...

最新文章

  1. AI机器学习科研助力 | 计算机科学方向一对一科研项目
  2. php中转,使用 PHP Curl 做数据中转
  3. vmware-tools安装指南
  4. Ansible-Playbook-template算数运算以及流程控制
  5. idea中如何创建servlet文件
  6. 大数据 互联网架构阶段 Redis
  7. Problem G. Pandaria(线段树合并 + Kruskal 重构树)
  8. 【转】第01课:生活中的监听模式——一坑爹的热水器
  9. C语言实现单链表面试题汇总
  10. 成员函数指针与高性能的C++委托(上篇)
  11. 反射(3)—动态、静态代理
  12. lambda python aws_AWS Lambda Layer For Python Pakage
  13. 1470. 重新排列数组
  14. CMap的使用(转)
  15. 图像增强--视网膜皮层Retinex算法(二)
  16. php opendir 相对路径,我是wamp环境,怎么样让php的opendir函数可以接受相对路径?...
  17. PKPM结构设计软件案例教学
  18. 10个容易被接受的辞职理由
  19. 量化研究 | 策略在指数与主连复权的差异化分析(二)
  20. 批量提取 srt 字幕文件中的文字

热门文章

  1. php 获取客户端的ip、地理信息、浏览器信息、本地真实ip
  2. GridView的DataKeyNames属性(转)
  3. 国内外著名CAD、CAM雕刻软件介绍
  4. [20171120]11G关闭直接路径读.txt
  5. 随心所欲玩复制 详解robocopy (完)
  6. Linux如何产看系统信息
  7. -Dmaven.multiModuleProjectDirectory system propery is not set.
  8. java for语句
  9. Windows 7 通过无线网卡,模拟Wifi,实现手机,电脑等无线设备共享上网
  10. 隐马尔可夫模型(HMM)简介