最近在使用spring boot 框架以微服务的形式开发项目,在网关层做了负载均衡,每次重启的时候直接kill掉进程 然后重启,但是其中会有一个问题,假如在重启的时候还有任务在跑,正好执行一半的时候,但是程序被kill了,那就执行了一半,那么数据就会有问题,所以直接用kill命令是有问题的,会造成数据缺失。
kill -9 进程id直接用这个命令据说也能行的通,但是我实验了好几次都是不行的,还是直接被杀死,没有等我任务执行完成。
1.actuator方式
网上查了查发现spring有自己的方法
首先引入依赖包
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
//安全验证依赖包
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
配置文件,配置对应的参数:
endpoints.shutdown.enabled=true #启用shutdown
endpoints.shutdown.sensitive=true #开启shutdown的安全验证
security.user.name=userName #用户名
security.user.password=password #密码
management.security.role=XX_ROLE #角色(我实验没有作用)
endpoints.shutdown.path=/shutdown #重启的url路径
management.port=端口号 #指定管理端口
management.address=X.X.X.X #指定客户端ID
把连接的请求放进自己的shell脚本里面就可以了,每次重启的时候,会检测是否还有任务在跑,如果有任务在跑就不会关闭进程,会等任务执行完了在去结束进程
2.关闭上下文方式
第一种方式,我服务器跑的时候curl请求开始的时候挺快的,但是过一会会特别慢,让我放弃了这种做法。
@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;
}
@PostMapping("/lalala")
public void shutdownContex() {
System.out.println("123123123");
}
}
框架在接收请求的时候都会走上下文,只要关闭所有的上下文即可关闭进程,同样也实现了优雅的关闭,测试结果一切都正常,和方式1 的预想结果都一样。