什么是优雅停机?
在web服务(Http协议)上线的时候,会通过kill命令杀死进程,这个时候在已经accept的请求还在线程池里面,我们要保证这部分请求正常处理并且返回数据之后再停机.
dubbo服务(Tcp协议)也是同样的道理.
优雅停机包括:线程池的优雅关闭,数据库连接池的关闭,数据源的关闭,kafka连接的关闭....
没有优雅停机的现象
1.客户端拿不到数据
2.数据源报已经关闭
Failed to obtain JDBC Connection; nested exception is com.alibaba.druid.pool.DataSourceClosedException: dataSource already closed
JVM的钩子
Runtime.addShutDownHook
我们的服务是基于SpringBoot+Dubbo+业务线程池来实现的.
dubbo框架提供了destroyAll来实现自身的优雅关闭,Spring容器对Bean的优雅关闭是通过@PreDestory来实现的,我们自己创建的ThreadPool也可以通过Runtime.addShutDownHook来实现优雅关闭。
但是这里有一个关键的问题是这三者是并行执行的,dubbo在进入优雅停机状态中的时候已经停止接收新的业务请求,然而已经接收的请求需要继续处理,但是有可能此时Spring的优雅关闭已经执行完成,导致在处理请求的时候出现异常(比如DataSource已经close了)。
那如何保证Spring容器等待dubbo优雅关闭执行完成以后再执行bean的@PreDestory方法(销毁bean)呢?下面有请Spring的ApplicationListener!