You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@dubbo.apache.org by zr...@apache.org on 2026/04/22 04:57:03 UTC

(dubbo) branch 3.3 updated: feat: support legacy and new prometheus client stacks (#16132)

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

zrlw 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 68a16cb533 feat: support legacy and new prometheus client stacks (#16132)
68a16cb533 is described below

commit 68a16cb533e2c1036234a5a4a7bc35de25cf7069
Author: SavitarC <71...@users.noreply.github.com>
AuthorDate: Wed Apr 22 12:56:58 2026 +0800

    feat: support legacy and new prometheus client stacks (#16132)
    
    * feat: support legacy and new prometheus client stacks
    
    - add an adapter-based Prometheus reporter for both Micrometer registries
    - detect both legacy and new Prometheus dependencies at runtime
    - wire new Prometheus pushgateway dependencies into the BOM and Spring Boot autoconfigure
    
    * spotless apply
    
    ---------
    
    Co-authored-by: zrlw <zr...@sina.com>
---
 dubbo-dependencies-bom/pom.xml                     |  13 ++
 .../dubbo/metrics/utils/MetricsSupportUtil.java    |  35 +++-
 dubbo-metrics/dubbo-metrics-otlp/pom.xml           |   5 -
 dubbo-metrics/dubbo-metrics-prometheus/pom.xml     |   8 +
 .../prometheus/PrometheusMetricsReporter.java      | 181 ++++++++++++++++++---
 .../PrometheusMetricsReporterFactory.java          |  15 +-
 .../prometheus/PrometheusMetricsReporterTest.java  |  88 ++++++++--
 .../PrometheusMetricsThreadPoolTest.java           |   2 +-
 .../dubbo-spring-boot-autoconfigure/pom.xml        |  16 ++
 9 files changed, 317 insertions(+), 46 deletions(-)

diff --git a/dubbo-dependencies-bom/pom.xml b/dubbo-dependencies-bom/pom.xml
index 27d8e073fa..213b7afa3d 100644
--- a/dubbo-dependencies-bom/pom.xml
+++ b/dubbo-dependencies-bom/pom.xml
@@ -128,6 +128,7 @@
     <micrometer-tracing.version>1.6.5</micrometer-tracing.version>
     <t_digest.version>3.3</t_digest.version>
     <prometheus_client.version>0.16.0</prometheus_client.version>
+    <prometheus_metrics.version>1.5.0</prometheus_metrics.version>
     <reactive.version>1.0.4</reactive.version>
     <reactor.version>3.8.5</reactor.version>
     <mutiny.version>2.9.5</mutiny.version>
@@ -260,6 +261,13 @@
         <type>pom</type>
         <scope>import</scope>
       </dependency>
+      <dependency>
+        <groupId>io.prometheus</groupId>
+        <artifactId>prometheus-metrics-bom</artifactId>
+        <version>${prometheus_metrics.version}</version>
+        <type>pom</type>
+        <scope>import</scope>
+      </dependency>
       <!-- Spring Boot -->
       <dependency>
         <groupId>org.springframework.boot</groupId>
@@ -945,6 +953,11 @@
         <artifactId>simpleclient_pushgateway</artifactId>
         <version>${prometheus_client.version}</version>
       </dependency>
+      <dependency>
+        <groupId>io.prometheus</groupId>
+        <artifactId>prometheus-metrics-exporter-pushgateway</artifactId>
+        <version>${prometheus_metrics.version}</version>
+      </dependency>
       <!-- reactive related dependencies -->
       <dependency>
         <groupId>org.reactivestreams</groupId>
diff --git a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/utils/MetricsSupportUtil.java b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/utils/MetricsSupportUtil.java
index b304197bb8..3415eac631 100644
--- a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/utils/MetricsSupportUtil.java
+++ b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/utils/MetricsSupportUtil.java
@@ -20,18 +20,45 @@ import org.apache.dubbo.common.utils.ClassUtils;
 
 public class MetricsSupportUtil {
 
+    private static final String[] LEGACY_PROMETHEUS_STACK = {
+        "io.micrometer.prometheus.PrometheusConfig",
+        "io.micrometer.prometheus.PrometheusMeterRegistry",
+        "io.prometheus.client.exporter.PushGateway",
+        "io.prometheus.client.exporter.BasicAuthHttpConnectionFactory"
+    };
+
+    private static final String[] NEW_PROMETHEUS_STACK = {
+        "io.micrometer.prometheusmetrics.PrometheusConfig",
+        "io.micrometer.prometheusmetrics.PrometheusMeterRegistry",
+        "io.prometheus.metrics.exporter.pushgateway.PushGateway"
+    };
+
     public static boolean isSupportMetrics() {
         return isClassPresent("io.micrometer.core.instrument.MeterRegistry");
     }
 
     public static boolean isSupportPrometheus() {
-        return isClassPresent("io.micrometer.prometheus.PrometheusConfig")
-                && isClassPresent("io.prometheus.client.exporter.BasicAuthHttpConnectionFactory")
-                && isClassPresent("io.prometheus.client.exporter.HttpConnectionFactory")
-                && isClassPresent("io.prometheus.client.exporter.PushGateway");
+        return isAllClassPresent(LEGACY_PROMETHEUS_STACK) || isAllClassPresent(NEW_PROMETHEUS_STACK);
+    }
+
+    public static boolean isSupportLegacyPrometheus() {
+        return isAllClassPresent(LEGACY_PROMETHEUS_STACK);
+    }
+
+    public static boolean isSupportNewPrometheus() {
+        return isAllClassPresent(NEW_PROMETHEUS_STACK);
     }
 
     private static boolean isClassPresent(String className) {
         return ClassUtils.isPresent(className, MetricsSupportUtil.class.getClassLoader());
     }
+
+    private static boolean isAllClassPresent(String... classNames) {
+        for (String className : classNames) {
+            if (!isClassPresent(className)) {
+                return false;
+            }
+        }
+        return true;
+    }
 }
diff --git a/dubbo-metrics/dubbo-metrics-otlp/pom.xml b/dubbo-metrics/dubbo-metrics-otlp/pom.xml
index 16f7b54e62..45b1ba467b 100644
--- a/dubbo-metrics/dubbo-metrics-otlp/pom.xml
+++ b/dubbo-metrics/dubbo-metrics-otlp/pom.xml
@@ -59,11 +59,6 @@
       <groupId>io.micrometer</groupId>
       <artifactId>micrometer-registry-otlp</artifactId>
     </dependency>
-    <dependency>
-      <groupId>org.apache.dubbo</groupId>
-      <artifactId>dubbo-metrics-default</artifactId>
-      <version>${project.parent.version}</version>
-    </dependency>
     <dependency>
       <groupId>com.squareup.okhttp3</groupId>
       <artifactId>mockwebserver</artifactId>
diff --git a/dubbo-metrics/dubbo-metrics-prometheus/pom.xml b/dubbo-metrics/dubbo-metrics-prometheus/pom.xml
index 96e3e18b92..ba6e7854b5 100644
--- a/dubbo-metrics/dubbo-metrics-prometheus/pom.xml
+++ b/dubbo-metrics/dubbo-metrics-prometheus/pom.xml
@@ -41,10 +41,18 @@
       <artifactId>dubbo-metrics-default</artifactId>
       <version>${project.parent.version}</version>
     </dependency>
+    <dependency>
+      <groupId>io.micrometer</groupId>
+      <artifactId>micrometer-registry-prometheus</artifactId>
+    </dependency>
     <dependency>
       <groupId>io.micrometer</groupId>
       <artifactId>micrometer-registry-prometheus-simpleclient</artifactId>
     </dependency>
+    <dependency>
+      <groupId>io.prometheus</groupId>
+      <artifactId>prometheus-metrics-exporter-pushgateway</artifactId>
+    </dependency>
     <dependency>
       <groupId>io.prometheus</groupId>
       <artifactId>simpleclient_pushgateway</artifactId>
diff --git a/dubbo-metrics/dubbo-metrics-prometheus/src/main/java/org/apache/dubbo/metrics/prometheus/PrometheusMetricsReporter.java b/dubbo-metrics/dubbo-metrics-prometheus/src/main/java/org/apache/dubbo/metrics/prometheus/PrometheusMetricsReporter.java
index 96948e1531..8fef1cf582 100644
--- a/dubbo-metrics/dubbo-metrics-prometheus/src/main/java/org/apache/dubbo/metrics/prometheus/PrometheusMetricsReporter.java
+++ b/dubbo-metrics/dubbo-metrics-prometheus/src/main/java/org/apache/dubbo/metrics/prometheus/PrometheusMetricsReporter.java
@@ -22,6 +22,7 @@ import org.apache.dubbo.common.logger.LoggerFactory;
 import org.apache.dubbo.common.utils.NamedThreadFactory;
 import org.apache.dubbo.common.utils.StringUtils;
 import org.apache.dubbo.metrics.report.AbstractMetricsReporter;
+import org.apache.dubbo.metrics.utils.MetricsSupportUtil;
 import org.apache.dubbo.rpc.model.ApplicationModel;
 
 import java.io.IOException;
@@ -29,10 +30,7 @@ import java.util.concurrent.Executors;
 import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.TimeUnit;
 
-import io.micrometer.prometheus.PrometheusConfig;
-import io.micrometer.prometheus.PrometheusMeterRegistry;
-import io.prometheus.client.exporter.BasicAuthHttpConnectionFactory;
-import io.prometheus.client.exporter.PushGateway;
+import io.micrometer.core.instrument.MeterRegistry;
 
 import static org.apache.dubbo.common.constants.LoggerCodeConstants.COMMON_METRICS_COLLECTOR_EXCEPTION;
 import static org.apache.dubbo.common.constants.MetricsConstants.PROMETHEUS_DEFAULT_JOB_NAME;
@@ -51,21 +49,23 @@ public class PrometheusMetricsReporter extends AbstractMetricsReporter {
 
     private final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(PrometheusMetricsReporter.class);
 
-    private final PrometheusMeterRegistry prometheusRegistry = new PrometheusMeterRegistry(PrometheusConfig.DEFAULT);
+    private final PrometheusClientAdapter adapter;
     private ScheduledExecutorService pushJobExecutor = null;
 
     public PrometheusMetricsReporter(URL url, ApplicationModel applicationModel) {
         super(url, applicationModel);
+        this.adapter = createAdapter();
     }
 
     @Override
     public void doInit() {
-        addMeterRegistry(prometheusRegistry);
+        addMeterRegistry(adapter.getMeterRegistry());
         schedulePushJob();
     }
 
+    @Override
     public String getResponse() {
-        return prometheusRegistry.scrape();
+        return adapter.scrape();
     }
 
     private void schedulePushJob() {
@@ -80,9 +80,10 @@ public class PrometheusMetricsReporter extends AbstractMetricsReporter {
 
             NamedThreadFactory threadFactory = new NamedThreadFactory("prometheus-push-job", true);
             pushJobExecutor = Executors.newScheduledThreadPool(1, threadFactory);
-            PushGateway pushGateway = new PushGateway(baseUrl);
+
+            Object pushGateway = adapter.createPushGateway(baseUrl);
             if (!StringUtils.isBlank(username)) {
-                pushGateway.setConnectionFactory(new BasicAuthHttpConnectionFactory(username, password));
+                adapter.setBasicAuth(pushGateway, username, password);
             }
 
             pushJobExecutor.scheduleWithFixedDelay(
@@ -90,20 +91,6 @@ public class PrometheusMetricsReporter extends AbstractMetricsReporter {
         }
     }
 
-    protected void push(PushGateway pushGateway, String job) {
-        try {
-            resetIfSamplesChanged();
-            pushGateway.pushAdd(prometheusRegistry.getPrometheusRegistry(), job);
-        } catch (IOException e) {
-            logger.error(
-                    COMMON_METRICS_COLLECTOR_EXCEPTION,
-                    "",
-                    "",
-                    "Error occurred when pushing metrics to prometheus: ",
-                    e);
-        }
-    }
-
     @Override
     public void doDestroy() {
 
@@ -120,11 +107,155 @@ public class PrometheusMetricsReporter extends AbstractMetricsReporter {
         return pushJobExecutor;
     }
 
+    protected void push(Object pushGateway, String job) {
+        try {
+            resetIfSamplesChanged();
+            adapter.pushAdd(pushGateway, job);
+        } catch (IOException e) {
+            logger.error(
+                    COMMON_METRICS_COLLECTOR_EXCEPTION,
+                    "",
+                    "",
+                    "Error occurred when pushing metrics to prometheus: ",
+                    e);
+        }
+    }
+
     /**
      * ut only
      */
     @Deprecated
-    public PrometheusMeterRegistry getPrometheusRegistry() {
-        return prometheusRegistry;
+    public MeterRegistry getPrometheusRegistry() {
+        return adapter.getMeterRegistry();
+    }
+
+    private PrometheusClientAdapter createAdapter() {
+        PrometheusClientAdapter adapter = tryCreateNewPrometheusClientAdapter();
+        if (adapter != null) {
+            logger.info("Using new Prometheus client implementation.");
+            return adapter;
+        }
+        adapter = tryCreateLegacyPrometheusClientAdapter();
+        if (adapter != null) {
+            logger.info("Using legacy Prometheus client implementation.");
+            return adapter;
+        }
+        throw new IllegalStateException("No supported Prometheus client implementation found.");
+    }
+
+    private PrometheusClientAdapter tryCreateNewPrometheusClientAdapter() {
+        try {
+            if (NewPrometheusClientAdapter.isAvailable()) {
+                return new NewPrometheusClientAdapter();
+            }
+        } catch (NoClassDefFoundError ignored) {
+            // The new Prometheus stack is only partially present. Treat it as unavailable
+            // so that we can fall back to the legacy implementation or to NOP reporting.
+        }
+        return null;
+    }
+
+    private PrometheusClientAdapter tryCreateLegacyPrometheusClientAdapter() {
+        try {
+            if (LegacyPrometheusClientAdapter.isAvailable()) {
+                return new LegacyPrometheusClientAdapter();
+            }
+        } catch (NoClassDefFoundError ignored) {
+            // The legacy Prometheus stack is only partially present. Treat it as unavailable
+            // so that factory-level fallback can downgrade to a NOP reporter.
+        }
+        return null;
+    }
+
+    private interface PrometheusClientAdapter {
+
+        MeterRegistry getMeterRegistry();
+
+        String scrape();
+
+        Object createPushGateway(String baseUrl);
+
+        void setBasicAuth(Object pushGateway, String username, String password);
+
+        void pushAdd(Object pushGateway, String job) throws IOException;
+    }
+
+    private static class LegacyPrometheusClientAdapter implements PrometheusClientAdapter {
+
+        private final io.micrometer.prometheus.PrometheusMeterRegistry registry =
+                new io.micrometer.prometheus.PrometheusMeterRegistry(io.micrometer.prometheus.PrometheusConfig.DEFAULT);
+
+        static boolean isAvailable() {
+            return MetricsSupportUtil.isSupportLegacyPrometheus();
+        }
+
+        @Override
+        public MeterRegistry getMeterRegistry() {
+            return registry;
+        }
+
+        @Override
+        public String scrape() {
+            return registry.scrape();
+        }
+
+        @Override
+        public Object createPushGateway(String baseUrl) {
+            return new io.prometheus.client.exporter.PushGateway(baseUrl);
+        }
+
+        @Override
+        public void setBasicAuth(Object pushGateway, String username, String password) {
+            ((io.prometheus.client.exporter.PushGateway) pushGateway)
+                    .setConnectionFactory(
+                            new io.prometheus.client.exporter.BasicAuthHttpConnectionFactory(username, password));
+        }
+
+        @Override
+        public void pushAdd(Object pushGateway, String job) throws IOException {
+            ((io.prometheus.client.exporter.PushGateway) pushGateway).pushAdd(registry.getPrometheusRegistry(), job);
+        }
+    }
+
+    private static class NewPrometheusClientAdapter implements PrometheusClientAdapter {
+
+        private final io.micrometer.prometheusmetrics.PrometheusMeterRegistry registry =
+                new io.micrometer.prometheusmetrics.PrometheusMeterRegistry(
+                        io.micrometer.prometheusmetrics.PrometheusConfig.DEFAULT);
+
+        static boolean isAvailable() {
+            return MetricsSupportUtil.isSupportNewPrometheus();
+        }
+
+        @Override
+        public MeterRegistry getMeterRegistry() {
+            return registry;
+        }
+
+        @Override
+        public String scrape() {
+            return registry.scrape();
+        }
+
+        @Override
+        public Object createPushGateway(String baseUrl) {
+            return io.prometheus.metrics.exporter.pushgateway.PushGateway.builder()
+                    .registry(registry.getPrometheusRegistry())
+                    .address(baseUrl);
+        }
+
+        @Override
+        public void setBasicAuth(Object pushGateway, String username, String password) {
+            ((io.prometheus.metrics.exporter.pushgateway.PushGateway.Builder) pushGateway)
+                    .basicAuth(username, password);
+        }
+
+        @Override
+        public void pushAdd(Object pushGateway, String job) throws IOException {
+            ((io.prometheus.metrics.exporter.pushgateway.PushGateway.Builder) pushGateway)
+                    .job(job)
+                    .build()
+                    .pushAdd();
+        }
     }
 }
diff --git a/dubbo-metrics/dubbo-metrics-prometheus/src/main/java/org/apache/dubbo/metrics/prometheus/PrometheusMetricsReporterFactory.java b/dubbo-metrics/dubbo-metrics-prometheus/src/main/java/org/apache/dubbo/metrics/prometheus/PrometheusMetricsReporterFactory.java
index fcad830e1e..94d6665616 100644
--- a/dubbo-metrics/dubbo-metrics-prometheus/src/main/java/org/apache/dubbo/metrics/prometheus/PrometheusMetricsReporterFactory.java
+++ b/dubbo-metrics/dubbo-metrics-prometheus/src/main/java/org/apache/dubbo/metrics/prometheus/PrometheusMetricsReporterFactory.java
@@ -67,6 +67,9 @@ public class PrometheusMetricsReporterFactory extends AbstractMetricsReporterFac
                 logger.error(INTERNAL_ERROR, "", "", "Failed to instantiate PrometheusMetricsReporter", ncde);
                 throw ncde;
             }
+        } catch (IllegalStateException ise) {
+            logger.error(INTERNAL_ERROR, "", "", "Failed to initialize PrometheusMetricsReporter", ise);
+            return new NopPrometheusMetricsReporter();
         }
     }
 
@@ -77,6 +80,16 @@ public class PrometheusMetricsReporterFactory extends AbstractMetricsReporterFac
         if (msg.contains("io/micrometer/core/instrument/composite/CompositeMeterRegistry")) {
             return true;
         }
-        return msg.contains("io.micrometer.core.instrument.composite.CompositeMeterRegistry");
+        if (msg.contains("io.micrometer.core.instrument.composite.CompositeMeterRegistry")) {
+            return true;
+        }
+        return msg.contains("io/micrometer/prometheus/")
+                || msg.contains("io.micrometer.prometheus.")
+                || msg.contains("io/micrometer/prometheusmetrics/")
+                || msg.contains("io.micrometer.prometheusmetrics.")
+                || msg.contains("io/prometheus/client/exporter/")
+                || msg.contains("io.prometheus.client.exporter.")
+                || msg.contains("io/prometheus/metrics/exporter/pushgateway/")
+                || msg.contains("io.prometheus.metrics.exporter.pushgateway.");
     }
 }
diff --git a/dubbo-metrics/dubbo-metrics-prometheus/src/test/java/org/apache/dubbo/metrics/prometheus/PrometheusMetricsReporterTest.java b/dubbo-metrics/dubbo-metrics-prometheus/src/test/java/org/apache/dubbo/metrics/prometheus/PrometheusMetricsReporterTest.java
index e8198a3d05..8aa4fbb915 100644
--- a/dubbo-metrics/dubbo-metrics-prometheus/src/test/java/org/apache/dubbo/metrics/prometheus/PrometheusMetricsReporterTest.java
+++ b/dubbo-metrics/dubbo-metrics-prometheus/src/test/java/org/apache/dubbo/metrics/prometheus/PrometheusMetricsReporterTest.java
@@ -30,11 +30,14 @@ import java.io.InputStreamReader;
 import java.io.OutputStream;
 import java.net.InetSocketAddress;
 import java.nio.charset.StandardCharsets;
+import java.util.Base64;
+import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicReference;
 import java.util.stream.Collectors;
 
 import com.sun.net.httpserver.HttpServer;
-import io.micrometer.prometheus.PrometheusMeterRegistry;
 import org.apache.http.client.methods.CloseableHttpResponse;
 import org.apache.http.client.methods.HttpGet;
 import org.apache.http.impl.client.CloseableHttpClient;
@@ -79,14 +82,9 @@ class PrometheusMetricsReporterTest {
         PrometheusMetricsReporter reporter = new PrometheusMetricsReporter(metricsConfig.toUrl(), applicationModel);
         reporter.init();
 
-        PrometheusMeterRegistry prometheusRegistry = reporter.getPrometheusRegistry();
-        Double d1 = prometheusRegistry.getPrometheusRegistry().getSampleValue("none_exist_metric");
-        Double d2 = prometheusRegistry
-                .getPrometheusRegistry()
-                .getSampleValue(
-                        "jvm_gc_memory_promoted_bytes_total", new String[] {"application_name"}, new String[] {name});
-        Assertions.assertNull(d1);
-        Assertions.assertNull(d2);
+        String response = reporter.getResponse();
+        Assertions.assertNotNull(response);
+        Assertions.assertFalse(response.isEmpty());
     }
 
     @Test
@@ -147,13 +145,57 @@ class PrometheusMetricsReporterTest {
         Assertions.assertTrue(executor.isTerminated() || executor.isShutdown());
     }
 
+    @Test
+    void testPushgatewayUsesBasicAuthWithNewAdapter() throws Exception {
+        CountDownLatch requestReceived = new CountDownLatch(1);
+        AtomicReference<String> requestMethod = new AtomicReference<>();
+        AtomicReference<String> requestPath = new AtomicReference<>();
+        AtomicReference<String> authorization = new AtomicReference<>();
+        AtomicReference<String> requestBody = new AtomicReference<>();
+        String username = "demo";
+        String password = "secret";
+        String job = "auth-job";
+
+        prometheusExporterHttpServer = HttpServer.create(new InetSocketAddress(0), 0);
+        prometheusExporterHttpServer.createContext("/", httpExchange -> {
+            requestMethod.set(httpExchange.getRequestMethod());
+            requestPath.set(httpExchange.getRequestURI().getPath());
+            authorization.set(httpExchange.getRequestHeaders().getFirst("Authorization"));
+            try (InputStream inputStream = httpExchange.getRequestBody()) {
+                requestBody.set(new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8))
+                        .lines()
+                        .collect(Collectors.joining("\n")));
+            }
+            httpExchange.sendResponseHeaders(202, -1);
+            httpExchange.close();
+            requestReceived.countDown();
+        });
+        prometheusExporterHttpServer.start();
+
+        PrometheusMetricsReporter reporter = createPushgatewayReporter(
+                "localhost:" + prometheusExporterHttpServer.getAddress().getPort(), job, username, password);
+        try {
+            Assertions.assertEquals(
+                    "io.micrometer.prometheusmetrics.PrometheusMeterRegistry",
+                    reporter.getPrometheusRegistry().getClass().getName());
+
+            Assertions.assertTrue(requestReceived.await(10, TimeUnit.SECONDS));
+            Assertions.assertEquals("POST", requestMethod.get());
+            Assertions.assertEquals("/metrics/job/" + job, requestPath.get());
+            Assertions.assertEquals(basicAuthHeader(username, password), authorization.get());
+            Assertions.assertTrue(requestBody.get().contains("jvm_memory_used_bytes"));
+        } finally {
+            reporter.destroy();
+        }
+    }
+
     private void exportHttpServer(PrometheusMetricsReporter reporter, int port) {
 
         try {
             prometheusExporterHttpServer = HttpServer.create(new InetSocketAddress(port), 0);
             prometheusExporterHttpServer.createContext("/metrics", httpExchange -> {
                 reporter.resetIfSamplesChanged();
-                String response = reporter.getPrometheusRegistry().scrape();
+                String response = reporter.getResponse();
                 httpExchange.sendResponseHeaders(200, response.getBytes().length);
                 try (OutputStream os = httpExchange.getResponseBody()) {
                     os.write(response.getBytes());
@@ -166,4 +208,30 @@ class PrometheusMetricsReporterTest {
             throw new RuntimeException(e);
         }
     }
+
+    private PrometheusMetricsReporter createPushgatewayReporter(
+            String baseUrl, String job, String username, String password) {
+        metricsConfig.setEnableJvm(true);
+        applicationModel.getApplicationConfigManager().setApplication(new ApplicationConfig("metrics-test"));
+
+        PrometheusConfig prometheusConfig = new PrometheusConfig();
+        PrometheusConfig.Pushgateway pushgateway = new PrometheusConfig.Pushgateway();
+        pushgateway.setEnabled(true);
+        pushgateway.setBaseUrl(baseUrl);
+        pushgateway.setJob(job);
+        pushgateway.setPushInterval(1);
+        pushgateway.setUsername(username);
+        pushgateway.setPassword(password);
+        prometheusConfig.setPushgateway(pushgateway);
+        metricsConfig.setPrometheus(prometheusConfig);
+
+        PrometheusMetricsReporter reporter = new PrometheusMetricsReporter(metricsConfig.toUrl(), applicationModel);
+        reporter.init();
+        return reporter;
+    }
+
+    private String basicAuthHeader(String username, String password) {
+        String credentials = username + ":" + password;
+        return "Basic " + Base64.getEncoder().encodeToString(credentials.getBytes(StandardCharsets.UTF_8));
+    }
 }
diff --git a/dubbo-metrics/dubbo-metrics-prometheus/src/test/java/org/apache/dubbo/metrics/prometheus/PrometheusMetricsThreadPoolTest.java b/dubbo-metrics/dubbo-metrics-prometheus/src/test/java/org/apache/dubbo/metrics/prometheus/PrometheusMetricsThreadPoolTest.java
index 2727b34980..64fb0ad065 100644
--- a/dubbo-metrics/dubbo-metrics-prometheus/src/test/java/org/apache/dubbo/metrics/prometheus/PrometheusMetricsThreadPoolTest.java
+++ b/dubbo-metrics/dubbo-metrics-prometheus/src/test/java/org/apache/dubbo/metrics/prometheus/PrometheusMetricsThreadPoolTest.java
@@ -124,7 +124,7 @@ public class PrometheusMetricsThreadPoolTest {
             prometheusExporterHttpServer = HttpServer.create(new InetSocketAddress(port), 0);
             prometheusExporterHttpServer.createContext("/metrics", httpExchange -> {
                 reporter.resetIfSamplesChanged();
-                String response = reporter.getPrometheusRegistry().scrape();
+                String response = reporter.getResponse();
                 httpExchange.sendResponseHeaders(200, response.getBytes().length);
                 try (OutputStream os = httpExchange.getResponseBody()) {
                     os.write(response.getBytes());
diff --git a/dubbo-spring-boot-project/dubbo-spring-boot-autoconfigure/pom.xml b/dubbo-spring-boot-project/dubbo-spring-boot-autoconfigure/pom.xml
index 45e6e4a3b6..6b98ad0501 100644
--- a/dubbo-spring-boot-project/dubbo-spring-boot-autoconfigure/pom.xml
+++ b/dubbo-spring-boot-project/dubbo-spring-boot-autoconfigure/pom.xml
@@ -128,6 +128,17 @@
       <artifactId>micrometer-core</artifactId>
       <scope>provided</scope>
     </dependency>
+    <dependency>
+      <groupId>io.micrometer</groupId>
+      <artifactId>micrometer-registry-prometheus</artifactId>
+      <scope>provided</scope>
+      <exclusions>
+        <exclusion>
+          <groupId>io.micrometer</groupId>
+          <artifactId>micrometer-core</artifactId>
+        </exclusion>
+      </exclusions>
+    </dependency>
     <dependency>
       <groupId>io.micrometer</groupId>
       <artifactId>micrometer-registry-prometheus-simpleclient</artifactId>
@@ -151,6 +162,11 @@
       <artifactId>simpleclient</artifactId>
       <scope>provided</scope>
     </dependency>
+    <dependency>
+      <groupId>io.prometheus</groupId>
+      <artifactId>prometheus-metrics-exporter-pushgateway</artifactId>
+      <scope>provided</scope>
+    </dependency>
     <dependency>
       <groupId>io.prometheus</groupId>
       <artifactId>simpleclient_pushgateway</artifactId>