简介
Dubbo 是通过 JDK 的 ShutdownHook 来完成优雅停机的,所以如果用户使用 kill -9 PID 等强制关闭指令,是不会执行优雅停机的,只有通过 kill PID 时,才会执行
原理
服务提供方
- 停止时,先标记为不接收新请求,新请求过来时直接报错,让客户端重试其它机器。
- 然后,检测线程池中的线程是否正在运行,如果有,等待所有线程执行完成,除非超时,则强制关闭。
服务消费方
- 停止时,不再发起新的调用请求,所有新的调用在客户端即报错。
- 然后,检测有没有请求的响应还没有返回,等待响应返回,除非超时,则强制关闭。
设置方式
设置优雅停机超时时间,缺省超时时间是 10 秒,如果超时则强制关闭。
# dubbo.properties
dubbo.service.shutdown.wait=15000
如果 ShutdownHook 不能生效,可以自行调用:
DubboShutdownHook.destroyAll();
Spring 容器
由于现在大多数开发者选择使用 Spring 构建 Dubbo 应用,Spring 框架本身也依赖于 shutdown hook 执行优雅停机,并且与 Dubbo 的优雅停机会并发执行,而 Dubbo 的一些 Bean 受 Spring 托管,当 Spring 容器优先关闭时,会导致 Dubbo 的优雅停机流程无法获取相关的 Bean 而报错,从而优雅停机失效。
- Dubbo 2.6.3 中新增了ShutdownHookListener类
Spring 先发布ContextClosedEvent事件,调用关闭 Dubbo 应用的钩子,然后再关闭自身的 Spring 应用。从而解决了上述因 Spring 钩子早于 Dubbo 钩子执行导致 Dubbo 优雅停机失效的问题
但是原有的JVM DubboShutdownHook还存在 - 在 dubbo 2.7.x 版本中,通过SpringExtensionFactory类移除了JVM DubboShutdownHook
网友评论