什么叫优雅停机?
向应用进程发出停止指令之后,能保证正在执行的业务操作不受影响,直到操作运行完毕之后再停止服务。应用程序接收到停止指令之后,会进行如下操作:
1、停止接收新的访问请求
2、正在处理的请求,等待请求处理完毕;对于内部正在执行的其他任务,比如定时任务、mq 消费等等,也要等当前正在执行的任务执行完毕,并且不再启动新的任务
3、当应用准备关闭的时候,按需向外发出信号,告知其他应用服务准备接手,以保证服务高可用
方式一
我们都知道,想要在Linux中终止一个进程有两种方式,如果是前台进程可以使用Ctrl+C键进行终止;如果是后台进程,那么需要使用kill命令来终止。(其实Ctrl+C也是kill命令)
常用的信号如下:
HUP 1 终端断线
INT 2 中断(同 Ctrl + C)
QUIT 3 退出(同 Ctrl + \)
TERM 15 终止
KILL 9 强制终止
CONT 18 继续(与STOP相反, fg/bg命令)
STOP 19 暂停(同 Ctrl + Z)
kill -9 和 kill -15 的区别?
kill命令默认的信号就是15,首先来说一下这个默认的kill -15信号。
当使用kill -15时,系统会发送一个终止的信号给对应的程序。当程序接收到该信号后,具体要如何处理是自己可以决定的。这时候,应用程序可以选择:
1、立即停止程序
2、释放响应资源后停止程序
3、忽略该信号,继续执行程序
因为kill -15信号只是通知对应的进程要进行”安全、干净的退出”,程序接到信号之后,退出前一般会进行一些”准备工作”,如资源释放、临时文件清理等等,如果准备工作做完了,再进行程序的终止。
但是,如果在”准备工作”进行过程中,遇到阻塞或者其他问题导致无法成功,那么应用程序可以选择忽略该终止信号。
和 kill -15相比,kill -9就相对强硬一点,系统会发出SIGKILL信号,他要求接收到该信号的程序应该立即结束运行,不能被阻塞或者忽略,但这通常会带来一些副作用,数据丢失或者终端无法恢复到正常状态等。
方式二
这里没有使用Actuator方法来进行关闭,Actuator太复杂。
/**
* 服务关闭
*/
@RequestMapping("/shutdown")
public void shutdown() {
try {
// 这里最好加一个密码判断,把密码写入yml里面
System.exit(0);
} catch (Exception e) {
LOGGER.error("shutdown:{}", e);
}
}
方式三
通过 ConfigurableApplicationContext
@Autowired
private ConfigurableApplicationContext applicationContext;
/**
* 服务关闭
*/
@RequestMapping("/shutdown")
public void shutdown() {
try {
// 这里最好加一个密码判断,把密码写入yml里面
applicationContext.close();
} catch (Exception e) {
LOGGER.error("shutdown:{}", e);
}
}
当前共有 3 条评论
感谢大佬的提议,已经更新上去了。
这是我的笔记里面记的。刚刚百度了一下,springboot新版本也增加了新的属性支持,参考:https://docs.spring.io/spring-boot/docs/2.7.10/reference/htmlsingle/#web.graceful-shutdown
(1)AnnotationConfigServletWebServerApplicationContext.close方法也可以; (2)kill -15 也可以,会触发类似@PreDestory之类的销毁事件;
感谢大佬的提议,已经更新上去了。
(1)AnnotationConfigServletWebServerApplicationContext.close方法也可以; (2)kill -15 也可以,会触发类似@PreDestory之类的销毁事件;