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

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


The following commit(s) were added to refs/heads/3.2 by this push:
     new e7790a7184 metric add SPI (#10622)
e7790a7184 is described below

commit e7790a71847763654c56860e22356cdd534a99fe
Author: jojocodeX <[email protected]>
AuthorDate: Thu Sep 29 13:04:43 2022 +0800

    metric add SPI (#10622)
---
 .../dubbo/common/constants/CommonConstants.java    |   4 +
 .../common/constants/LoggerCodeConstants.java      |   2 +
 .../org/apache/dubbo/config/ApplicationConfig.java |  35 ++--
 .../org/apache/dubbo/config/MetricsConfig.java     |  27 ++-
 dubbo-config/dubbo-config-api/pom.xml              |   8 +
 .../builders/InternalServiceConfigBuilder.java     | 223 +++++++++++++++++++++
 .../config/deploy/DefaultApplicationDeployer.java  |  59 ++++++
 .../deploy/DefaultMetricsServiceExporter.java      | 114 +++++++++++
 .../ConfigurableMetadataServiceExporter.java       | 150 ++------------
 ...o.common.metrics.service.MetricsServiceExporter |   1 +
 dubbo-config/dubbo-config-spring/pom.xml           |   8 +
 .../src/main/resources/META-INF/dubbo.xsd          |   7 +
 .../configprops/SpringBootConfigPropsTest.java     |   1 +
 .../metrics/SpringBootConfigMetricsTest.java       |  95 +++++++++
 .../spring/schema/DubboNamespaceHandlerTest.java   |   3 +
 ...che.dubbo.common.metrics.service.MetricsService |   1 +
 ...o.common.metrics.service.MetricsServiceExporter |   1 +
 .../dubbo/config/spring/metrics-aggregation.xml    |   2 +-
 .../apache/dubbo/metrics/filter/MetricsFilter.java |   3 +
 .../metrics/service/DefaultMetricsService.java     |  10 +-
 ...che.dubbo.common.metrics.service.MetricsService |   1 +
 .../dubbo/internal/org.apache.dubbo.rpc.Filter     |   1 +
 ...che.dubbo.common.metrics.MetricsReporterFactory |   1 +
 23 files changed, 598 insertions(+), 159 deletions(-)

diff --git 
a/dubbo-common/src/main/java/org/apache/dubbo/common/constants/CommonConstants.java
 
b/dubbo-common/src/main/java/org/apache/dubbo/common/constants/CommonConstants.java
index bd4e256528..8c4719000a 100644
--- 
a/dubbo-common/src/main/java/org/apache/dubbo/common/constants/CommonConstants.java
+++ 
b/dubbo-common/src/main/java/org/apache/dubbo/common/constants/CommonConstants.java
@@ -43,6 +43,10 @@ public interface CommonConstants {
 
     String METADATA_SERVICE_PROTOCOL_KEY = "metadata-service-protocol";
 
+    String METRICS_SERVICE_PORT_KEY = "metrics-service-port";
+
+    String METRICS_SERVICE_PROTOCOL_KEY = "metrics-service-protocol";
+
     String LIVENESS_PROBE_KEY = "liveness-probe";
 
     String READINESS_PROBE_KEY = "readiness-probe";
diff --git 
a/dubbo-common/src/main/java/org/apache/dubbo/common/constants/LoggerCodeConstants.java
 
b/dubbo-common/src/main/java/org/apache/dubbo/common/constants/LoggerCodeConstants.java
index ae41ddfe5c..5dc83f19dd 100644
--- 
a/dubbo-common/src/main/java/org/apache/dubbo/common/constants/LoggerCodeConstants.java
+++ 
b/dubbo-common/src/main/java/org/apache/dubbo/common/constants/LoggerCodeConstants.java
@@ -164,4 +164,6 @@ public interface LoggerCodeConstants {
 
     String TRANSPORT_CLIENT_CONNECT_TIMEOUT = "6-2";
 
+    String INTERNAL_SERVICE_CONFIG_ERROR = "6-3";
+
 }
diff --git 
a/dubbo-common/src/main/java/org/apache/dubbo/config/ApplicationConfig.java 
b/dubbo-common/src/main/java/org/apache/dubbo/config/ApplicationConfig.java
index 0d6f28fa66..4e7a601bd1 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/config/ApplicationConfig.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/config/ApplicationConfig.java
@@ -16,23 +16,6 @@
  */
 package org.apache.dubbo.config;
 
-import org.apache.dubbo.common.compiler.support.AdaptiveCompiler;
-import org.apache.dubbo.common.infra.InfraAdapter;
-import org.apache.dubbo.common.logger.Logger;
-import org.apache.dubbo.common.logger.LoggerFactory;
-import org.apache.dubbo.common.utils.CollectionUtils;
-import org.apache.dubbo.common.utils.StringUtils;
-import org.apache.dubbo.config.support.Parameter;
-import org.apache.dubbo.rpc.model.ApplicationModel;
-
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
 import static 
org.apache.dubbo.common.constants.CommonConstants.APPLICATION_KEY;
 import static 
org.apache.dubbo.common.constants.CommonConstants.APPLICATION_PROTOCOL_KEY;
 import static 
org.apache.dubbo.common.constants.CommonConstants.APPLICATION_VERSION_KEY;
@@ -61,6 +44,23 @@ import static 
org.apache.dubbo.config.Constants.DEVELOPMENT_ENVIRONMENT;
 import static org.apache.dubbo.config.Constants.PRODUCTION_ENVIRONMENT;
 import static org.apache.dubbo.config.Constants.TEST_ENVIRONMENT;
 
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.dubbo.common.compiler.support.AdaptiveCompiler;
+import org.apache.dubbo.common.infra.InfraAdapter;
+import org.apache.dubbo.common.logger.Logger;
+import org.apache.dubbo.common.logger.LoggerFactory;
+import org.apache.dubbo.common.utils.CollectionUtils;
+import org.apache.dubbo.common.utils.StringUtils;
+import org.apache.dubbo.config.support.Parameter;
+import org.apache.dubbo.rpc.model.ApplicationModel;
+
 
 /**
  * The application info
@@ -547,6 +547,7 @@ public class ApplicationConfig extends AbstractConfig {
         this.metadataServiceProtocol = metadataServiceProtocol;
     }
 
+
     @Parameter(key = LIVENESS_PROBE_KEY)
     public String getLivenessProbe() {
         return livenessProbe;
diff --git 
a/dubbo-common/src/main/java/org/apache/dubbo/config/MetricsConfig.java 
b/dubbo-common/src/main/java/org/apache/dubbo/config/MetricsConfig.java
index a37985650a..8811d5d612 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/config/MetricsConfig.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/config/MetricsConfig.java
@@ -16,6 +16,9 @@
  */
 package org.apache.dubbo.config;
 
+import java.util.HashMap;
+import java.util.Map;
+
 import org.apache.dubbo.common.URL;
 import org.apache.dubbo.common.utils.UrlUtils;
 import org.apache.dubbo.config.nested.AggregationConfig;
@@ -23,9 +26,6 @@ import org.apache.dubbo.config.nested.PrometheusConfig;
 import org.apache.dubbo.config.support.Nested;
 import org.apache.dubbo.rpc.model.ApplicationModel;
 
-import java.util.HashMap;
-import java.util.Map;
-
 /**
  * MetricsConfig
  */
@@ -59,6 +59,11 @@ public class MetricsConfig extends AbstractConfig {
     @Nested
     private AggregationConfig aggregation;
 
+    private String exportServiceProtocol;
+
+    private Integer exportServicePort;
+
+
     public MetricsConfig() {
     }
 
@@ -116,5 +121,21 @@ public class MetricsConfig extends AbstractConfig {
     public void setAggregation(AggregationConfig aggregation) {
         this.aggregation = aggregation;
     }
+
+    public String getExportServiceProtocol() {
+        return exportServiceProtocol;
+    }
+
+    public void setExportServiceProtocol(String exportServiceProtocol) {
+        this.exportServiceProtocol = exportServiceProtocol;
+    }
+
+    public Integer getExportServicePort() {
+        return exportServicePort;
+    }
+
+    public void setExportServicePort(Integer exportServicePort) {
+        this.exportServicePort = exportServicePort;
+    }
 }
 
diff --git a/dubbo-config/dubbo-config-api/pom.xml 
b/dubbo-config/dubbo-config-api/pom.xml
index 2baac24e9f..c947249309 100644
--- a/dubbo-config/dubbo-config-api/pom.xml
+++ b/dubbo-config/dubbo-config-api/pom.xml
@@ -35,11 +35,19 @@
             <artifactId>dubbo-registry-api</artifactId>
             <version>${project.parent.version}</version>
         </dependency>
+
         <dependency>
             <groupId>org.apache.dubbo</groupId>
             <artifactId>dubbo-metadata-api</artifactId>
             <version>${project.parent.version}</version>
         </dependency>
+
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-metrics-api</artifactId>
+            <version>${project.parent.version}</version>
+        </dependency>
+
         <dependency>
             <groupId>org.apache.dubbo</groupId>
             <artifactId>dubbo-monitor-api</artifactId>
diff --git 
a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/bootstrap/builders/InternalServiceConfigBuilder.java
 
b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/bootstrap/builders/InternalServiceConfigBuilder.java
new file mode 100644
index 0000000000..fac4126f60
--- /dev/null
+++ 
b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/bootstrap/builders/InternalServiceConfigBuilder.java
@@ -0,0 +1,223 @@
+/*
+ * 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.bootstrap.builders;
+
+import static 
org.apache.dubbo.common.constants.CommonConstants.CORE_THREADS_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.DUBBO_PROTOCOL;
+import static org.apache.dubbo.common.constants.CommonConstants.THREADPOOL_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.THREADS_KEY;
+import static 
org.apache.dubbo.common.constants.LoggerCodeConstants.INTERNAL_SERVICE_CONFIG_ERROR;
+import static org.apache.dubbo.remoting.Constants.BIND_PORT_KEY;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.function.Consumer;
+
+import org.apache.dubbo.common.logger.ErrorTypeAwareLogger;
+import org.apache.dubbo.common.logger.LoggerFactory;
+import org.apache.dubbo.common.utils.Assert;
+import org.apache.dubbo.common.utils.CollectionUtils;
+import org.apache.dubbo.common.utils.StringUtils;
+import org.apache.dubbo.config.ApplicationConfig;
+import org.apache.dubbo.config.ProtocolConfig;
+import org.apache.dubbo.config.RegistryConfig;
+import org.apache.dubbo.config.ServiceConfig;
+import org.apache.dubbo.rpc.Protocol;
+import org.apache.dubbo.rpc.ProtocolServer;
+import org.apache.dubbo.rpc.model.ApplicationModel;
+
+public class InternalServiceConfigBuilder<T> {
+
+    private final ErrorTypeAwareLogger logger = 
LoggerFactory.getErrorTypeAwareLogger(getClass());
+
+    private final ApplicationModel applicationModel;
+    private String  protocol;
+    private Integer port;
+    private String registryId;
+    private Class<T> interfaceClass;
+    private T   ref;
+
+    private InternalServiceConfigBuilder(ApplicationModel applicationModel) {
+        this.applicationModel = applicationModel;
+    }
+
+    public static <T> InternalServiceConfigBuilder<T> 
newBuilder(ApplicationModel applicationModel) {
+        return new InternalServiceConfigBuilder<>(applicationModel);
+    }
+
+
+
+    public InternalServiceConfigBuilder<T> interfaceClass(Class<T> 
interfaceClass) {
+        this.interfaceClass = interfaceClass;
+        return getThis();
+    }
+
+    public InternalServiceConfigBuilder<T> ref(T ref) {
+        this.ref = ref;
+        return getThis();
+    }
+
+    public InternalServiceConfigBuilder<T> registryId(String registryId) {
+        this.registryId = registryId;
+        return getThis();
+    }
+    
+    public InternalServiceConfigBuilder<T> protocol(String protocol, String 
key) {
+        if (StringUtils.isEmpty(protocol) && StringUtils.isNotBlank(key)) {
+            Map<String, String> params = 
getApplicationConfig().getParameters();
+
+            if (CollectionUtils.isNotEmptyMap(params)) {
+                protocol = getApplicationConfig().getParameters().get(key);
+            }
+        }
+        this.protocol = StringUtils.isNotEmpty(protocol) ? protocol : 
DUBBO_PROTOCOL;
+
+        return getThis();
+    }
+
+    public InternalServiceConfigBuilder<T> protocol(String protocol) {
+        this.protocol(protocol, null);
+        return getThis();
+    }
+
+    public InternalServiceConfigBuilder<T> port(Integer specPort) {
+        return port(specPort,null);
+    }
+
+
+    public InternalServiceConfigBuilder<T> port(Integer specPort, String key) {
+        Assert.notEmptyString(this.protocol,"export protocol is null");
+        Assert.notNull(this.interfaceClass,"export interfaceClass is null");
+
+        if (specPort != null) {
+            this.port = specPort;
+            return getThis();
+        }
+        Map<String, String> params = getApplicationConfig().getParameters();
+        if (CollectionUtils.isNotEmptyMap(params) && 
StringUtils.isNotBlank(key)) {
+            String rawPort = getApplicationConfig().getParameters().get(key);
+            if (StringUtils.isNotEmpty(rawPort)) {
+                specPort = Integer.parseInt(rawPort);
+            }
+        }
+
+        if (specPort == null || specPort < -1) {
+            try {
+                if (logger.isInfoEnabled()) {
+                    logger.info(interfaceClass.getName()+"Service Port hasn't 
been set will use default protocol defined in protocols.");
+                }
+
+                Protocol protocol = 
applicationModel.getExtensionLoader(Protocol.class).getExtension(this.protocol);
+                if (protocol != null && protocol.getServers() != null) {
+                    Iterator<ProtocolServer> it = 
protocol.getServers().iterator();
+                    // export service may export before normal service export, 
it.hasNext() will return false.
+                    // so need use specified protocol port.
+                    if (it.hasNext()) {
+                        ProtocolServer server = it.next();
+                        String rawPort = 
server.getUrl().getParameter(BIND_PORT_KEY);
+                        if (rawPort == null) {
+                            String addr = server.getAddress();
+                            rawPort = addr.substring(addr.indexOf(":") + 1);
+                        }
+                        this.port = Integer.parseInt(rawPort);
+                    } else {
+                        Integer protocolPort = getProtocolConfig().getPort();
+                        if (null != protocolPort && protocolPort != -1) {
+                            this.port = protocolPort;
+                        }
+                    }
+                }
+            } catch (Exception e) {
+                logger.error(INTERNAL_SERVICE_CONFIG_ERROR, "invalid specified 
" + port + "  port, error "+e.getMessage(),
+                    "", "Failed to find any valid protocol, will use random 
port to export  service.",e);
+            }
+        }
+        if (this.port == null) {
+            this.port = -1;
+        }
+        return getThis();
+    }
+
+    private ProtocolConfig getProtocolConfig() {
+        return 
applicationModel.getApplicationConfigManager().getProtocol(protocol).get();
+    }
+
+    public ServiceConfig<T> build(Consumer<ServiceConfig<T>> configConsumer){
+        ProtocolConfig protocolConfig = new ProtocolConfig();
+        protocolConfig.setName(this.protocol);
+        protocolConfig.setPort(this.port);
+
+        this.nullAssert();
+
+        logger.info("Using " + this.protocol + " protocol to export 
"+interfaceClass.getName()+" service on port " + protocolConfig.getPort());
+
+        ApplicationConfig applicationConfig = getApplicationConfig();
+
+        ServiceConfig<T> serviceConfig = new ServiceConfig<>();
+        serviceConfig.setScopeModel(applicationModel.getInternalModule());
+        serviceConfig.setApplication(applicationConfig);
+
+        RegistryConfig registryConfig = new RegistryConfig("N/A");
+        registryConfig.setId(this.registryId);
+        registryConfig.setScopeModel(this.applicationModel);
+
+        serviceConfig.setRegistry(registryConfig);
+
+        serviceConfig.setRegister(false);
+        serviceConfig.setProtocol(protocolConfig);
+        serviceConfig.setDelay(0);
+        serviceConfig.setInterface(interfaceClass);
+        serviceConfig.setRef(this.ref);
+        serviceConfig.setGroup(applicationConfig.getName());
+        serviceConfig.setVersion("1.0.0");
+
+        serviceConfig.setExecutes(100); // max tasks running at the same time
+        Map<String, String> params = new HashMap<>();
+        params.put(THREADPOOL_KEY, "cached");
+        params.put(THREADS_KEY, "100");
+        params.put(CORE_THREADS_KEY, "2");
+
+        serviceConfig.setParameters(params);
+
+        if (null != configConsumer) {
+            configConsumer.accept(serviceConfig);
+        }
+
+        return serviceConfig;
+    }
+
+    public ServiceConfig<T> build(){
+        return build(null);
+    }
+    private void nullAssert() {
+        Assert.notNull(port, "export service port is null");
+        Assert.notNull(protocol, "export service protocol is null");
+        Assert.notNull(interfaceClass, "export service interfaceClass is 
null");
+        Assert.notNull(ref,"export service ref is null");
+        Assert.notNull(registryId,"export service registryId is null");
+    }
+
+    protected InternalServiceConfigBuilder<T> getThis() {
+        return this;
+    }
+
+    private ApplicationConfig getApplicationConfig() {
+        return 
applicationModel.getApplicationConfigManager().getApplication().get();
+    }
+
+}
diff --git 
a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/deploy/DefaultApplicationDeployer.java
 
b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/deploy/DefaultApplicationDeployer.java
index 441598e375..edbfc0da78 100644
--- 
a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/deploy/DefaultApplicationDeployer.java
+++ 
b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/deploy/DefaultApplicationDeployer.java
@@ -33,6 +33,10 @@ import org.apache.dubbo.common.extension.ExtensionLoader;
 import org.apache.dubbo.common.lang.ShutdownHookCallbacks;
 import org.apache.dubbo.common.logger.ErrorTypeAwareLogger;
 import org.apache.dubbo.common.logger.LoggerFactory;
+import org.apache.dubbo.common.metrics.MetricsReporter;
+import org.apache.dubbo.common.metrics.MetricsReporterFactory;
+import org.apache.dubbo.common.metrics.collector.DefaultMetricsCollector;
+import org.apache.dubbo.common.metrics.service.MetricsServiceExporter;
 import org.apache.dubbo.common.threadpool.manager.ExecutorRepository;
 import org.apache.dubbo.common.threadpool.manager.FrameworkExecutorRepository;
 import org.apache.dubbo.common.utils.ArrayUtils;
@@ -42,6 +46,7 @@ import org.apache.dubbo.config.ApplicationConfig;
 import org.apache.dubbo.config.ConfigCenterConfig;
 import org.apache.dubbo.config.DubboShutdownHook;
 import org.apache.dubbo.config.MetadataReportConfig;
+import org.apache.dubbo.config.MetricsConfig;
 import org.apache.dubbo.config.RegistryConfig;
 import org.apache.dubbo.config.context.ConfigManager;
 import org.apache.dubbo.config.utils.CompositeReferenceCache;
@@ -75,6 +80,7 @@ import static 
org.apache.dubbo.common.constants.CommonConstants.REGISTRY_SPLIT_P
 import static 
org.apache.dubbo.common.constants.CommonConstants.REMOTE_METADATA_STORAGE_TYPE;
 import static 
org.apache.dubbo.common.constants.LoggerCodeConstants.CONFIG_REFRESH_INSTANCE_ERROR;
 import static 
org.apache.dubbo.common.constants.LoggerCodeConstants.CONFIG_REGISTER_INSTANCE_ERROR;
+import static 
org.apache.dubbo.common.constants.MetricsConstants.PROTOCOL_PROMETHEUS;
 import static org.apache.dubbo.common.utils.StringUtils.isEmpty;
 import static org.apache.dubbo.common.utils.StringUtils.isNotEmpty;
 import static 
org.apache.dubbo.metadata.MetadataConstants.DEFAULT_METADATA_PUBLISH_DELAY;
@@ -105,6 +111,9 @@ public class DefaultApplicationDeployer extends 
AbstractDeployer<ApplicationMode
     private ScheduledFuture<?> asyncMetadataFuture;
     private volatile CompletableFuture<Boolean> startFuture;
     private final DubboShutdownHook dubboShutdownHook;
+
+    private volatile MetricsServiceExporter metricsServiceExporter;
+
     private final Object stateLock = new Object();
     private final Object startLock = new Object();
     private final Object destroyLock = new Object();
@@ -190,6 +199,11 @@ public class DefaultApplicationDeployer extends 
AbstractDeployer<ApplicationMode
 
             initModuleDeployers();
 
+
+            initMetricsReporter();
+
+            initMetricsService();
+
             // @since 2.7.8
             startMetadataCenter();
 
@@ -329,6 +343,27 @@ public class DefaultApplicationDeployer extends 
AbstractDeployer<ApplicationMode
         }
     }
 
+    private void initMetricsService() {
+        this.metricsServiceExporter = 
getExtensionLoader(MetricsServiceExporter.class).getDefaultExtension();
+        metricsServiceExporter.init();
+    }
+
+    private void initMetricsReporter() {
+        DefaultMetricsCollector collector = 
applicationModel.getBeanFactory().getOrRegisterBean(DefaultMetricsCollector.class);
+        MetricsConfig metricsConfig = configManager.getMetrics().orElse(null);
+        // TODO compatible with old usage of metrics, remove protocol check 
after new metrics is ready for use.
+        if (metricsConfig != null && 
PROTOCOL_PROMETHEUS.equals(metricsConfig.getProtocol())) {
+            collector.setCollectEnabled(true);
+            String protocol = metricsConfig.getProtocol();
+            if (StringUtils.isNotEmpty(protocol)) {
+                MetricsReporterFactory metricsReporterFactory = 
getExtensionLoader(MetricsReporterFactory.class).getAdaptiveExtension();
+                MetricsReporter metricsReporter = 
metricsReporterFactory.createMetricsReporter(metricsConfig.toUrl());
+                metricsReporter.init();
+            }
+        }
+    }
+
+
     private boolean isUsedRegistryAsConfigCenter(RegistryConfig 
registryConfig) {
         return isUsedRegistryAsCenter(registryConfig, 
registryConfig::getUseAsConfigCenter, "config",
             DynamicConfigurationFactory.class);
@@ -611,6 +646,9 @@ public class DefaultApplicationDeployer extends 
AbstractDeployer<ApplicationMode
             return;
         }
 
+        // export MetricsService
+        exportMetricsService();
+
         if (isRegisterConsumerInstance()) {
             exportMetadataService();
             if (hasPreparedApplicationInstance.compareAndSet(false, true)) {
@@ -643,6 +681,24 @@ public class DefaultApplicationDeployer extends 
AbstractDeployer<ApplicationMode
         }
     }
 
+    private void exportMetricsService() {
+        try {
+            metricsServiceExporter.export();
+        } catch (Exception e) {
+            logger.error("exportMetricsService an exception occurred when 
handle starting event", e);
+        }
+    }
+
+    private void unexportMetricsService() {
+        if (metricsServiceExporter != null) {
+            try {
+                metricsServiceExporter.unexport();
+            } catch (Exception ignored) {
+                // ignored
+            }
+        }
+    }
+
     private boolean hasExportedServices() {
         for (ModuleModel moduleModel : applicationModel.getModuleModels()) {
             if 
(CollectionUtils.isNotEmpty(moduleModel.getConfigManager().getServices())) {
@@ -766,6 +822,8 @@ public class DefaultApplicationDeployer extends 
AbstractDeployer<ApplicationMode
             }
             onStopping();
 
+            unexportMetricsService();
+
             unregisterServiceInstance();
             destroyRegistries();
             destroyMetadataReports();
@@ -774,6 +832,7 @@ public class DefaultApplicationDeployer extends 
AbstractDeployer<ApplicationMode
             if (asyncMetadataFuture != null) {
                 asyncMetadataFuture.cancel(true);
             }
+
         }
     }
 
diff --git 
a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/deploy/DefaultMetricsServiceExporter.java
 
b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/deploy/DefaultMetricsServiceExporter.java
new file mode 100644
index 0000000000..07359bb252
--- /dev/null
+++ 
b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/deploy/DefaultMetricsServiceExporter.java
@@ -0,0 +1,114 @@
+/*
+ * 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.deploy;
+
+import static 
org.apache.dubbo.common.constants.MetricsConstants.PROTOCOL_PROMETHEUS;
+
+import org.apache.dubbo.common.logger.Logger;
+import org.apache.dubbo.common.logger.LoggerFactory;
+import org.apache.dubbo.common.metrics.service.MetricsService;
+import org.apache.dubbo.common.metrics.service.MetricsServiceExporter;
+import org.apache.dubbo.config.MetricsConfig;
+import org.apache.dubbo.config.ServiceConfig;
+import org.apache.dubbo.config.bootstrap.builders.InternalServiceConfigBuilder;
+import org.apache.dubbo.rpc.model.ApplicationModel;
+import org.apache.dubbo.rpc.model.ScopeModelAware;
+
+/**
+ * Export metrics service
+ */
+public class DefaultMetricsServiceExporter implements MetricsServiceExporter, 
ScopeModelAware {
+
+    private final Logger logger = LoggerFactory.getLogger(getClass());
+
+    private          ApplicationModel              applicationModel;
+    private          MetricsService                metricsService;
+    private volatile ServiceConfig<MetricsService> serviceConfig;
+
+    @Override
+    public void init() {
+        initialize();
+    }
+
+    private void initialize() {
+        MetricsConfig metricsConfig = 
applicationModel.getApplicationConfigManager().getMetrics().orElse(null);
+        // TODO compatible with old usage of metrics, remove protocol check 
after new metrics is ready for use.
+        if (metricsConfig != null &&  metricsService == null) {
+            if (PROTOCOL_PROMETHEUS.equals(metricsConfig.getProtocol()) ) {
+                this.metricsService  = 
applicationModel.getExtensionLoader(MetricsService.class).getDefaultExtension();
+            } else {
+                logger.warn("Protocol " + metricsConfig.getProtocol() + " not 
support for new metrics mechanism. " +
+                    "Using old metrics mechanism instead.");
+            }
+        }
+    }
+
+    @Override
+    public void setApplicationModel(ApplicationModel applicationModel) {
+        this.applicationModel = applicationModel;
+    }
+
+    @Override
+    public MetricsServiceExporter export() {
+        if (metricsService != null) {
+            if (!isExported()) {
+                ServiceConfig<MetricsService> serviceConfig = 
InternalServiceConfigBuilder.<MetricsService>newBuilder(applicationModel)
+                    .interfaceClass(MetricsService.class)
+                    .protocol(getMetricsConfig().getExportServiceProtocol())
+                    .port(getMetricsConfig().getExportServicePort())
+                    .ref(metricsService)
+                    .registryId("internal-metrics-registry")
+                    .build();
+
+                // export
+                serviceConfig.export();
+
+                if (logger.isInfoEnabled()) {
+                    logger.info("The MetricsService exports urls : " + 
serviceConfig.getExportedUrls());
+                }
+                this.serviceConfig = serviceConfig;
+            } else {
+                if (logger.isWarnEnabled()) {
+                    logger.warn("The MetricsService has been exported : " + 
serviceConfig.getExportedUrls());
+                }
+            }
+        } else {
+            if (logger.isWarnEnabled()) {
+                logger.warn("The MetricsConfig not exist, will not export 
metrics service.");
+            }
+        }
+
+        return this;
+    }
+
+    @Override
+    public MetricsServiceExporter unexport() {
+        if (isExported()) {
+            serviceConfig.unexport();
+        }
+        return this;
+    }
+
+    private MetricsConfig getMetricsConfig() {
+        return 
applicationModel.getApplicationConfigManager().getMetrics().get();
+    }
+
+    private boolean isExported() {
+        return serviceConfig != null && serviceConfig.isExported() && 
!serviceConfig.isUnexported();
+    }
+
+}
diff --git 
a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/metadata/ConfigurableMetadataServiceExporter.java
 
b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/metadata/ConfigurableMetadataServiceExporter.java
index d663e8add1..31a3c4880f 100644
--- 
a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/metadata/ConfigurableMetadataServiceExporter.java
+++ 
b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/metadata/ConfigurableMetadataServiceExporter.java
@@ -16,39 +16,25 @@
  */
 package org.apache.dubbo.config.metadata;
 
+import static java.util.Collections.emptyList;
+import static 
org.apache.dubbo.common.constants.CommonConstants.METADATA_SERVICE_PORT_KEY;
+import static 
org.apache.dubbo.common.constants.CommonConstants.METADATA_SERVICE_PROTOCOL_KEY;
+
+import java.util.Collections;
+import java.util.List;
+
 import org.apache.dubbo.common.URL;
 import org.apache.dubbo.common.logger.ErrorTypeAwareLogger;
 import org.apache.dubbo.common.logger.LoggerFactory;
-import org.apache.dubbo.common.utils.CollectionUtils;
-import org.apache.dubbo.common.utils.StringUtils;
 import org.apache.dubbo.config.ApplicationConfig;
 import org.apache.dubbo.config.ArgumentConfig;
 import org.apache.dubbo.config.MethodConfig;
-import org.apache.dubbo.config.ProtocolConfig;
-import org.apache.dubbo.config.RegistryConfig;
 import org.apache.dubbo.config.ServiceConfig;
+import org.apache.dubbo.config.bootstrap.builders.InternalServiceConfigBuilder;
 import org.apache.dubbo.metadata.MetadataService;
 import org.apache.dubbo.registry.client.metadata.MetadataServiceDelegation;
-import org.apache.dubbo.rpc.Protocol;
-import org.apache.dubbo.rpc.ProtocolServer;
 import org.apache.dubbo.rpc.model.ApplicationModel;
 
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import static java.util.Collections.emptyList;
-import static 
org.apache.dubbo.common.constants.CommonConstants.CORE_THREADS_KEY;
-import static org.apache.dubbo.common.constants.CommonConstants.DUBBO_PROTOCOL;
-import static 
org.apache.dubbo.common.constants.CommonConstants.METADATA_SERVICE_PORT_KEY;
-import static 
org.apache.dubbo.common.constants.CommonConstants.METADATA_SERVICE_PROTOCOL_KEY;
-import static org.apache.dubbo.common.constants.CommonConstants.THREADPOOL_KEY;
-import static org.apache.dubbo.common.constants.CommonConstants.THREADS_KEY;
-import static 
org.apache.dubbo.common.constants.LoggerCodeConstants.CONFIG_FAILED_FIND_PROTOCOL;
-import static org.apache.dubbo.remoting.Constants.BIND_PORT_KEY;
-
 /**
  * Export metadata service
  */
@@ -68,9 +54,17 @@ public class ConfigurableMetadataServiceExporter {
 
     public synchronized ConfigurableMetadataServiceExporter export() {
         if (serviceConfig == null || !isExported()) {
-            this.serviceConfig = buildServiceConfig();
+            this.serviceConfig = 
InternalServiceConfigBuilder.<MetadataService>newBuilder(applicationModel)
+                .interfaceClass(MetadataService.class)
+                .protocol(getApplicationConfig().getMetadataServiceProtocol(), 
METADATA_SERVICE_PROTOCOL_KEY)
+                .port(getApplicationConfig().getMetadataServicePort(), 
METADATA_SERVICE_PORT_KEY)
+                .registryId("internal-metadata-registry")
+                .ref(metadataService)
+                .build(configConsumer -> 
configConsumer.setMethods(generateMethodConfig()));
+
             // export
             serviceConfig.export();
+
             
metadataService.setMetadataURL(serviceConfig.getExportedUrls().get(0));
             if (logger.isInfoEnabled()) {
                 logger.info("The MetadataService exports urls : " + 
serviceConfig.getExportedUrls());
@@ -100,115 +94,6 @@ public class ConfigurableMetadataServiceExporter {
         return 
applicationModel.getApplicationConfigManager().getApplication().get();
     }
 
-    private ProtocolConfig getProtocolConfig(String protocol) {
-        return 
applicationModel.getApplicationConfigManager().getProtocol(protocol).get();
-    }
-
-    private ProtocolConfig generateMetadataProtocol() {
-        // protocol always defaults to dubbo if not specified
-        String specifiedProtocol = getSpecifiedProtocol();
-        // port can not being determined here if not specified
-        Integer port = getSpecifiedPort();
-
-        ProtocolConfig protocolConfig = new ProtocolConfig();
-        protocolConfig.setName(specifiedProtocol);
-
-        if (port == null || port < -1) {
-            try {
-                if (logger.isInfoEnabled()) {
-                    logger.info("Metadata Service Port hasn't been set will 
use default protocol defined in protocols.");
-                }
-
-                Protocol protocol = 
applicationModel.getExtensionLoader(Protocol.class).getExtension(specifiedProtocol);
-                if (protocol != null && protocol.getServers() != null) {
-                    Iterator<ProtocolServer> it = 
protocol.getServers().iterator();
-                    // metadata service may export before normal service 
export, it.hasNext() will return false.
-                    // so need use specified protocol port.
-                    if (it.hasNext()) {
-                        ProtocolServer server = it.next();
-                        String rawPort = 
server.getUrl().getParameter(BIND_PORT_KEY);
-                        if (rawPort == null) {
-                            String addr = server.getAddress();
-                            rawPort = addr.substring(addr.indexOf(":") + 1);
-                        }
-                        protocolConfig.setPort(Integer.parseInt(rawPort));
-                    } else {
-                        Integer protocolPort = 
getProtocolConfig(specifiedProtocol).getPort();
-                        if (null != protocolPort && protocolPort != -1) {
-                            protocolConfig.setPort(protocolPort);
-                        }
-                    }
-                }
-            } catch (Exception e) {
-                logger.error(CONFIG_FAILED_FIND_PROTOCOL, "invalid specified " 
+ specifiedProtocol + "  protocol", "", "Failed to find any valid protocol, 
will use random port to export metadata service.", e);
-            }
-        } else {
-            protocolConfig.setPort(port);
-        }
-
-        if (protocolConfig.getPort() == null) {
-            protocolConfig.setPort(-1);
-        }
-
-        logger.info("Using " + specifiedProtocol + " protocol to export 
metadata service on port " + protocolConfig.getPort());
-
-        return protocolConfig;
-    }
-
-    private Integer getSpecifiedPort() {
-        Integer port = getApplicationConfig().getMetadataServicePort();
-        if (port == null) {
-            Map<String, String> params = 
getApplicationConfig().getParameters();
-            if (CollectionUtils.isNotEmptyMap(params)) {
-                String rawPort = 
getApplicationConfig().getParameters().get(METADATA_SERVICE_PORT_KEY);
-                if (StringUtils.isNotEmpty(rawPort)) {
-                    port = Integer.parseInt(rawPort);
-                }
-            }
-        }
-        return port;
-    }
-
-    private String getSpecifiedProtocol() {
-        String protocol = getApplicationConfig().getMetadataServiceProtocol();
-        if (StringUtils.isEmpty(protocol)) {
-            Map<String, String> params = 
getApplicationConfig().getParameters();
-            if (CollectionUtils.isNotEmptyMap(params)) {
-                protocol = 
getApplicationConfig().getParameters().get(METADATA_SERVICE_PROTOCOL_KEY);
-            }
-        }
-
-        return StringUtils.isNotEmpty(protocol) ? protocol : DUBBO_PROTOCOL;
-    }
-
-
-    private ServiceConfig<MetadataService> buildServiceConfig() {
-        ApplicationConfig applicationConfig = getApplicationConfig();
-        ServiceConfig<MetadataService> serviceConfig = new ServiceConfig<>();
-        serviceConfig.setScopeModel(applicationModel.getInternalModule());
-        serviceConfig.setApplication(applicationConfig);
-        RegistryConfig registryConfig = new RegistryConfig("N/A");
-        registryConfig.setId("internal-metadata-registry");
-        serviceConfig.setRegistry(registryConfig);
-        serviceConfig.setRegister(false);
-        serviceConfig.setProtocol(generateMetadataProtocol());
-        serviceConfig.setInterface(MetadataService.class);
-        serviceConfig.setDelay(0);
-        serviceConfig.setRef(metadataService);
-        serviceConfig.setGroup(applicationConfig.getName());
-        serviceConfig.setVersion(MetadataService.VERSION);
-        serviceConfig.setMethods(generateMethodConfig());
-        serviceConfig.setConnections(1); // separate connection
-        serviceConfig.setExecutes(100); // max tasks running at the same time
-        Map<String, String> threadParams = new HashMap<>();
-        threadParams.put(THREADPOOL_KEY, "cached");
-        threadParams.put(THREADS_KEY, "100");
-        threadParams.put(CORE_THREADS_KEY, "2");
-        serviceConfig.setParameters(threadParams);
-
-        return serviceConfig;
-    }
-
     /**
      * Generate Method Config for Service Discovery Metadata <p/>
      * <p>
@@ -240,5 +125,4 @@ public class ConfigurableMetadataServiceExporter {
     public List<URL> getExportedURLs() {
         return serviceConfig != null ? serviceConfig.getExportedUrls() : 
emptyList();
     }
-
 }
diff --git 
a/dubbo-config/dubbo-config-api/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.common.metrics.service.MetricsServiceExporter
 
b/dubbo-config/dubbo-config-api/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.common.metrics.service.MetricsServiceExporter
new file mode 100644
index 0000000000..7edea936d5
--- /dev/null
+++ 
b/dubbo-config/dubbo-config-api/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.common.metrics.service.MetricsServiceExporter
@@ -0,0 +1 @@
+default=org.apache.dubbo.config.deploy.DefaultMetricsServiceExporter
diff --git a/dubbo-config/dubbo-config-spring/pom.xml 
b/dubbo-config/dubbo-config-spring/pom.xml
index 93aad74d69..0455fe6591 100644
--- a/dubbo-config/dubbo-config-spring/pom.xml
+++ b/dubbo-config/dubbo-config-spring/pom.xml
@@ -38,6 +38,14 @@
             <artifactId>dubbo-config-api</artifactId>
             <version>${project.parent.version}</version>
         </dependency>
+
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-metrics-prometheus</artifactId>
+            <version>${project.parent.version}</version>
+            <scope>test</scope>
+        </dependency>
+
         <dependency>
             <groupId>org.springframework</groupId>
             <artifactId>spring-beans</artifactId>
diff --git 
a/dubbo-config/dubbo-config-spring/src/main/resources/META-INF/dubbo.xsd 
b/dubbo-config/dubbo-config-spring/src/main/resources/META-INF/dubbo.xsd
index 10bc5c6278..e58f4f6367 100644
--- a/dubbo-config/dubbo-config-spring/src/main/resources/META-INF/dubbo.xsd
+++ b/dubbo-config/dubbo-config-spring/src/main/resources/META-INF/dubbo.xsd
@@ -952,6 +952,13 @@
                 <xsd:documentation><![CDATA[ The metrics protocol. 
]]></xsd:documentation>
             </xsd:annotation>
         </xsd:attribute>
+
+        <xsd:attribute name="enable-jvm-metrics" type="xsd:boolean" 
default="false">
+            <xsd:annotation>
+                <xsd:documentation><![CDATA[ Enable jvm metrics when 
collecting. ]]></xsd:documentation>
+            </xsd:annotation>
+        </xsd:attribute>
+
         <xsd:attribute name="port" type="xsd:string">
             <xsd:annotation>
                 <xsd:documentation><![CDATA[ Deprecated. No longer use. 
]]></xsd:documentation>
diff --git 
a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/boot/configprops/SpringBootConfigPropsTest.java
 
b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/boot/configprops/SpringBootConfigPropsTest.java
index 4d2b8e303b..4b7091189c 100644
--- 
a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/boot/configprops/SpringBootConfigPropsTest.java
+++ 
b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/boot/configprops/SpringBootConfigPropsTest.java
@@ -55,6 +55,7 @@ import static 
org.apache.dubbo.common.constants.MetricsConstants.PROTOCOL_PROMET
         "dubbo.protocol.name=dubbo",
         "dubbo.protocol.port=20880",
         "dubbo.metrics.protocol=prometheus",
+        "dubbo.metrics.enable-jvm-metrics=true",
         "dubbo.metrics.prometheus.exporter.enabled=true",
         "dubbo.metrics.prometheus.exporter.enable-http-service-discovery=true",
         
"dubbo.metrics.prometheus.exporter.http-service-discovery-url=localhost:8080",
diff --git 
a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/metrics/SpringBootConfigMetricsTest.java
 
b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/metrics/SpringBootConfigMetricsTest.java
new file mode 100644
index 0000000000..3b54f09bd0
--- /dev/null
+++ 
b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/metrics/SpringBootConfigMetricsTest.java
@@ -0,0 +1,95 @@
+/*
+ * 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.metrics;
+
+import static 
org.apache.dubbo.common.constants.MetricsConstants.PROTOCOL_PROMETHEUS;
+
+import org.apache.dubbo.config.MetricsConfig;
+import org.apache.dubbo.config.bootstrap.DubboBootstrap;
+import org.apache.dubbo.config.context.ConfigManager;
+import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+
+@SpringBootTest(
+    properties = {
+        "dubbo.application.NAME = dubbo-demo-application",
+        "dubbo.module.name = dubbo-demo-module",
+        "dubbo.registry.address = zookeeper://localhost:2181",
+        "dubbo.protocol.name=dubbo",
+        "dubbo.protocol.port=20880",
+        "dubbo.metrics.protocol=prometheus",
+        "dubbo.metrics.export-service-protocol=tri",
+        "dubbo.metrics.export-service-port=9999",
+        "dubbo.metrics.enable-jvm-metrics=true",
+        "dubbo.metrics.prometheus.exporter.enabled=true",
+        "dubbo.metrics.prometheus.exporter.enable-http-service-discovery=true",
+        
"dubbo.metrics.prometheus.exporter.http-service-discovery-url=localhost:8080",
+        "dubbo.metrics.prometheus.exporter.metrics-port=20888",
+        "dubbo.metrics.prometheus.exporter.metrics-path=/metrics",
+        "dubbo.metrics.aggregation.enabled=true",
+        "dubbo.metrics.aggregation.bucket-num=5",
+        "dubbo.metrics.aggregation.time-window-seconds=120",
+        "dubbo.metadata-report.address=${zookeeper.connection.address.2}"
+    },
+    classes = {
+        SpringBootConfigMetricsTest.class
+    }
+)
+@Configuration
+@ComponentScan
+@EnableDubbo
+public class SpringBootConfigMetricsTest {
+
+    @BeforeAll
+    public static void beforeAll() {
+        DubboBootstrap.reset();
+    }
+
+    @AfterAll
+    public static void afterAll() {
+        DubboBootstrap.reset();
+    }
+
+    @Autowired
+    private ConfigManager configManager;
+
+    @Test
+    public void testMetrics() {
+        MetricsConfig metricsConfig = configManager.getMetrics().get();
+
+        Assertions.assertEquals(PROTOCOL_PROMETHEUS, 
metricsConfig.getProtocol());
+        Assertions.assertTrue(metricsConfig.getEnableJvmMetrics());
+        
Assertions.assertEquals("tri",metricsConfig.getExportServiceProtocol());
+        Assertions.assertEquals(9999, metricsConfig.getExportServicePort());
+        
Assertions.assertTrue(metricsConfig.getPrometheus().getExporter().getEnabled());
+        
Assertions.assertTrue(metricsConfig.getPrometheus().getExporter().getEnableHttpServiceDiscovery());
+        Assertions.assertEquals("localhost:8080", 
metricsConfig.getPrometheus().getExporter().getHttpServiceDiscoveryUrl());
+        Assertions.assertEquals(20888, 
metricsConfig.getPrometheus().getExporter().getMetricsPort());
+        Assertions.assertEquals("/metrics", 
metricsConfig.getPrometheus().getExporter().getMetricsPath());
+        Assertions.assertEquals(5, 
metricsConfig.getAggregation().getBucketNum());
+        Assertions.assertEquals(120, 
metricsConfig.getAggregation().getTimeWindowSeconds());
+        Assertions.assertTrue(metricsConfig.getAggregation().getEnabled());
+    }
+
+}
diff --git 
a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/schema/DubboNamespaceHandlerTest.java
 
b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/schema/DubboNamespaceHandlerTest.java
index 69bb8d7c5c..73ae2cbddb 100644
--- 
a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/schema/DubboNamespaceHandlerTest.java
+++ 
b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/schema/DubboNamespaceHandlerTest.java
@@ -55,6 +55,7 @@ import static org.hamcrest.CoreMatchers.nullValue;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
 
 public class DubboNamespaceHandlerTest {
 
@@ -256,6 +257,8 @@ public class DubboNamespaceHandlerTest {
         MetricsConfig metricsBean = ctx.getBean(MetricsConfig.class);
         MetricsConfig metrics = configManager.getMetrics().get();
 
+        assertTrue(metrics.getEnableJvmMetrics());
+
         assertEquals(metrics.getAggregation().getEnabled(), true);
         assertEquals(metrics.getAggregation().getBucketNum(), 5);
         assertEquals(metrics.getAggregation().getTimeWindowSeconds(), 120);
diff --git 
a/dubbo-config/dubbo-config-spring/src/test/resources/META-INF/dubbo/internal/org.apache.dubbo.common.metrics.service.MetricsService
 
b/dubbo-config/dubbo-config-spring/src/test/resources/META-INF/dubbo/internal/org.apache.dubbo.common.metrics.service.MetricsService
new file mode 100644
index 0000000000..66833ce76a
--- /dev/null
+++ 
b/dubbo-config/dubbo-config-spring/src/test/resources/META-INF/dubbo/internal/org.apache.dubbo.common.metrics.service.MetricsService
@@ -0,0 +1 @@
+default=org.apache.dubbo.metrics.service.DefaultMetricsService
diff --git 
a/dubbo-config/dubbo-config-spring/src/test/resources/META-INF/dubbo/internal/org.apache.dubbo.common.metrics.service.MetricsServiceExporter
 
b/dubbo-config/dubbo-config-spring/src/test/resources/META-INF/dubbo/internal/org.apache.dubbo.common.metrics.service.MetricsServiceExporter
new file mode 100644
index 0000000000..7edea936d5
--- /dev/null
+++ 
b/dubbo-config/dubbo-config-spring/src/test/resources/META-INF/dubbo/internal/org.apache.dubbo.common.metrics.service.MetricsServiceExporter
@@ -0,0 +1 @@
+default=org.apache.dubbo.config.deploy.DefaultMetricsServiceExporter
diff --git 
a/dubbo-config/dubbo-config-spring/src/test/resources/org/apache/dubbo/config/spring/metrics-aggregation.xml
 
b/dubbo-config/dubbo-config-spring/src/test/resources/org/apache/dubbo/config/spring/metrics-aggregation.xml
index d0eafd70ef..96835f7703 100644
--- 
a/dubbo-config/dubbo-config-spring/src/test/resources/org/apache/dubbo/config/spring/metrics-aggregation.xml
+++ 
b/dubbo-config/dubbo-config-spring/src/test/resources/org/apache/dubbo/config/spring/metrics-aggregation.xml
@@ -24,7 +24,7 @@
     <!-- current application configuration -->
     <dubbo:application name="demo-consumer" />
 
-    <dubbo:metrics>
+    <dubbo:metrics enable-jvm-metrics="true">
         <dubbo:aggregation enabled="true" bucket-num="5" 
time-window-seconds="120" />
     </dubbo:metrics>
 
diff --git 
a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/filter/MetricsFilter.java
 
b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/filter/MetricsFilter.java
index 4e5cc13d9f..f13c90d6a9 100644
--- 
a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/filter/MetricsFilter.java
+++ 
b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/filter/MetricsFilter.java
@@ -66,6 +66,9 @@ public class MetricsFilter implements Filter, 
BaseFilter.Listener, ScopeModelAwa
     }
 
     private void collect(Invocation invocation, 
Consumer<MetricsCollectExecutor> execute) {
+        if (collector == null || !collector.isCollectEnabled()) {
+            return;
+        }
         MetricsCollectExecutor collectorExecutor = new 
MetricsCollectExecutor(collector, invocation);
         execute.accept(collectorExecutor);
     }
diff --git 
a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/service/DefaultMetricsService.java
 
b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/service/DefaultMetricsService.java
index c91e5f3e83..440f09efd0 100644
--- 
a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/service/DefaultMetricsService.java
+++ 
b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/service/DefaultMetricsService.java
@@ -17,6 +17,11 @@
 
 package org.apache.dubbo.metrics.service;
 
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
 import org.apache.dubbo.common.metrics.collector.DefaultMetricsCollector;
 import org.apache.dubbo.common.metrics.collector.MetricsCollector;
 import org.apache.dubbo.common.metrics.model.MetricsCategory;
@@ -27,11 +32,6 @@ import 
org.apache.dubbo.common.metrics.service.MetricsService;
 import org.apache.dubbo.metrics.collector.AggregateMetricsCollector;
 import org.apache.dubbo.rpc.model.ApplicationModel;
 
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
 /**
  * Default implementation of {@link MetricsService}
  */
diff --git 
a/dubbo-metrics/dubbo-metrics-api/src/resources/META-INF/dubbo/internal/org.apache.dubbo.common.metrics.service.MetricsService
 
b/dubbo-metrics/dubbo-metrics-api/src/resources/META-INF/dubbo/internal/org.apache.dubbo.common.metrics.service.MetricsService
new file mode 100644
index 0000000000..66833ce76a
--- /dev/null
+++ 
b/dubbo-metrics/dubbo-metrics-api/src/resources/META-INF/dubbo/internal/org.apache.dubbo.common.metrics.service.MetricsService
@@ -0,0 +1 @@
+default=org.apache.dubbo.metrics.service.DefaultMetricsService
diff --git 
a/dubbo-metrics/dubbo-metrics-api/src/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.Filter
 
b/dubbo-metrics/dubbo-metrics-api/src/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.Filter
new file mode 100644
index 0000000000..1cd29b9b77
--- /dev/null
+++ 
b/dubbo-metrics/dubbo-metrics-api/src/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.Filter
@@ -0,0 +1 @@
+metrics-beta=org.apache.dubbo.metrics.filter.MetricsFilter
diff --git 
a/dubbo-metrics/dubbo-metrics-prometheus/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.common.metrics.MetricsReporterFactory
 
b/dubbo-metrics/dubbo-metrics-prometheus/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.common.metrics.MetricsReporterFactory
new file mode 100644
index 0000000000..97deed53e3
--- /dev/null
+++ 
b/dubbo-metrics/dubbo-metrics-prometheus/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.common.metrics.MetricsReporterFactory
@@ -0,0 +1 @@
+prometheus=org.apache.dubbo.metrics.prometheus.PrometheusMetricsReporterFactory

Reply via email to