相关历史文章(阅读本文之前,您可能需要先看下之前的系列?)

国内最全的Spring Boot系列之三

一分钟get:缓存穿透、缓存击穿、缓存雪崩 - 第304篇

布隆过滤器Bloom Filter竟然让我解决了一个大厂的问题 - 第305篇

100G的文件如何读取 - 第306篇

100G的文件如何读取续集 - 第307篇

Java语言的优雅停机 - 第308篇

师傅:对于java的shutdown hook有所了解之后,我们还是重点来看看Spring Boot如何优化停止服务吧。

悟纤:师傅,这节课那我认真听了,不然到时候生产环境都不知道如何正确停止服务了。

师傅:你这话… 说的… 师傅讲的每节课都很重要,好不。

悟纤:师傅,每节课我都有认真听的,不行待会你随便考我下。

师傅:那我们今天先把这个SpringBoot如何优雅停止学习完,在慢慢折磨你…

悟纤:师傅,我脑瓜怎么就嗡嗡的呐。

一、准备工作

1.1 准备一个项目

随便创建一个Spring Boot项目,这里使用的是截止到2020年5月 最新的版本:2.2.7.RELEASE。

1.2 创建一个bean

我们创建一个Bean ,有一个销毁的方法:

@Componentpublic class TerminateBean {    @PreDestroy    public void preDestroy() {        System.out.println("TerminalBean is destroyed");    }}

在接下来的测试中,主要是看这个preDestroy会不会被执行。

1.3 添加actuator的功能

SpringBoot 提供的actuator的功能,它可以执行shutdown, health, info等,默认情况下,actuator的shutdown是disable的,我们需要打开它。

利用actuator也是停止服务的方式,在下面会使用到,这里先把依赖添加进来。

引入acturator的maven依赖:

  <dependency>          <groupId>org.springframework.bootgroupId>          <artifactId>spring-boot-starter-actuatorartifactId>      dependency>

打开shutdown节点:

修改applicatoin.properties文件:

management.endpoint.shutdown.enabled=truemanagement.endpoints.web.exposure.include=*

这里暴露了所有的,也可以指定暴露shutdown:

management.endpoint.shutdown.enabled=truemanagement.endpoints.web.exposure.include=shutdown

二、SpringBoot的n中停机操作

2.1 Run As – Java Application运行 – Console Termiante关闭

我们使用Run As – Java Application的方式进行运行我们的Application,启动成功之后,使用Console中的Terminate关闭。

此时控制台不会执行preDestroy方法。

2.2 Run As – Spring Boot App运行 – Console Terminate关闭

我们使用Run As – Spring Boot App的方式进行运行我们的Application,启动成功之后,使用Console中的Terminate关闭。

此时控制台会执行preDestroy方法。

2.3 Run As – Java Application运行 – kill -15 pid关闭

我们使用Run As – JavaApplication的方式进行运行我们的Application,启动成功之后,kill -15 pid。

此时控制台会执行preDestroy方法。

2020-05-09 19:47:08.640  INFO 682 --- [extShutdownHook] o.s.s.concurrent.ThreadPoolTaskExecutor  : Shutting down ExecutorService 'applicationTaskExecutor'TerminalBean is destroyed

注意控制台的打印信息:有一个我们在前面讲过的非常熟悉的extShutdownHook,不然猜出Spring底层也是使用了

Runtime.getRuntime().addShutdownHook(Thread hook);

我们看下源码:

org.springframework.context.support.AbstractApplicationContext.registerShutdownHook():

