From b48b7924fb087ac648d05b4e35b87f00dee0aada Mon Sep 17 00:00:00 2001 From: Gong Dewei Date: Thu, 29 Jul 2021 15:15:04 +0800 Subject: [PATCH] support disable shutdown hook (#8369) --- .../org/apache/dubbo/config/ConfigKeys.java | 10 +++- .../dubbo/config/DubboShutdownHook.java | 12 ++++- .../dubbo/config/spring/ShutdownHookTest.java | 52 +++++++++++++++++++ 3 files changed, 72 insertions(+), 2 deletions(-) create mode 100644 dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/ShutdownHookTest.java diff --git a/dubbo-common/src/main/java/org/apache/dubbo/config/ConfigKeys.java b/dubbo-common/src/main/java/org/apache/dubbo/config/ConfigKeys.java index d1b200d36f6..e7089b4c9f7 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/config/ConfigKeys.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/config/ConfigKeys.java @@ -48,5 +48,13 @@ public interface ConfigKeys { */ String DUBBO_CONFIG_IGNORE_DUPLICATED_INTERFACE = "dubbo.config.ignore-duplicated-interface"; - + /** + * Disable dubbo shutdown hook, Default value is false. + * When disable the shutdown hook, you may need to do : + * 1. offline all services by qos manually before shutdown dubbo application + * 2. no DubboBootstrapStopedEvent will be sent + * 3. all ShutdownHookCallback will not be called + * 4. dubbo application will not be destroyed when spring context is closed + */ + String DUBBO_LIFECYCLE_DISABLE_SHUTDOWN_HOOK = "dubbo.lifecycle.disable-shutdown-hook"; } diff --git a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/DubboShutdownHook.java b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/DubboShutdownHook.java index 792ffa01b01..6380a2437f6 100644 --- a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/DubboShutdownHook.java +++ b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/DubboShutdownHook.java @@ -19,6 +19,7 @@ import org.apache.dubbo.common.lang.ShutdownHookCallbacks; import org.apache.dubbo.common.logger.Logger; import org.apache.dubbo.common.logger.LoggerFactory; +import org.apache.dubbo.rpc.model.ApplicationModel; import java.util.concurrent.atomic.AtomicBoolean; @@ -44,7 +45,7 @@ public class DubboShutdownHook extends Thread { /** * Has it already been destroyed or not? */ - private static final AtomicBoolean destroyed = new AtomicBoolean(false); + private final AtomicBoolean destroyed = new AtomicBoolean(false); private DubboShutdownHook(String name) { super(name); @@ -56,6 +57,15 @@ public static DubboShutdownHook getDubboShutdownHook() { @Override public void run() { + String disableShutdownHookValue = (String) ApplicationModel.getEnvironment().getConfiguration() + .getProperty(ConfigKeys.DUBBO_LIFECYCLE_DISABLE_SHUTDOWN_HOOK, "false"); + if (Boolean.parseBoolean(disableShutdownHookValue)) { + if (logger.isWarnEnabled()) { + logger.warn("Shutdown hook is disabled, please shutdown dubbo services by qos manually"); + } + return; + } + if (destroyed.compareAndSet(false, true)) { if (logger.isInfoEnabled()) { logger.info("Run shutdown hook now."); diff --git a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/ShutdownHookTest.java b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/ShutdownHookTest.java new file mode 100644 index 00000000000..a0b1a74ef65 --- /dev/null +++ b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/ShutdownHookTest.java @@ -0,0 +1,52 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.dubbo.config.spring; + +import org.apache.dubbo.config.ConfigKeys; +import org.apache.dubbo.config.bootstrap.DubboBootstrap; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.springframework.context.support.ClassPathXmlApplicationContext; + +public class ShutdownHookTest { + + @Test + public void testDisableShutdownHook(){ + SysProps.setProperty(ConfigKeys.DUBBO_LIFECYCLE_DISABLE_SHUTDOWN_HOOK, "true"); + + try { + ClassPathXmlApplicationContext providerContext; + String resourcePath = "org/apache/dubbo/config/spring"; + providerContext = new ClassPathXmlApplicationContext( + resourcePath + "/demo-provider.xml", + resourcePath + "/demo-provider-properties.xml"); + providerContext.start(); + + Assertions.assertEquals(true, DubboBootstrap.getInstance().isStarted()); + Assertions.assertEquals(false, DubboBootstrap.getInstance().isShutdown()); + + // close spring context + providerContext.close(); + + // expect dubbo bootstrap will not be destroyed after closing spring context + Assertions.assertEquals(true, DubboBootstrap.getInstance().isStarted()); + Assertions.assertEquals(false, DubboBootstrap.getInstance().isShutdown()); + } finally { + SysProps.clear(); + } + } +}