【优雅停机】优雅停机

什么是优雅停机?

​ 应用停止时,应用内部必然存在一部分正在处理的业务,如果此使用kill -9 pid的方式暴力停止了服务,会导致正在执行的交易强制中断,影响业务的完整性。为了解决这种问题,优雅停机便被提出来了,简单点说就是让应用处理完正在处理的交易之后,再停下来。

如何实现优雅停机

​ 对于Java应用来说,可以通过java.lang.Runtime.getRuntime().addShutdownHook(Thread hook) 来实现。在应用启动时注册钩子线程,当使用kill pid来停止服务时,会调用hook中的代码来进行服务停止,这时便可以通过自己的逻辑来实现服务的的优雅停机。

钩子(Hook)方法内部逻辑顺序

  • 第一步,要让应用处理完正在处理的任务,那么必须先停止接收外部请求,否则,请求源源不断的进行,应用是永远也处理不完的。

需要注意的问题:

  • 对于接入,可以通过全局变量的方式,控制接入组件不再接入请求。如果通过直接close connection的方式来进行,前边已经接入处理的请求会被强制中断,导致收不到回执。
  • 对于请求接入,需要设置超时时间,否则会存在丢失一笔报文的请求。超时时间的目的是为了循环能在指定时间内再进行一次,否则全局变量是修改了,但是一直没有收到请求,当已经执行了第二步,这时进来的请求,将会处理失败。例如Java Socket通讯接入可通过以下方式。
ServerSocket server = new ServerSocket(port);
server.setSoTimeout(10*1000);
while(true){
Socket client = server.accept();
}
  • 第二步,当切断了进来的请求后,这时就要判断业务是不是全部处理完成了。这里提供一种参考的思路,获取应用中的所有线程池,并调用线程池的shutdown()方法,阻止新的任务提交。之后启动while循环,直到调用所有的线程池的isTerminated()方法返回的都是true,则认为请求已经处理完成。

  • 这时停止服务,便可以保证不会存在请求丢失的情况。

原文地址:https://www.cnblogs.com/itaot/p/12088563.html