@Override  public void registerShutdownHook() {    if (this.shutdownHook == null) {      // No shutdown hook registered yet.      this.shutdownHook = new Thread() {        @Override        public void run() {          synchronized (startupShutdownMonitor) {            doClose();          }        }      };      Runtime.getRuntime().addShutdownHook(this.shutdownHook);    }  }

2.4 Run As – Java Application运行 – kill -9 pid关闭

我们使用Run As – JavaApplication的方式进行运行我们的Application,启动成功之后,kill -9 pid。

此时控制台不会执行preDestroy方法。

2.5 actuator:post shutdown

还记得我们在准备工作的时候,添加了actuator,这个会暴露出来一个/actuator/shutdown的地址,我们就可以请求一下:

curl -X POST  http://localhost:8080/actuator/shutdown

注意:是post方法,而且post这里要大写、大写、大写,重要的事情说3遍,否则会报错:

{  "timestamp": "2020-05-11T07:37:55.154+0000",  "status": 405,  "error": "Method Not Allowed",  "message": "Request method 'post' not supported",  "path": "/actuator/shutdown"}

请求成功的话,会返回:

{"message":"Shutting down,bye..."}

此时控制台会执行preDestroy方法。

2.6 ApplicationContext.close()

这种方式的思路就是获取到ApplicationContext,然后调用它的close()方法。

@RestControllerpublic class ShutDownController implements ApplicationContextAware {  private ApplicationContext applicationContext;    @Override  public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {    this.applicationContext = applicationContext;  }    @RequestMapping("/shutdownByCTX")    public String shutdownByCTX(){        ConfigurableApplicationContext ctx = (ConfigurableApplicationContext) applicationContext;        ctx.close();        return "context is shutdown!!!";    }}

说明:编写一个类实现ApplicationContextAware,主要是要获取上下文ApplicationContext;然后我们暴露一个请求/shutdownByCTX,在此方法使用applicationContext的close方法。

测试,可以通过浏览器访问地址:

http://127.0.0.1:8080/shutdownByCTX

注意:当请求/shutdownByCTX的话,并不能看到返回值,而是:

curl: (52) Empty reply from server

此时控制台会执行preDestroy方法。

2.7 SpringApplication.exit()

利用SpringApplication提供的exit方法:

  @RequestMapping("/shutdownBySpringApplication")    public String shutdownBySpringApplication(){    SpringApplication.exit(applicationContext,(ExitCodeGenerator)()->0);        return "context is shutdown!!!";    }

此时控制台会执行preDestroy方法。

2.8 pid | xargs kill

此方式是将pid写入到文件,然后使用xargskill进行关闭服务。

  public static void main(String[] args) {    SpringApplication application = new SpringApplication(SpringBootShutdownDemoApplication.class);        // 指定一个文件,写入pid号        application.addListeners(new ApplicationPidFileWriter("/data/tmp/app.pid"));        application.run(args);  }

通过命令 cat /data/tmp/app.pid| xargs kill命令直接停止服务。

此时控制台会执行preDestroy方法。

三、悟纤小结

悟纤:师傅,你今天这节课讲的有点乱呐?是不是来事了?

师傅:徒儿,看来你今天没有挨抽,不舒服,是吧?

悟纤:师傅,那怪徒儿太笨,没消化的了嘛。

师傅:那好,你按照自己的理解,来和大家梳理下。

小结下:

一、通过应用暴露shutdown

(1)actutor的/actutor/shutdown方法(需要配置):此时控制台会执行preDestroy方法。

(2)利用Application的close()方法(需要编码暴露出一个访问的方法):此时控制台会执行preDestroy方法。

(3)利用SpingApplication的exit()方法(需要编码暴露出一个访问的方法):此时控制台会执行preDestroy方法。

二、kill

(1)kill -9 pid:不需要编码,也不需要配置,利用操作系统的强制关闭经常指令;此时控制台不会执行preDestroy方法。

(2)kill -15 pid:不需要编码,也不需要配置,利用操作系统的强制关闭经常指令;此时控制台会执行preDestroy方法。

(3)kill | xargs kill:需要编码,然后利用操作系统的指令cat /data/tmp/app.pid |xargs kill;此时控制台会执行preDestroy方法。

四、生产环境怎么玩呐?

在生产环境,我们是这么玩的?

编写一个sh脚本,通过grep查找到我们项目的pid,然后先使用kill -15 pid,然后sleep一下,然后在超找pid , 如果没找到,说明已经关闭了,如果找到了,说明关闭失败了,那么就使用kill-9 pid强制关闭进程了。

我就是我,是颜色不一样的烟火。我就是我,是与众不同的小苹果。

à悟空学院:https://t.cn/Rg3fKJD

学院中有Spring Boot相关的课程!点击「阅读原文」进行查看!

SpringBoot视频:http://t.cn/A6ZagYTi

Spring Cloud视频:http://t.cn/A6ZagxSR

SpringBoot Shiro视频:http://t.cn/A6Zag7IV

SpringBoot交流平台:https://t.cn/R3QDhU0

SpringData和JPA视频:http://t.cn/A6Zad1OH

SpringSecurity5.0视频:http://t.cn/A6ZadMBe

Sharding-JDBC分库分表实战:

http://t.cn/A6ZarrqS

分布式事务解决方案「手写代码」:

http://t.cn/A6ZaBnIr

深入理解JVM内存模型/调优实战:

http://t.cn/A6wWMVqG

springboot 优雅停机_SpringBoot 优雅停止服务的几种方法 第309篇相关推荐

  1. SpringBoot 优雅停止服务的几种方法 - 第309篇

    相关历史文章(阅读本文之前,您可能需要先看下之前的系列

  2. springboot 优雅关闭_Springboot 优雅停止服务的几种方法

    在使用Springboot的时候,都要涉及到服务的停止和启动,当我们停止服务的时候,很多时候大家都是kill -9 直接把程序进程杀掉,这样程序不会执行优雅的关闭.而且一些没有执行完的程序就会直接退出 ...

  3. controller调用controller的方法_SpringBoot 优雅停止服务的几种方法

    转自:博客园,作者:黄青石 www.cnblogs.com/huangqingshi/p/11370291.html 在使用 SpringBoot 的时候,都要涉及到服务的停止和启动,当我们停止服务的 ...

  4. SpringBoot 优雅停止服务的几种方法

    方法一 Springboot提供的actuator的功能,它可以执行shutdown, health, info <dependency><groupId>org.spring ...

  5. Spring Boot 优雅停止服务的几种方法

    作者 | 黄青石 来源 | https://www.cnblogs.com/huangqingshi/p/11370291.html 最近突然想到了优雅停止 SpringBoot 服务问题,在使用 S ...

  6. 停止计算机sql服务,SQL Server启动和停止服务的三种方法

    一.为什么要启动SQL Server服务? 1.如果你不开启服务,去连接数据会出现报错信息 2.因为不连接到服务器,就对数据库操作不了 二.启动SQL Server的三种方法 第一种:后台启动服务 * ...

  7. 打开和关闭mysql服务的两种方法

    方法一:使用cmd命令 首先,打开我们的dos窗口,开始-运行-输入cmd. 如上图所示,输入net start mysql 回车即可启动,输入net stop mysql 回车即可关闭. 方法二:选 ...

  8. linux系统下重启网络服务的两种方法

    linux系统下重启网络服务的两种方法 发布时间:2020-04-02 11:25:25 来源:亿速云 阅读:207 作者:小新 今天小编给大家分享的是linux系统下重启网络服务的两种方法,很多人都 ...

  9. 启动计算机管理服务,电脑打开服务管理界三种方法

    Win7服务管理包含了计算机操作系统和应用程序提供的所有服务,比如打印机服务,如果没有接入打印机设备,它的启动就没有了意义.所以可以通过禁用一些用不到的服务来加快开机启动,优化系统性能.但是很多用户不 ...

最新文章

  1. 成员资格、授权 – ASP.NET MVC 4 系列
  2. LeetCode - 4. 寻找两个正序数组的中位数
  3. 分布式服务器集群架构方案思考
  4. 如何直接强制客户端刷新.js文件
  5. android视频通信和web端,探讨用webrtc在手机和浏览器之间实现音视频实时通信的实施环境...
  6. 【数据库】Oracle用户、授权、角色管理
  7. Android开发 - 掌握ConstraintLayout(一)传统布局的问题
  8. VMware虚拟机的三种联网方法及原理
  9. wrapper怎么用_用责任链模式设计拦截器
  10. 【面试笔记系列】排序算法汇总
  11. java集合是wftc_java的集合是什么?
  12. DBeaver数据库连接工具的简单操作
  13. html制作dnf,dnf怎么制作img文件 时装拼合教程
  14. phpdesigner怎么写php,phpdesigner
  15. windows睡眠和休眠的区别
  16. dell服务器全系列手册,DELL服务器 RAID配置中文手册.pdf
  17. 数据压缩作业:清音、浊音、爆破音频谱分析
  18. SHAMANIC Heil Amazonas-DschungelSHAMA
  19. 用Python给娃送上一份猪年春节礼物。文末源码!
  20. c2059 错误类型

热门文章

  1. 算法高级(47)-AI现在都可以写代码了-辅助编程
  2. java接收前台tex格式t数据_java 下载文件时,设置response.setContentType 根据文件类型...
  3. Keychain的介绍和使用
  4. Node.js之HTTP模块学习
  5. Tree树 递归查询,显示成JSON格式
  6. 对于超平面的理解[转载]
  7. Metaspace泄漏排查
  8. angularJS之angular-datatable的方法
  9. 从省市区多重级联想到的,react和jquery的差别
  10. Zend Framework实例教程三