You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@dubbo.apache.org by al...@apache.org on 2024/10/02 01:53:06 UTC

(dubbo) branch 3.3 updated: feat(actuator):Adding Support for Spring Boot Actuator (#14596)

This is an automated email from the ASF dual-hosted git repository.

albumenj pushed a commit to branch 3.3
in repository https://gitbox.apache.org/repos/asf/dubbo.git


The following commit(s) were added to refs/heads/3.3 by this push:
     new 6982695af2 feat(actuator):Adding Support for Spring Boot Actuator (#14596)
6982695af2 is described below

commit 6982695af2b25553562806877f7c08eb381401fb
Author: JinQian <62...@users.noreply.github.com>
AuthorDate: Wed Oct 2 09:53:00 2024 +0800

    feat(actuator):Adding Support for Spring Boot Actuator (#14596)
    
    * feat(dubbo-actuator):add actuator
    
    * fix:Illegal logger method invocations
    
    * fix:add automatically generate properties,simplify the invoke process,fixed an error where Class name duplicate DubboEndpoint in dubbo-spring-boot-compatible
    
    * fix:Actuator offline and gracefulshutdown operations are disabled by default
    
    * fix:Only enable live, ready and startup by default
    
    * fix:Remove development comments
    
    * fix:Remove automatically generate properties feature
    
    * fix:Change the configuration format
    
    * fix:Set endpoint enablement to be opt-in rather than opt-out, modify README.md
---
 .../apache/dubbo/qos/QosScopeModelInitializer.java |   6 +-
 .../dubbo/qos/command/ActuatorCommandExecutor.java |  63 +++++++++++
 .../apache/dubbo/qos/command/ActuatorExecutor.java |  27 +----
 .../dubbo-spring-boot-actuator/README.md           | 119 ++++++++++++++++++++-
 .../dubbo-spring-boot-actuator/pom.xml             |   7 ++
 .../DubboEndpointAnnotationAutoConfiguration.java  |   6 +-
 ...etadataEndpoint.java => DubboQosEndpoints.java} |  28 ++++-
 .../META-INF/dubbo-endpoints-default.properties    |  19 ++--
 ...bboEndpointAnnotationAutoConfigurationTest.java |   6 +-
 .../boot/actuate/endpoint/DubboEndpointTest.java   |  10 +-
 .../dubbo-spring-boot-compatible/actuator/pom.xml  |   7 ++
 .../DubboExtensionEndpointAutoConfiguration.java   |  38 +++++++
 .../configuration/DubboActuatorProperties.java}    |  42 ++++----
 ...rk.boot.autoconfigure.AutoConfiguration.imports |   1 +
 14 files changed, 310 insertions(+), 69 deletions(-)

diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/QosScopeModelInitializer.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/QosScopeModelInitializer.java
index 58125556ba..cf2679c36a 100644
--- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/QosScopeModelInitializer.java
+++ b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/QosScopeModelInitializer.java
@@ -17,6 +17,7 @@
 package org.apache.dubbo.qos;
 
 import org.apache.dubbo.common.beans.factory.ScopeBeanFactory;
+import org.apache.dubbo.qos.command.ActuatorCommandExecutor;
 import org.apache.dubbo.qos.command.util.SerializeCheckUtils;
 import org.apache.dubbo.qos.server.Server;
 import org.apache.dubbo.rpc.model.ApplicationModel;
@@ -33,7 +34,10 @@ public class QosScopeModelInitializer implements ScopeModelInitializer {
     }
 
     @Override
-    public void initializeApplicationModel(ApplicationModel applicationModel) {}
+    public void initializeApplicationModel(ApplicationModel applicationModel) {
+        ScopeBeanFactory beanFactory = applicationModel.getBeanFactory();
+        beanFactory.registerBean(ActuatorCommandExecutor.class);
+    }
 
     @Override
     public void initializeModuleModel(ModuleModel moduleModel) {}
diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/ActuatorCommandExecutor.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/ActuatorCommandExecutor.java
new file mode 100644
index 0000000000..7073eea124
--- /dev/null
+++ b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/ActuatorCommandExecutor.java
@@ -0,0 +1,63 @@
+/*
+ * 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.qos.command;
+
+import org.apache.dubbo.common.logger.Logger;
+import org.apache.dubbo.common.logger.LoggerFactory;
+import org.apache.dubbo.qos.api.BaseCommand;
+import org.apache.dubbo.qos.api.CommandContext;
+import org.apache.dubbo.rpc.model.ApplicationModel;
+
+import java.util.Arrays;
+
+public class ActuatorCommandExecutor implements ActuatorExecutor {
+    private static final Logger logger = LoggerFactory.getLogger(ActuatorCommandExecutor.class);
+    private final ApplicationModel applicationModel;
+
+    public ActuatorCommandExecutor(ApplicationModel applicationModel) {
+        this.applicationModel = applicationModel;
+    }
+
+    @Override
+    public String execute(String commandName, String[] parameters) {
+        CommandContext commandContext;
+
+        if (parameters == null || parameters.length == 0) {
+            commandContext = CommandContextFactory.newInstance(commandName);
+            commandContext.setHttp(true);
+        } else {
+            commandContext = CommandContextFactory.newInstance(commandName, parameters, true);
+        }
+
+        logger.info("[Dubbo Actuator QoS] Command Process start. Command: " + commandContext.getCommandName()
+                + ", Args: " + Arrays.toString(commandContext.getArgs()));
+
+        BaseCommand command;
+        try {
+            command = applicationModel
+                    .getExtensionLoader(BaseCommand.class)
+                    .getExtension(commandContext.getCommandName());
+            return command.execute(commandContext, commandContext.getArgs());
+        } catch (Throwable t) {
+            logger.info(
+                    "[Dubbo Actuator QoS] Command Process Failed. Command: " + commandContext.getCommandName()
+                            + ", Args: " + Arrays.toString(commandContext.getArgs()),
+                    t);
+            throw t;
+        }
+    }
+}
diff --git a/dubbo-spring-boot/dubbo-spring-boot-actuator/src/main/java/org/apache/dubbo/spring/boot/actuate/endpoint/DubboMetadataEndpoint.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/ActuatorExecutor.java
similarity index 53%
copy from dubbo-spring-boot/dubbo-spring-boot-actuator/src/main/java/org/apache/dubbo/spring/boot/actuate/endpoint/DubboMetadataEndpoint.java
copy to dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/ActuatorExecutor.java
index 3eb816d17a..f63abf07e8 100644
--- a/dubbo-spring-boot/dubbo-spring-boot-actuator/src/main/java/org/apache/dubbo/spring/boot/actuate/endpoint/DubboMetadataEndpoint.java
+++ b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/ActuatorExecutor.java
@@ -14,30 +14,9 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.dubbo.spring.boot.actuate.endpoint;
+package org.apache.dubbo.qos.command;
 
-import org.apache.dubbo.spring.boot.actuate.endpoint.metadata.DubboMetadata;
+public interface ActuatorExecutor {
 
-import java.util.Map;
-
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
-import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;
-
-/**
- * Actuator {@link Endpoint} to expose Dubbo Meta Data
- *
- * @see Endpoint
- * @since 2.7.0
- */
-@Endpoint(id = "dubbo")
-public class DubboMetadataEndpoint {
-
-    @Autowired
-    private DubboMetadata dubboMetadata;
-
-    @ReadOperation
-    public Map<String, Object> invoke() {
-        return dubboMetadata.invoke();
-    }
+    String execute(String command, String[] args);
 }
diff --git a/dubbo-spring-boot/dubbo-spring-boot-actuator/README.md b/dubbo-spring-boot/dubbo-spring-boot-actuator/README.md
index b0f22c027c..a753c9ef36 100644
--- a/dubbo-spring-boot/dubbo-spring-boot-actuator/README.md
+++ b/dubbo-spring-boot/dubbo-spring-boot-actuator/README.md
@@ -153,7 +153,40 @@ Actuator endpoint `dubbo` supports Actuator Endpoints :
 | `dubboservices` | `false`     | `/actuator/dubbo/services`            | `GET`       | Exposes all Dubbo's `ServiceBean`   | `application/json` |
 | `dubboreferences` | `false` | `/actuator/dubbo/references` | `GET`       | Exposes all Dubbo's `ReferenceBean` | `application/json` |
 | `dubboconfigs` | `true` | `/actuator/dubbo/configs`    | `GET`       | Exposes all Dubbo's `*Config`       | `application/json` |
-| `dubboshutdown` | `false` | `/actuator/dubbo/shutdown`   | `POST`      | Shutdown Dubbo services             | `application/json` |
+| `dubboshutdown` | `false` | `/actuator/dubbo/shutdown`   | `GET`   | Shutdown Dubbo services             | `application/json` |
+| `help` | `false` | `/actuator/dubbo/help` | `GET` | List all commands |  |
+| `ready` | `true` | `/actuator/dubbo/ready` | `GET` | Check whether the current process/service is ready for external service | `application/json` |
+| `live` | `true` | `/actuator/dubbo/live` | `GET` | Check whether the current process/service is alive | `application/json` |
+| `ls` | `false` | `/actuator/dubbo/ls` | `GET` | List consumers and providers | `application/json` |
+| `startup` | `true` | `/actuator/dubbo/startup` | `GET` | Check if the current framework has been started | `application/json` |
+| `ps` | `false` | `/actuator/dubbo/ps` | `GET` | View information about the current process, including `listenable` ports | `application/json` |
+| `version` | `false` | `/actuator/dubbo/version` | `GET` | Display the version number of the currently running `Dubbo` | `application/json` |
+| `getaddress` | `false` | `/actuator/dubbo/getaddress?args=xxx.*` | `GET` | View the list of valid `IP` addresses for a service | `application/json` |
+| `getconfig` | `false` | `/actuator/dubbo/getconfig` | `GET` | View the valid `configuration` of the current application | `application/json` |
+| `metrics` | `false` | `/actuator/dubbo/metrics` | `GET` | View `metrics`(Need to enable metrics statistics) | `application/json` |
+| `metrics_default` | `false` | `/actuator/dubbo/metrics_default` | `GET` | View the default `metrics`(Need to enable metrics statistics) | `application/json` |
+| `publishmetadata` | `false` | `/actuator/dubbo/publishmetadata` or `/actuator/dubbo/publishmetadata?args=10` | `GET` | Publishes or updates the current application `Metadata` (Delay can be set) | `application/json` |
+| `online` | `false` | `/actuator/dubbo/online` or `/actuator/dubbo/online?args=xxx.*` | `GET` | Register one or more services to the registry (including application and interface addresses) | `application/json` |
+| `onlineapp` | `false` | `/actuator/dubbo/onlineApp` or `/actuator/dubbo/onlineApp?args=xxx.xxx.*` | `GET` | Register one or more services to the registry (only application addresses) | `application/json` |
+| `onlineinterface` | `false` | `/actuator/dubbo/onlineInterface` or `/actuator/dubbo/onlineInterface?args=xxx.*` | `GET` | Register one or more services to the registry (only interface addresses) | `application/json` |
+| `offline` | `false` | `/actuator/dubbo/offline` or `/actuator/dubbo/offline?args=xxx.*` | `GET` | Unregister one or more services from the registry (including application and interface addresses) | `application/json` |
+| `offlineapp` | `false` | `/actuator/dubbo/offlineApp` or `/actuator/dubbo/offlineApp?args=xxx.*` | `GET` | Unregister one or more services from the registry (only application addresses) | `application/json` |
+| `offlineinterface` | `false` | `/actuator/dubbo/offlineInterface` or `/actuator/dubbo/offlineInterface?args=xxx.*` | `GET` | Unregister one or more services from the registry (only interface addresses) | `application/json` |
+| `loggerinfo` | `false` | `/actuator/dubbo/loggerInfo` | `GET` | Query log configuration | `application/json` |
+| `switchlogger` | `false` | `/actuator/dubbo/switchLogger?args={loggerAdapterName}` | `GET` | Modify the log output framework,`loggerAdapterName`: `slf4j`, `jcl`, `log4j`, `jdk`, `log4j2` | `application/json` |
+| `switchloglevel` | `false` | `/actuator/dubbo/switchLogLevel?args={level}` | `GET` | Modify log level,level: `ALL`, `TRACE`, `DEBUG`, `INFO`, `WARN`, `ERROR`, `OFF` | `application/json` |
+| `disabledetailprofiler` | `false` | `/actuator/dubbo/disableDetailProfiler` | `GET` | Turn off `detail profiler` mode, it will not affect `simple profiler` | `application/json` |
+| `enabledetailprofiler` | `false` | `/actuator/dubbo/enableDetailProfiler` | `GET` | Enable the `detail profiler` mode, which is disabled by default, you need to enable the `simple profiler` mode to actually enable it | `application/json` |
+| `disablesimpleprofiler` | `false` | `/actuator/dubbo/disableSimpleProfiler` | `GET` | Turn off the `simple profiler` mode, and the `detail profiler` will not be enabled after it is turned off | `application/json` |
+| `enablesimpleprofiler` | `false` | `/actuator/dubbo/enableSimpleProfiler` | `GET` | Enable `simple profiler` mode, enabled by default | `application/json` |
+| `setprofilerwarnpercent` | `false` | `/actuator/dubbo/setProfilerWarnPercent?args={percent}` | `GET` | Control `serialization` alarm frequency (only for classes in the warning list) | `application/json` |
+| `serializecheckstatus` | `false` | `/actuator/dubbo/dubboserializecheckstatus` | `GET` | View the current configuration information | `application/json` |
+| `serializewarnedclasses` | `false` | `/actuator/dubbo/dubboserializewarnedclasses` | `GET` | View the real-time alarm list | `application/json` |
+| `disableroutersnapshot` | `false` | `/actuator/dubbo/disableRouterSnapshot` or `/actuator/dubbo/disableRouterSnapshot?args=xxx.*` | `GET` | Disable routing result collection mode | `application/json` |
+| `enableroutersnapshot` | `false` | `/actuator/dubbo/enableRouterSnapshot` or `/actuator/dubbo/enableRouterSnapshot?args=xxx.*` | `GET` | Enable routing result collection mode | `application/json` |
+| `getrecentroutersnapshot` | `false` | `/actuator/dubbo/getRecentRouterSnapshot` | `GET` | Obtain the historical routing status (up to 32 results stored) | `application/json` |
+| `getenabledroutersnapshot` | `false` | `/actuator/dubbo/getEnabledRouterSnapshot` | `GET` | Get the services that are currently collecting | `application/json` |
+| `gracefulshutdown` | `false` | `/actuator/dubbo/gracefulShutdown` | `GET` | Unregister all services registered by the current IP instance from the registry | `application/json` |
 
 
 
@@ -429,6 +462,57 @@ The key is the simple name of Dubbo `*Config`  Class , the value is`*Config` Bea
 
 
 
+`/actuator/dubbo/ls `List consumers and providers :
+
+```
+As Provider side:
++-----------------------------------------------------------------------------------+-----------------------------+
+|                       Provider Service Name                                       |             PUB             |
++-----------------------------------------------------------------------------------+-----------------------------+
+|   DubboInternal - dubbo-springboot-demo-provider/org.apache.dubbo.metadata.MetadataService: 1.0.0   |           |
++-----------------------------------------------------------------------------------+-----------------------------+
+|DubboInternal - dubbo-springboot-demo-provider/org.apache.dubbo.metrics.service.MetricsService: 1.0.0|           |
++-----------------------------------------------------------------------------------+-----------------------------+
+|           org.apache.dubbo.springboot.demo.DemoService                            |zookeeper-A(Y)/zookeeper-I(Y)|
++-----------------------------------------------------------------------------------+-----------------------------+
+As Consumer side:
++---------------------+---+
+|Consumer Service Name|NUM|
++---------------------+---+
+
+```
+
+- Services prefixed with `DubboInternal` are built-in services of Dubbo, and are not registered with the registry by default.
+
+- The first part of `zookeeper-A(Y)` in the service publishing status is the corresponding registry name, and the second part is the registration mode (`A` stands for application-level address registration, `I` stands for interface-level address registration), The third part represents whether the corresponding mode has been registered
+
+- The first part of `zookeeper-AF(I-2,A-2)` in the service subscription status is the corresponding registration center name, and the second part is the subscription mode (`AF` stands for dual subscription mode, `FA` stands for only Application-level subscription, `FI` stands for interface-level subscription only), the first half of the third part represents the source of the address mode (`A` stands for application-level address, `I` stands for interface-level address), and the second h [...]
+
+
+
+
+`/actuator/dubbo/switchLogLevel?args={level}` allows switching between permitted log levels, and the parameter cannot be empty, `/actuator/dubbo/switchLogLevel?args=WARN`.
+
+The log configuration modified by `switchLogger`/`switchLogLevel` is not stored persistently and will become invalid after the application is restarted.
+
+
+
+`/actuator/dubbo/disableSimpleProfiler` turn off the `simple profiler` mode, and the `detail profiler` will not be enabled after it is turned off.
+
+The performance sampling function can detect the time consumption of various parts of the Dubbo processing link,where `simple profiler` mode is enabled by default.
+
+
+
+`/actuator/dubbo/enableDetailProfiler` enable the `detail profiler` mode, which is disabled by default, you need to enable the `simple profiler` mode to actually enable it.
+
+Compared with the `simple profiler` mode, the `detail profiler` collects more time-consuming processing of each filter, specific time-consuming protocols, etc. In the `simple profiler` mode, if you find that there is a long time-consuming situation inside the Dubbo framework, you can enable the `detail profiler` mode to better troubleshoot the problem.
+
+
+
+`/actuator/dubbo/gracefulShutdown` unregister all services registered by the current IP instance from the registry. The difference from 'offline' is that this command will also notify all consumers via TCP connection to stop calling this instance. To restore, please execute 'online' to bring all services back online.
+
+
+
 ## Externalized Configuration
 
 
@@ -495,5 +579,38 @@ management.endpoint.dubboconfigs.enabled = true
 management.endpoint.dubboservices.enabled = true
 management.endpoint.dubboreferences.enabled = true
 management.endpoint.dubboproperties.enabled = true
+management.endpoint.dubbo.help.enabled = true
+management.endpoint.dubbo.ready.enabled = true
+management.endpoint.dubbo.ls.enabled = true
+management.endpoint.dubbo.live.enabled = true
+management.endpoint.dubbo.startup.enabled = true
+management.endpoint.dubbo.ps.enabled = true
+management.endpoint.dubbo.version.enabled = true
+management.endpoint.dubbo.getaddress.enabled = true
+management.endpoint.dubbo.getconfig.enabled = true
+management.endpoint.dubbo.metrics.enabled = true
+management.endpoint.dubbo.metrics_default.enabled = true
+management.endpoint.dubbo.publishmetadata.enabled = true
+management.endpoint.dubbo.online.enabled = true
+management.endpoint.dubbo.onlineapp.enabled = true
+management.endpoint.dubbo.onlineinterface.enabled = true
+management.endpoint.dubbo.offline.enabled = true
+management.endpoint.dubbo.offlineapp.enabled = true
+management.endpoint.dubbo.offlineinterface.enabled = true
+management.endpoint.dubbo.loggerinfo.enabled = true
+management.endpoint.dubbo.switchlogger.enabled = true
+management.endpoint.dubbo.switchloglevel.enabled = true
+management.endpoint.dubbo.disabledetailprofiler.enabled = true
+management.endpoint.dubbo.disablesimpleprofiler.enabled = true
+management.endpoint.dubbo.enabledetailprofiler.enabled = true
+management.endpoint.dubbo.enablesimpleprofiler.enabled = true
+management.endpoint.dubbo.setprofilerwarnpercent.enabled = true
+management.endpoint.dubbo.serializecheckstatus.enabled = true
+management.endpoint.dubbo.serializewarnedclasses.enabled = true
+management.endpoint.dubbo.disableroutersnapshot.enabled = true
+management.endpoint.dubbo.enableroutersnapshot.enabled = true
+management.endpoint.dubbo.getrecentroutersnapshot.enabled = true
+management.endpoint.dubbo.getenabledroutersnapshot.enabled = true
+management.endpoint.dubbo.gracefulshutdown.enabled = true
 ```
 
diff --git a/dubbo-spring-boot/dubbo-spring-boot-actuator/pom.xml b/dubbo-spring-boot/dubbo-spring-boot-actuator/pom.xml
index b91b00c525..15d4bf13f9 100644
--- a/dubbo-spring-boot/dubbo-spring-boot-actuator/pom.xml
+++ b/dubbo-spring-boot/dubbo-spring-boot-actuator/pom.xml
@@ -111,6 +111,13 @@
       <optional>true</optional>
     </dependency>
 
+    <dependency>
+      <groupId>org.apache.dubbo</groupId>
+      <artifactId>dubbo-qos</artifactId>
+      <version>${project.version}</version>
+      <optional>true</optional>
+    </dependency>
+
     <!-- Test Dependencies -->
     <dependency>
       <groupId>org.springframework.boot</groupId>
diff --git a/dubbo-spring-boot/dubbo-spring-boot-actuator/src/main/java/org/apache/dubbo/spring/boot/actuate/autoconfigure/DubboEndpointAnnotationAutoConfiguration.java b/dubbo-spring-boot/dubbo-spring-boot-actuator/src/main/java/org/apache/dubbo/spring/boot/actuate/autoconfigure/DubboEndpointAnnotationAutoConfiguration.java
index 93ff379073..e132ace752 100644
--- a/dubbo-spring-boot/dubbo-spring-boot-actuator/src/main/java/org/apache/dubbo/spring/boot/actuate/autoconfigure/DubboEndpointAnnotationAutoConfiguration.java
+++ b/dubbo-spring-boot/dubbo-spring-boot-actuator/src/main/java/org/apache/dubbo/spring/boot/actuate/autoconfigure/DubboEndpointAnnotationAutoConfiguration.java
@@ -17,8 +17,8 @@
 package org.apache.dubbo.spring.boot.actuate.autoconfigure;
 
 import org.apache.dubbo.spring.boot.actuate.endpoint.DubboConfigsMetadataEndpoint;
-import org.apache.dubbo.spring.boot.actuate.endpoint.DubboMetadataEndpoint;
 import org.apache.dubbo.spring.boot.actuate.endpoint.DubboPropertiesMetadataEndpoint;
+import org.apache.dubbo.spring.boot.actuate.endpoint.DubboQosEndpoints;
 import org.apache.dubbo.spring.boot.actuate.endpoint.DubboReferencesMetadataEndpoint;
 import org.apache.dubbo.spring.boot.actuate.endpoint.DubboServicesMetadataEndpoint;
 import org.apache.dubbo.spring.boot.actuate.endpoint.DubboShutdownEndpoint;
@@ -52,8 +52,8 @@ public class DubboEndpointAnnotationAutoConfiguration {
     @ConditionalOnMissingBean
     @ConditionalOnAvailableEndpoint
     @CompatibleConditionalOnEnabledEndpoint
-    public DubboMetadataEndpoint dubboEndpoint() {
-        return new DubboMetadataEndpoint();
+    public DubboQosEndpoints dubboQosEndpoints() {
+        return new DubboQosEndpoints();
     }
 
     @Bean
diff --git a/dubbo-spring-boot/dubbo-spring-boot-actuator/src/main/java/org/apache/dubbo/spring/boot/actuate/endpoint/DubboMetadataEndpoint.java b/dubbo-spring-boot/dubbo-spring-boot-actuator/src/main/java/org/apache/dubbo/spring/boot/actuate/endpoint/DubboQosEndpoints.java
similarity index 58%
copy from dubbo-spring-boot/dubbo-spring-boot-actuator/src/main/java/org/apache/dubbo/spring/boot/actuate/endpoint/DubboMetadataEndpoint.java
copy to dubbo-spring-boot/dubbo-spring-boot-actuator/src/main/java/org/apache/dubbo/spring/boot/actuate/endpoint/DubboQosEndpoints.java
index 3eb816d17a..4abe1989c6 100644
--- a/dubbo-spring-boot/dubbo-spring-boot-actuator/src/main/java/org/apache/dubbo/spring/boot/actuate/endpoint/DubboMetadataEndpoint.java
+++ b/dubbo-spring-boot/dubbo-spring-boot-actuator/src/main/java/org/apache/dubbo/spring/boot/actuate/endpoint/DubboQosEndpoints.java
@@ -16,6 +16,9 @@
  */
 package org.apache.dubbo.spring.boot.actuate.endpoint;
 
+import org.apache.dubbo.qos.command.ActuatorExecutor;
+import org.apache.dubbo.rpc.model.ApplicationModel;
+import org.apache.dubbo.spring.boot.actuate.endpoint.configuration.DubboActuatorProperties;
 import org.apache.dubbo.spring.boot.actuate.endpoint.metadata.DubboMetadata;
 
 import java.util.Map;
@@ -23,21 +26,40 @@ import java.util.Map;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
 import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;
+import org.springframework.boot.actuate.endpoint.annotation.Selector;
+import org.springframework.lang.Nullable;
 
 /**
- * Actuator {@link Endpoint} to expose Dubbo Meta Data
+ * Dubbo Actuator {@link Endpoint}
  *
  * @see Endpoint
- * @since 2.7.0
+ * @since 3.3.0
  */
 @Endpoint(id = "dubbo")
-public class DubboMetadataEndpoint {
+public class DubboQosEndpoints {
+
+    @Autowired
+    private ApplicationModel applicationModel;
 
     @Autowired
     private DubboMetadata dubboMetadata;
 
+    @Autowired
+    private DubboActuatorProperties dubboActuatorProperties;
+
     @ReadOperation
     public Map<String, Object> invoke() {
         return dubboMetadata.invoke();
     }
+
+    @ReadOperation
+    public String handleCommand(@Selector String command, @Nullable String[] args) {
+        if (dubboActuatorProperties.isEnabled(command.toLowerCase())) {
+            ActuatorExecutor actuatorExecutor =
+                    applicationModel.getBeanFactory().getBean(ActuatorExecutor.class);
+            return actuatorExecutor.execute(command, args);
+        } else {
+            return ("Invalid command or not enabled");
+        }
+    }
 }
diff --git a/dubbo-spring-boot/dubbo-spring-boot-actuator/src/main/resources/META-INF/dubbo-endpoints-default.properties b/dubbo-spring-boot/dubbo-spring-boot-actuator/src/main/resources/META-INF/dubbo-endpoints-default.properties
index 2eef0739c0..36078408ea 100644
--- a/dubbo-spring-boot/dubbo-spring-boot-actuator/src/main/resources/META-INF/dubbo-endpoints-default.properties
+++ b/dubbo-spring-boot/dubbo-spring-boot-actuator/src/main/resources/META-INF/dubbo-endpoints-default.properties
@@ -2,20 +2,19 @@
 # those values of properties can be override by higher PropertySource
 # @see DubboEndpointsAutoConfiguration
 
-# Set enabled for Dubbo Endpoints
-management.endpoint.dubbo.enabled = true
-management.endpoint.dubboshutdown.enabled = false
-management.endpoint.dubboconfigs.enabled = true
-management.endpoint.dubboservices.enabled = false
-management.endpoint.dubboreferences.enabled = false
-management.endpoint.dubboproperties.enabled = true
-
 # "management.endpoints.web.base-path" should not be configured in this file
-
 # Re-defines path-mapping of Dubbo Web Endpoints
-
 management.endpoints.web.path-mapping.dubboshutdown = dubbo/shutdown
 management.endpoints.web.path-mapping.dubboconfigs = dubbo/configs
 management.endpoints.web.path-mapping.dubboservices = dubbo/services
 management.endpoints.web.path-mapping.dubboreferences = dubbo/references
 management.endpoints.web.path-mapping.dubboproperties = dubbo/properties
+
+# Set endpoint enablement to be opt-in rather than opt-out
+management.endpoints.enabled-by-default = false
+
+# Set enabled for Dubbo Endpoints
+management.endpoint.dubbo.enabled = true
+management.endpoint.dubbo.ready.enabled = true
+management.endpoint.dubbo.startup.enabled = true
+management.endpoint.dubbo.live.enabled = true
diff --git a/dubbo-spring-boot/dubbo-spring-boot-actuator/src/test/java/org/apache/dubbo/spring/boot/actuate/autoconfigure/DubboEndpointAnnotationAutoConfigurationTest.java b/dubbo-spring-boot/dubbo-spring-boot-actuator/src/test/java/org/apache/dubbo/spring/boot/actuate/autoconfigure/DubboEndpointAnnotationAutoConfigurationTest.java
index 1999808e7b..03504a09d1 100644
--- a/dubbo-spring-boot/dubbo-spring-boot-actuator/src/test/java/org/apache/dubbo/spring/boot/actuate/autoconfigure/DubboEndpointAnnotationAutoConfigurationTest.java
+++ b/dubbo-spring-boot/dubbo-spring-boot-actuator/src/test/java/org/apache/dubbo/spring/boot/actuate/autoconfigure/DubboEndpointAnnotationAutoConfigurationTest.java
@@ -21,8 +21,8 @@ import org.apache.dubbo.config.annotation.DubboReference;
 import org.apache.dubbo.config.annotation.DubboService;
 import org.apache.dubbo.config.bootstrap.DubboBootstrap;
 import org.apache.dubbo.spring.boot.actuate.endpoint.DubboConfigsMetadataEndpoint;
-import org.apache.dubbo.spring.boot.actuate.endpoint.DubboMetadataEndpoint;
 import org.apache.dubbo.spring.boot.actuate.endpoint.DubboPropertiesMetadataEndpoint;
+import org.apache.dubbo.spring.boot.actuate.endpoint.DubboQosEndpoints;
 import org.apache.dubbo.spring.boot.actuate.endpoint.DubboReferencesMetadataEndpoint;
 import org.apache.dubbo.spring.boot.actuate.endpoint.DubboServicesMetadataEndpoint;
 import org.apache.dubbo.spring.boot.actuate.endpoint.DubboShutdownEndpoint;
@@ -86,7 +86,7 @@ import org.springframework.web.client.RestTemplate;
 class DubboEndpointAnnotationAutoConfigurationTest {
 
     @Autowired
-    private DubboMetadataEndpoint dubboEndpoint;
+    private DubboQosEndpoints dubboQosEndpoints;
 
     @Autowired
     private DubboConfigsMetadataEndpoint dubboConfigsMetadataEndpoint;
@@ -225,7 +225,7 @@ class DubboEndpointAnnotationAutoConfigurationTest {
 
     @Test
     void testHttpEndpoints() throws JsonProcessingException {
-        //        testHttpEndpoint("/dubbo", dubboEndpoint::invoke);
+        //        testHttpEndpoint("/dubbo", dubboQosEndpoints::invoke);
         testHttpEndpoint("/dubbo/configs", dubboConfigsMetadataEndpoint::configs);
         testHttpEndpoint("/dubbo/services", dubboServicesMetadataEndpoint::services);
         testHttpEndpoint("/dubbo/references", dubboReferencesMetadataEndpoint::references);
diff --git a/dubbo-spring-boot/dubbo-spring-boot-actuator/src/test/java/org/apache/dubbo/spring/boot/actuate/endpoint/DubboEndpointTest.java b/dubbo-spring-boot/dubbo-spring-boot-actuator/src/test/java/org/apache/dubbo/spring/boot/actuate/endpoint/DubboEndpointTest.java
index 0aea4fc7a8..4af6ffd467 100644
--- a/dubbo-spring-boot/dubbo-spring-boot-actuator/src/test/java/org/apache/dubbo/spring/boot/actuate/endpoint/DubboEndpointTest.java
+++ b/dubbo-spring-boot/dubbo-spring-boot-actuator/src/test/java/org/apache/dubbo/spring/boot/actuate/endpoint/DubboEndpointTest.java
@@ -34,20 +34,20 @@ import org.springframework.test.context.junit.jupiter.SpringExtension;
 import static org.apache.dubbo.common.Version.getVersion;
 
 /**
- * {@link DubboMetadataEndpoint} Test
+ * {@link DubboQosEndpoints} Test
  *
- * @see DubboMetadataEndpoint
+ * @see DubboQosEndpoints
  * @since 2.7.0
  */
 @ExtendWith(SpringExtension.class)
 @SpringBootTest(
-        classes = {DubboMetadataEndpoint.class},
+        classes = {DubboQosEndpoints.class},
         properties = {"dubbo.application.name = dubbo-demo-application"})
 @EnableAutoConfiguration
 class DubboEndpointTest {
 
     @Autowired
-    private DubboMetadataEndpoint dubboEndpoint;
+    private DubboQosEndpoints dubboQosEndpoints;
 
     @BeforeEach
     public void init() {
@@ -62,7 +62,7 @@ class DubboEndpointTest {
     @Test
     void testInvoke() {
 
-        Map<String, Object> metadata = dubboEndpoint.invoke();
+        Map<String, Object> metadata = dubboQosEndpoints.invoke();
 
         Assert.assertNotNull(metadata.get("timestamp"));
 
diff --git a/dubbo-spring-boot/dubbo-spring-boot-compatible/actuator/pom.xml b/dubbo-spring-boot/dubbo-spring-boot-compatible/actuator/pom.xml
index a185cbb07c..c25c1f3309 100644
--- a/dubbo-spring-boot/dubbo-spring-boot-compatible/actuator/pom.xml
+++ b/dubbo-spring-boot/dubbo-spring-boot-compatible/actuator/pom.xml
@@ -94,6 +94,13 @@
       <scope>test</scope>
     </dependency>
 
+    <dependency>
+      <groupId>org.apache.dubbo</groupId>
+      <artifactId>dubbo-qos</artifactId>
+      <version>${project.version}</version>
+      <optional>true</optional>
+    </dependency>
+
     <!-- Test Dependencies -->
     <dependency>
       <groupId>org.springframework.boot</groupId>
diff --git a/dubbo-spring-boot/dubbo-spring-boot-compatible/actuator/src/main/java/org/apache/dubbo/spring/boot/actuate/autoconfigure/DubboExtensionEndpointAutoConfiguration.java b/dubbo-spring-boot/dubbo-spring-boot-compatible/actuator/src/main/java/org/apache/dubbo/spring/boot/actuate/autoconfigure/DubboExtensionEndpointAutoConfiguration.java
new file mode 100644
index 0000000000..871497fc91
--- /dev/null
+++ b/dubbo-spring-boot/dubbo-spring-boot-compatible/actuator/src/main/java/org/apache/dubbo/spring/boot/actuate/autoconfigure/DubboExtensionEndpointAutoConfiguration.java
@@ -0,0 +1,38 @@
+/*
+ * 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.spring.boot.actuate.autoconfigure;
+
+import org.apache.dubbo.spring.boot.actuate.endpoint.configuration.DubboActuatorProperties;
+
+import org.springframework.boot.autoconfigure.AutoConfigureAfter;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+
+import static org.apache.dubbo.spring.boot.util.DubboUtils.DUBBO_PREFIX;
+
+/**
+ * Dubbo Extension Endpoints Auto-{@link Configuration}
+ */
+@ConditionalOnProperty(prefix = DUBBO_PREFIX, name = "enabled", matchIfMissing = true)
+@ConditionalOnClass(name = {"org.springframework.boot.actuate.health.Health"})
+@Configuration
+@AutoConfigureAfter(
+        name = {"org.apache.dubbo.spring.boot.actuate.autoconfigure.DubboEndpointMetadataAutoConfiguration"})
+@ComponentScan(basePackageClasses = DubboActuatorProperties.class)
+public class DubboExtensionEndpointAutoConfiguration {}
diff --git a/dubbo-spring-boot/dubbo-spring-boot-actuator/src/main/java/org/apache/dubbo/spring/boot/actuate/endpoint/DubboMetadataEndpoint.java b/dubbo-spring-boot/dubbo-spring-boot-compatible/actuator/src/main/java/org/apache/dubbo/spring/boot/actuate/endpoint/configuration/DubboActuatorProperties.java
similarity index 51%
rename from dubbo-spring-boot/dubbo-spring-boot-actuator/src/main/java/org/apache/dubbo/spring/boot/actuate/endpoint/DubboMetadataEndpoint.java
rename to dubbo-spring-boot/dubbo-spring-boot-compatible/actuator/src/main/java/org/apache/dubbo/spring/boot/actuate/endpoint/configuration/DubboActuatorProperties.java
index 3eb816d17a..238c9527cc 100644
--- a/dubbo-spring-boot/dubbo-spring-boot-actuator/src/main/java/org/apache/dubbo/spring/boot/actuate/endpoint/DubboMetadataEndpoint.java
+++ b/dubbo-spring-boot/dubbo-spring-boot-compatible/actuator/src/main/java/org/apache/dubbo/spring/boot/actuate/endpoint/configuration/DubboActuatorProperties.java
@@ -14,30 +14,34 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.dubbo.spring.boot.actuate.endpoint;
-
-import org.apache.dubbo.spring.boot.actuate.endpoint.metadata.DubboMetadata;
+package org.apache.dubbo.spring.boot.actuate.endpoint.configuration;
 
 import java.util.Map;
 
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
-import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+import org.springframework.util.StringUtils;
 
-/**
- * Actuator {@link Endpoint} to expose Dubbo Meta Data
- *
- * @see Endpoint
- * @since 2.7.0
- */
-@Endpoint(id = "dubbo")
-public class DubboMetadataEndpoint {
+@Component
+@ConfigurationProperties(prefix = "management.endpoint")
+public class DubboActuatorProperties {
+
+    private Map<String, Boolean> dubbo;
 
-    @Autowired
-    private DubboMetadata dubboMetadata;
+    public Map<String, Boolean> getDubbo() {
+        return dubbo;
+    }
+
+    public void setDubbo(Map<String, Boolean> dubbo) {
+        this.dubbo = dubbo;
+    }
 
-    @ReadOperation
-    public Map<String, Object> invoke() {
-        return dubboMetadata.invoke();
+    public boolean isEnabled(String command) {
+        if (StringUtils.hasText(command)) {
+            Boolean enabled = dubbo.get(command + ".enabled");
+            return enabled != null && enabled;
+        } else {
+            return false;
+        }
     }
 }
diff --git a/dubbo-spring-boot/dubbo-spring-boot-compatible/actuator/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/dubbo-spring-boot/dubbo-spring-boot-compatible/actuator/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
index adb80652d8..7d91fbe55b 100644
--- a/dubbo-spring-boot/dubbo-spring-boot-compatible/actuator/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
+++ b/dubbo-spring-boot/dubbo-spring-boot-compatible/actuator/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
@@ -1,3 +1,4 @@
 org.apache.dubbo.spring.boot.actuate.autoconfigure.DubboEndpointAutoConfiguration
 org.apache.dubbo.spring.boot.actuate.autoconfigure.DubboHealthIndicatorAutoConfiguration
 org.apache.dubbo.spring.boot.actuate.autoconfigure.DubboEndpointMetadataAutoConfiguration
+org.apache.dubbo.spring.boot.actuate.autoconfigure.DubboExtensionEndpointAutoConfiguration