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

关于Dubbo2.7.7和SpringBoot2.1.1优雅停机的问题 #8892

Closed
2 tasks done
yuxiao97 opened this issue Sep 23, 2021 · 4 comments
Closed
2 tasks done

关于Dubbo2.7.7和SpringBoot2.1.1优雅停机的问题 #8892

yuxiao97 opened this issue Sep 23, 2021 · 4 comments

Comments

@yuxiao97
Copy link

yuxiao97 commented Sep 23, 2021

  • I have searched the issues of this repository and believe that this is not a duplicate.
  • I have checked the FAQ of this repository and believe that this is not a duplicate.

Environment

  • Dubbo version: 2.7.7
  • SpringBoot version: 2.1.1.RELEASE
  • Operating System version: Linux
  • Java version: 1.8

Steps to reproduce this issue

发现Dubbo的优雅停机和Spring的优雅停机并没有先后顺序,都是注册到Runtime的shutdownHook中的,这样Dubbo还能真正的优雅停机嘛?如何做到真正的优雅停机?
Dubbo注册关闭勾子的源码如下,位于DubboBootstrap中

private DubboBootstrap() {
        configManager = ApplicationModel.getConfigManager();
        environment = ApplicationModel.getEnvironment();

        DubboShutdownHook.getDubboShutdownHook().register();
        ShutdownHookCallbacks.INSTANCE.addCallback(new ShutdownHookCallback() {
            @Override
            public void callback() throws Throwable {
                DubboBootstrap.this.destroy();
            }
        });
    }

public class DubboShutdownHook extends Thread {
    @Override
    public void run() {
        if (logger.isInfoEnabled()) {
            logger.info("Run shutdown hook now.");
        }

        callback();
        doDestroy();
    }

    /**
     * Register the ShutdownHook
     */
    public void register() {
        if (registered.compareAndSet(false, true)) {
            DubboShutdownHook dubboShutdownHook = getDubboShutdownHook();
            Runtime.getRuntime().addShutdownHook(dubboShutdownHook);
            dispatch(new DubboShutdownHookRegisteredEvent(dubboShutdownHook));
        }
    }
}

从源码可见,Dubbo在注册关闭勾子时传递了DubboShutdownHook,其run内部先执行了callback,也就是说会执行DubboBootstrap.this.destroy(),另外在DubboBootstrapApplicationListener实现了Spring的ApplicationListener,其最终逻辑也会执行到DubboBootstrap.destroy(),先看下destroy的源码:

    public void destroy() {
        if (destroyLock.tryLock()) {
            try {
                DubboShutdownHook.destroyAll();

                if (started.compareAndSet(true, false)
                        && destroyed.compareAndSet(false, true)) {

                    unregisterServiceInstance();
                    unexportMetadataService();
                    unexportServices();
                    unreferServices();

                    destroyRegistries();
                    DubboShutdownHook.destroyProtocols();
                    destroyServiceDiscoveries();

                    clear();
                    shutdown();
                    release();
                }
            } finally {
                destroyLock.unlock();
            }
        }
    }

如果先执行到destroy的是Dubbo自主注册的关闭勾子触发的,在关闭过程中,通过Spring关闭事件的也执行到这里,在tryLock时会直接返回,那么Spring会销毁自己的容器,此时Dubbo相关组件正在停止中,如果该过程中还有需要调用Spring相关Bean的过程,可能会出现找不到Bean的情况,这样也就无法达到真正意义上的优雅关闭,不知道这样的理解是否正确?如果只通过Spring的关闭事件进行关闭,这样一定可以保证Dubbo组件的销毁先于Spring,避免不会出现Dubbo找不到Spring相关依赖的问题。

@yuxiao97 yuxiao97 reopened this Sep 26, 2021
@haoyann
Copy link
Contributor

haoyann commented Sep 27, 2021

可以看看 #7317,有解决这个问题吗。

@yuxiao97
Copy link
Author

可以看看 #7317,有解决这个问题吗。

是同一类问题,请问在哪个发布版本解决的?我这边好查看下。

@haoyann
Copy link
Contributor

haoyann commented Sep 27, 2021

可以试一下 2.7.14 版本。

@CrazyHZM
Copy link
Member

No feedback for a long time, please close the issue temporarily. If there is still a problem, you can reopen it.

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