在使用SpringBoot的时候,通常情况下,我都是使用ps -ef | grep java
找到对于的服务器id,然后通过kill -9 进程号
进行删除的,这样会导致正在进行的进程也会被关闭,而没有将目前的工作进行保存,最近看到一篇文章,也就自己进行尝试,参考链接放在了最后面
- 通过SpringBoot提供的actuator
actuator提供审计,健康检查,HTTP跟踪等功能,能够帮助我们监控和管理SpringBoot,在这里他提供了执行shutdown的功能
<!-- 添加依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
#在application.yml 中进行配置,shutdown默认是关闭的,这里需要将其设置为true,同时将接口暴露出来到web上
management:
endpoint:
shutdown:
enabled: true
endpoints:
web:
exposure:
include: shutdown
// 配置controller
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.PreDestroy;
@RestController
public class EpidemicController {
private static final Logger logger = LoggerFactory.getLogger(EpidemicController.class);
@Test
@GetMapping("/test")
public String test(){
return "test";
}
// 为控制类定义对应的销毁方法
@PreDestroy
public void preDestroy(){
System.out.print("controller is destroy");
}
}
启动并访问测试接口,访问正常
使用post访问actuator提供的关闭接口,这里我用idea的控制台进行post访问
curl -X POST http://localhost:8081/epidemic/actuator/shutdown
系统正常退出,并且调用了定义好的销毁方法
2. 获取程序启动时候的context,然后关闭主程序启动时的context
// 构建application的时候,将启动时的ConfigurableApplicationContext保存为静态变量,然后在接口中进行关闭
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
@SpringBootApplication
public class EpidemicApplication {
public static ConfigurableApplicationContext ctx;
public static void main(String[] args) {
ctx = SpringApplication.run(EpidemicApplication.class,args);
}
}
import cn.edu.dgut.EpidemicApplication;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.PreDestroy;
@RestController
public class EpidemicController {
private static final Logger logger = LoggerFactory.getLogger(EpidemicController.class);
@GetMapping("/test")
public String test(){
return "test";
}
@PreDestroy
public void preDestroy(){
System.out.print("controller is destroy");
}
// 在接口中调用的时候进行关闭
@GetMapping("/shutdown")
public void shutdown(){
System.out.print("shutdown project");
EpidemicApplication.ctx.close();
}
}
结果:程序正常退出
3. SpringBoot启动的时候将进程号写入一个app.pid文件
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.ApplicationPidFileWriter;
@SpringBootApplication
public class EpidemicApplication {
public static void main(String[] args) {
SpringApplication application = new SpringApplication(EpidemicApplication.class);
// 添加一个pid监听器,将pid写入文件中
application.addListeners(new ApplicationPidFileWriter("/root/java/test/app.pid"));
application.run(args);
}
}
通过cat /root/java/test/app.pid | xargs kill
将程序关闭
参考链接:https://mp.weixin.qq.com/s/oDVaem4rY8AemFEgIZEfdQ
来源:CSDN
作者:xcz1314
链接:https://blog.csdn.net/xcz1314/article/details/104150054