方法一

  • Springboot提供的actuator的功能,它可以执行shutdown, health, info
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
# 设置服务的端口号为3300
server.port=3300management.endpoint.shutdown.enabled=truemanagement.endpoints.web.exposure.include=shutdown

shutdown节点打开,将/actuator/shutdown暴露web访问也设置上
除了shutdown之外还有health, info的web访问都打开的话将
配置management.endpoints.web.exposure.include=*即可。

  • 关闭时执行销毁操作
import javax.annotation.PreDestroy;public class TerminateBean {// 关闭时执行销毁操作@PreDestroypublic void destroy() {System.out.println("TerminalBean is destroyed");}
}
  • 自定义Config注册bean
import com.hqs.springboot.shutdowndemo.bean.TerminateBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class ShutDownConfig {@Beanpublic TerminateBean getTerminateBean() {return new TerminateBean();}
}

在启动类里输出启动日志

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

日志可以输出启动时的日志和停止时的日志

方法二

获取程序启动时候的context,然后关闭主程序启动时的context。这样程序在关闭的时候也会调用PreDestroy注解。如下方法在程序启动十秒后进行关闭

/* * method 2: use ctx.close to shutdown all application context*/
ConfigurableApplicationContext ctx = SpringApplication.run(ShutdowndemoApplication.class, args);
try {TimeUnit.SECONDS.sleep(10);
} catch (InterruptedException e) {e.printStackTrace();
}ctx.close();

方法三

在springboot启动的时候将进程号写入一个app.pid文件,生成的路径是可以指定的,可以通过命令 cat /Users/huangqingshi/app.id | xargs kill 命令直接停止服务,这个时候bean对象的PreDestroy方法也会调用的。这种方法大家使用的比较普遍。写一个start.sh用于启动springboot程序,然后写一个停止程序将服务停止。

/* * method 3 : generate a pid in a specified path, while use command to shutdown pid :'cat /Users/huangqingshi/app.pid | xargs kill'*/
SpringApplication application = new SpringApplication(ShutdowndemoApplication.class);
application.addListeners(new ApplicationPidFileWriter("/Users/huangqingshi/app.pid"));
application.run();

方法四

通过调用一个SpringApplication.exit()方法也可以退出程序,同时将生成一个退出码,这个退出码可以传递给所有的context。这个就是一个JVM的钩子,通过调用这个方法的话会把所有PreDestroy的方法执行并停止,并且传递给具体的退出码给所有Context。通过调用System.exit(exitCode)可以将这个错误码也传给JVM。程序执行完后最后会输出:Process finished with exit code 0,给JVM一个SIGNAL

/* * method 4: exit this application using static method*/
ConfigurableApplicationContext ctx = SpringApplication.run(ShutdowndemoApplication.class, args);
exitApplication(ctx);
public static void exitApplication(ConfigurableApplicationContext context) {int exitCode = SpringApplication.exit(context, (ExitCodeGenerator) () -> 0);System.exit(exitCode);
}

方法五

自己写一个Controller,然后将自己写好的Controller获取到程序的context,然后调用自己配置的Controller方法退出程序。通过调用自己写的/shutDownContext方法关闭程序:curl -X POST http://localhost:3333/shutDownContext

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
public class ShutDownController implements ApplicationContextAware {private ApplicationContext context;@PostMapping("/shutDownContext")public String shutDownContext() {ConfigurableApplicationContext ctx = (ConfigurableApplicationContext) context;ctx.close();return "context is shutdown";}@GetMapping("/")public String getIndex() {return "OK";}@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {context = applicationContext;}
}

如何暴力停止呢,简单,直接kill -9 相应的PID即可。

真实工作中还需要考虑的点还很多,比如需要保护暴露的点不被别人利用,一般要加一些防火墙,或者只在内网使用,保证程序安全。

在真实的工作中的时候第三种比较常用,程序中一般使用内存队列线程池的时候最好要优雅的关机,将内存队列没有处理的保存起来或线程池中没处理完的程序处理完。但是因为停机的时候比较快,所以停服务的时候最好不要处理大量的数据操作,这样会影响程序停止。

SpringBoot 优雅停止服务的几种方法相关推荐

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

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

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

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

  3. springboot 优雅停机_SpringBoot 优雅停止服务的几种方法 第309篇

    相关历史文章(阅读本文之前,您可能需要先看下之前的系列?) 国内最全的Spring Boot系列之三 一分钟get:缓存穿透.缓存击穿.缓存雪崩 - 第304篇 布隆过滤器Bloom Filter竟然 ...

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

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

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

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

  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. (转)如何修改maven的默认jdk版本
  2. java C语言内存占用_使用Cgroup限制Java使用的内存量-思路
  3. 3-3 面向对象 本章总结
  4. idea ctrl+alt+t快捷键
  5. python随机发牌_魔术师发牌问题 -- python实现
  6. C语言学习之输出“魔方阵”。所谓魔方阵是指这样的方阵,它的每一行、每一列和对角线之和均相等。
  7. flink的CEP调研与使用
  8. String.prototype 几个简洁的字符处理函数 (转)
  9. _Linux中功能强大的截图工具 - Flameshot
  10. 13.FutureTask异步计算
  11. 从16位到32位再到64位,为何16年过去,依然没有128位系统出现?
  12. 分类模型评估之ROC-AUC曲线和PRC曲线
  13. linux中posix共享内存,Linux 共享内存(POSIX)
  14. PHP 根据URL将图片下载到本地(curl爬取)
  15. 计算机地址输入法教案,计算机教案(输入法
  16. 澳洲2022人口普查结果出炉--华人占比开始下降
  17. macOS Big Sur 11.4 (20F71) 正式版(DMG、ISO、IPSW),百度网盘下载
  18. 【Unity3D】IK动画
  19. 阿里云服务器修改名称
  20. python 列表写入excel_python怎么读取和写入excel表格

热门文章

  1. B00015 C++实现的图类
  2. 学习 Perl(一) —— 安装及 hello world
  3. matlab 中使用 GPU 加速运算
  4. 记号(notation)的学习
  5. Python Flask Web 第十课 —— flask-wtf
  6. 熟悉 CMake(二)—— 以一个实例说明 CMakeLists.txt 文件的编写
  7. Tricks(二十九)—— 2^10000 的位数
  8. python简单爬虫代码-使用Python3.5写简单网络爬虫
  9. python有道-Python调用有道词典翻译
  10. 博越同级别没对手!敢和同级别quot;王者quot;硬碰硬!