-关于2.6.3release版本优雅停机问题,之前我在社区也发提出的issue中于开发交流过,发现依然存在问题。
1. 框架的停机hook和spring的停机hook同时触发,导致服务的实现类中无法获取业务bean,导致服务无法正确完成。(因为spring 
context先于框架close了)
场景一:Springboot+innerTomcat
@SpringBootApplication
@ComponetScan
@ImportResource({"classpath:/META-INF/spring/dubbo*.xml"})
public class GatewayApplication {
        public static void main(String[] args) {
                SpringApplication.run(GatewayApplication.class, args);
                System.in.read();
                //模拟停机
                System.exit(0);
        }
}
场景二:
public static void main(String[] args) {
        ClassPathXmlApplicationContext ctx = new 
ClassPathXmlApplicationContext(classpath:/META-INF/spring/dubbo*.xml);
        ctx.registerShutdownHook();
        ctx.start();
}

2. 
我们分析了下2.6.3停机代码,针对spring容器需要关闭dubbo默认hook,通过spring的停机hook触发close事件listener来停机。初始化DubboApplicationListener目前只针对Main方法和Spring+web.xml方式。个人觉得DubboApplicationListener思路是对的,但是需要针对不同spring使用场景,不能总体覆盖。个人觉得DubboApplicationContextInitializer设计就有点别扭。

3. 建议:针对Spring容器优雅停机,我们建议将spring 
close事件监听逻辑移到ApplicationConfig中,并在ApplicationConfig中注销默认停机hook,注册spring 
停机hook。这样做的好处就是,如果框架是基于spring容器,可以一刀切的方式实现hook的管理,完全依赖spirng管理停机,使用者仅需要关系spring生命周期。核心修改如下:
ApplicationConfig implments ApplicationContextWare, 
ApplicationListener<ContextClosedEvent>{
    public void onApplicationEvent(ContextClosedEvent event){
        DubboShutdownHook.getDubboShutDownHook().destroyAll();
    }

    public void setApplicationContext(ApplicationContext ctx){
        //注销dubbohook,将removeShutdownHook从DubboBootstrap中迁移到DubboShutdownHook中
        DubboShutdownHook.removeShutdownHook();
       //注册spring hook
         ctx.registerShutdownHook();
    }
}

4.我们应用在实际使用过程中碰到很多停机问题,我们也针对性的对框架优雅停机尝试研究和优化,个人对dubbo代码理解有限,恳请指正。

[ Full content available at: 
https://github.com/apache/incubator-dubbo/issues/2525 ]
This message was relayed via gitbox.apache.org for [email protected]

Reply via email to