SpringBoot生命周期管理之停掉应用服务几种方法

前言
在生产环境下管理Spring Boot应用的生命周期非常重要。Spring容器通过ApplicationContext处理应用服务的所有的beans的创建、初始化、销毁。
本文着重于生命周期中的销毁阶段的处理,我将使用多种方式来实现关闭Spring Boot应用服务。如果你需要了解关于Spring Boot更多内容,请看我之前写过的文章和精品合辑!
一、通过Actuator Shutdown 端点服务
Spring Boot Actuator是一个主要用于应用指标监控和健康检查的服务。可以通过Http访问对应的Endpoint来获取应用的健康及指标信息。另外,它还提供了一个远程通过http实现应用shutdown的端点。
首先,我们要在Spring Boot中引入Actuator。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
生产环境通常出于安全考虑,不能将应用关闭的访问完全公开,我们还要引入spring-boot-starter-security。具体的安全配置,请参考学习Spring security,在此不多做叙述!
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
默认情况下,出于安全考虑shutdown端点服务是处于关闭状态的,我们需要通过配置开启:
management.endpoints.web.exposure.include=*
management.endpoint.shutdown.enabled=true
endpoints.shutdown.enabled=true
至此,我们就可以通过发送一个Post请求,来停掉Spring Boot应用服务。
curl -X POST localhost:port/actuator/shutdown
这种方法的缺陷在于:当你引入Actuator的shutdown服务的时候,其他的监控服务也自动被引入了。
二、 关闭Application Context
我们也可以自己实现一个Controller开放访问端点,调用Application Context的close方法实现应用服务的关闭。
@RestController
public class ShutdownController implements ApplicationContextAware {
private ApplicationContext context;
@PostMapping("/shutdownContext")
public void shutdownContext() {
((ConfigurableApplicationContext) context).close();
}
@Override
public void setApplicationContext(ApplicationContext ctx) throws BeansException {
this.context = ctx;
}
}
我们添加了一个Controller继承自ApplicationContextAware接口,并且重写了setApplicationContext方法获取当前的应用上下文。然后在Post请求方法中调用close方法关闭当前应用。这种实现的方法更加轻量级,不会像Actuator一样引入更多的内容。我们同样可以通过发送Post请求,实现应用的关闭。
curl -X POST localhost:port/shutdownContext
同样,当你对外开放一个关闭服务的端点,你要考虑它的权限与安全性
四、退出 SpringApplication
还可以通过SpringApplication 向JVM注册一个 shutdown 钩子来确保应用服务正确的关闭。
ConfigurableApplicationContext ctx = new SpringApplicationBuilder(Application.class)
.web(WebApplicationType.NONE).run();
int exitCode = SpringApplication.exit(ctx, new ExitCodeGenerator() {
@Override
public int getExitCode() {
// return the error code
return 0;
}
});
System.exit(exitCode);
同样的效果,使用Java 8 lambda可以这样实现,代码简单很多:
SpringApplication.exit(ctx, () -> 0);
五、kill杀掉应用进程
我们还可以使用bat或者shell脚本来停止应用的进程。所以,我们首先在应用启动的时候,要把进程ID写到一个文件里面。如下所示:
SpringApplicationBuilder app = new SpringApplicationBuilder(Application.class)
.web(WebApplicationType.NONE);
app.build().addListeners(new ApplicationPidFileWriter("./bin/shutdown.pid"));
app.run();
创建一个shutdown.bat脚本,内容如下:
kill $(cat ./bin/shutdown.pid)
然后调用这个脚本就可以把应用服务进程杀死。
期待您的关注
- 博主最近新写了一本书:《手摸手教您学习SpringBoot系列-16章97节》
- 本文转载注明出处(必须带连接,不能只转文字):字母哥博客。
SpringBoot生命周期管理之停掉应用服务几种方法的更多相关文章
- Java实现生命周期管理机制
先扯再说 最近一直在研究某个国产开源的MySQL数据库中间件,拉下其最新版的代码到eclipse后,启动起来,然后做各种测试和代码追踪:用完想要关闭它时,拉出它的STOP类想要运行时,发现这个类里赫然 ...
- 快速构建Windows 8风格应用30-应用生命周期管理
原文:快速构建Windows 8风格应用30-应用生命周期管理 引言 Windows 8 中可以启动多个应用并在其中切换,我们没有必要担心降低系统速度或消耗电池电量. 因为系统会自动挂起(有时会终止) ...
- 004-docker命令-容器生命周期管理、容器操作
1.容器生命周期管理 docker run :创建一个新的容器并运行一个命令 语法:docker run [OPTIONS] IMAGE [COMMAND] [ARG...] OPTIONS说明: - ...
- Jasper:用户指南 / 设备 / 生命周期管理 / SIM 卡状态
ylbtech-Jasper:用户指南 / 设备 / 生命周期管理 / SIM 卡状态 1.返回顶部 1. SIM 卡状态 每个设备都有一个状态,决定了它能否在网络上建立数据连接,并且会影响设备是否计 ...
- Delphi 接口使用中,对象生命周期管理,如何释放需要注意的问题
网上有篇文章<Delphi接口编程的两大陷阱>,里面提到接口的生存期管理的问题.但该文章里面提到的两个问题,其实都是对 Delphi 不理解导致的. 先说该篇文章中提到的第一个问题为什 ...
- Rediskey生命周期管理-key聚合
| 导语 Redis中的数据以k-v的方式组织:为了方便管理key一般具有某些特定的模式:有些key直接是由mysql中的表行数据转化而来:如果要对Redis的key进行生命周期管理,由于Redis的 ...
- k8s的Pod状态和生命周期管理
Pod状态和生命周期管理 一.什么是Pod? 二.Pod中如何管理多个容器? 三.使用Pod 四.Pod的持久性和终止 五.Pause容器 六.init容器 七.Pod的生命周期 (1)Pod p ...
- 这么简单的ES索引生命周期管理,不了解一下吗~
对于日志或指标(metric)类时序性强的ES索引,因为数据量大,并且写入和查询大多都是近期时间内的数据.我们可以采用hot-warm-cold架构将索引数据切分成hot/warm/cold的索引.h ...
- akka-typed(1) - actor生命周期管理
akka-typed的actor从创建.启用.状态转换.停用.监视等生命周期管理方式和akka-classic还是有一定的不同之处.这篇我们就介绍一下akka-typed的actor生命周期管理. 每 ...
随机推荐
- RDDs基本操作之Transformations
逐元素Transformation map() map()接收函数,把函数应用到RDD的每个元素,返回新的RDD 举例: val lines = sc.parallelize(Array(" ...
- 二叉树总结(五)伸展树、B-树和B+树
一.伸展树 伸展树(Splay Tree)是一种二叉排序树,它能在O(log n)内完成插入.查找和删除操作. 因为,它是一颗二叉排序树,所以,它拥有二叉查找树的性质:除此之外,伸展树还具有的一个特点 ...
- 前端初探 Gitlab CI/CD
前言 纵观人类历史的发展以及三次工业革命,你会发现利用机器来替代部分人力劳动,将重复的工作自动化从而解放生产力都是发展的必然趋势,在软件工程领域也不例外,其中 CI/CD 就是其中一项,那么什么是 C ...
- 不fq安装 golang tools
go get -u -v github.com/golang/tools/go/buildutil ln -s $GOPATH/src/github.com/golang/tools $GOPATH/ ...
- 素数路径Prime Path POJ-3126 素数,BFS
题目链接:Prime Path 题目大意 从一个四位素数m开始,每次只允许变动一位数字使其变成另一个四位素数.求最终把m变成n所需的最少次数. 思路 BFS.搜索的时候,最低位为0,2,4,6,8可以 ...
- 基于Docker搭建大数据集群(二)基础组件配置
主要内容 jdk环境搭建 scala环境搭建 zookeeper部署 mysql部署 前提 docker容器之间能免密钥登录 yum源更换为阿里源 安装包 微云分享 | tar包目录下 JDK 1.8 ...
- 如何解决myeclipse2014突然无法打开的问题
今天突然发现我的myeclipse2014打开不了,昨晚还好好的,上网找了一下没有找到解决方法,于是新建一个工作区间Workspace Test,再打开File->Switch WorkSpac ...
- 【ADO.NET基础-GridView】GridView的编辑、更新、取消、删除以及相关基础操作代码
代码都是基础操作,后续功能还会更新,如有问题欢迎提出和提问....... 前台代码: <asp:GridView ID=" OnRowDataBound="GridView1 ...
- 无暇代码(js的整洁之道)
如果你关注代码本身和代码的编写方式,而不是只关心它是否能工作,那么你写代码是有一定的水准.专业开发人员将为未来的自己和“其他人”编写代码,而不仅仅只编写当前能工作就行的代码.在此基础上,简洁代码可以定 ...
- Shell之命令执行的判断依据
目录 Shell之命令执行的判断依据 参考 Shell之命令执行的判断依据