Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Problems of graceful shutdown in 2.6.3 and some recommendations #2525

Closed
rangtao opened this issue Sep 19, 2018 · 11 comments
Closed

Problems of graceful shutdown in 2.6.3 and some recommendations #2525

rangtao opened this issue Sep 19, 2018 · 11 comments
Assignees

Comments

@rangtao
Copy link

rangtao commented Sep 19, 2018

-关于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{
    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代码理解有限,恳请指正。

@rangtao rangtao changed the title Problems of graceful shutdown of dubbo in 2.6.3 and some recommendations Problems of graceful shutdown in 2.6.3 and some recommendations Sep 19, 2018
@zonghaishang
Copy link
Member

3.建议:针对Spring容器优雅停机,我们建议将spring close事件监听逻辑移到ApplicationConfig中,并在ApplicationConfig中注销默认停机hook,注册spring 停机hook。这样做的好处就是,如果框架是基于spring容器,可以一刀切的方式实现hook的管理,完全依赖spirng管理停机,使用者仅需要关系spring生命周期。

强绑定了spring容器,不可取,这在dubbo-config-api模块不依赖spring。

@zonghaishang
Copy link
Member

duplicate of #2435

@zonghaishang
Copy link
Member

I have already commented: #2435

@zonghaishang
Copy link
Member

Thanks for providing valuable suggestions. Do you have any actual scenario problems with 2.6.3?

@rangtao
Copy link
Author

rangtao commented Sep 20, 2018

如上描述场景一(Springboot+innerTomcat),spring先于停机流程结束,影响在途调用。

@rangtao
Copy link
Author

rangtao commented Sep 20, 2018

--sry,没理解您的答复,看注释的意思是等待注册中心通知延迟。

关于第三个问题,在2.6.1中ProtocolConfig类中,destroyAll方法包含如下sleep代码。2.6.2中将此部分sleep代码删除了。
see HeaderExchangeServer#isRunning:

private boolean isRunning() {
    Collection<Channel> channels = getChannels();
    for (Channel channel : channels) {
        if (DefaultFuture.hasFuture(channel)) {
         /**
         *  If there are any client connections,
         *  our server should be running.
         */
         if (channel.isConnected()) {
            return true;
        }
    }

If there is a client connection, it will automatically wait, there was a bug before, so will invoke sleep

@zonghaishang
Copy link
Member

针对场景1能提供复现的demo吗?你自己建立一个github工程,把demo代码放进去。
针对场景3,原来因为关闭server的时候没有正确判断是否还有client持有连接,所以要sleep, 现在这个Bug解决了,不需要主动sleep了

@zonghaishang
Copy link
Member

如上描述场景一(Springboot+innerTomcat),spring先于停机流程结束,影响在途调用。 这个场景使用哪个版本的dubbo?

@beiwei30 beiwei30 self-assigned this Oct 31, 2018
@beiwei30
Copy link
Member

I will look into this further in this week.

@beiwei30
Copy link
Member

beiwei30 commented Nov 1, 2018

@rangtao I made a quick prototype based on @ralf0131's work. Would you mind take a look and give me your feedback?

pls. check this: #2725

@beiwei30
Copy link
Member

beiwei30 commented Nov 5, 2018

enhanced with pull requests: #2734, #2725

@beiwei30 beiwei30 closed this as completed Nov 5, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants