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

Hexiaoqiao pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/hadoop.git


The following commit(s) were added to refs/heads/trunk by this push:
     new 9ec39013e57 HADOOP-19905. Implement HttpServer2 thread pool metrics. 
(#8520). Contributed by KWON BYUNGCHANG.
9ec39013e57 is described below

commit 9ec39013e57cafe87bd80f4e2fd945d982b61c63
Author: KwonByungchang <[email protected]>
AuthorDate: Thu Jul 2 13:50:37 2026 +0900

    HADOOP-19905. Implement HttpServer2 thread pool metrics. (#8520). 
Contributed by KWON BYUNGCHANG.
    
    Reviewed-by: K0K0V0K <[email protected]>
    Signed-off-by: He Xiaoqiao <[email protected]>
---
 .../java/org/apache/hadoop/http/HttpServer2.java   | 13 +++--
 .../org/apache/hadoop/http/HttpServer2Metrics.java | 60 ++++++++++++++++++++--
 .../org/apache/hadoop/http/TestHttpServer.java     | 32 ++++++++++++
 3 files changed, 99 insertions(+), 6 deletions(-)

diff --git 
a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/http/HttpServer2.java
 
b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/http/HttpServer2.java
index 1ec9e8f6332..d17874d78ac 100644
--- 
a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/http/HttpServer2.java
+++ 
b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/http/HttpServer2.java
@@ -1448,11 +1448,18 @@ public void start() throws IOException {
           // Create metrics source for each HttpServer2 instance.
           // Use port number to make the metrics source name unique.
           int port = -1;
+          int acceptorThreads = 0;
+          int selectorThreads = 0;
           for (ServerConnector connector : listeners) {
-            port = connector.getLocalPort();
-            break;
+            if (port == -1) {
+              port = connector.getLocalPort();
+            }
+            acceptorThreads += connector.getAcceptors();
+            selectorThreads += 
connector.getSelectorManager().getSelectorCount();
           }
-          metrics = HttpServer2Metrics.create(statsHandler, port);
+          metrics = HttpServer2Metrics.create(statsHandler, port,
+              (QueuedThreadPool) webServer.getThreadPool(),
+              acceptorThreads, selectorThreads);
         }
       } catch (IOException ex) {
         LOG.info("HttpServer.start() threw a non Bind IOException", ex);
diff --git 
a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/http/HttpServer2Metrics.java
 
b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/http/HttpServer2Metrics.java
index 7a74e7be3f7..f99476fc4d1 100644
--- 
a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/http/HttpServer2Metrics.java
+++ 
b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/http/HttpServer2Metrics.java
@@ -18,6 +18,7 @@
 package org.apache.hadoop.http;
 
 import org.eclipse.jetty.server.handler.StatisticsHandler;
+import org.eclipse.jetty.util.thread.QueuedThreadPool;
 
 import org.apache.hadoop.classification.InterfaceAudience;
 import org.apache.hadoop.classification.InterfaceStability;
@@ -37,6 +38,9 @@ public class HttpServer2Metrics {
 
   private final StatisticsHandler handler;
   private final int port;
+  private final QueuedThreadPool threadPool;
+  private final int acceptorThreads;
+  private final int selectorThreads;
 
   @Metric("number of requested that have been asynchronously dispatched")
   public int asyncDispatches() {
@@ -142,15 +146,65 @@ public long responsesBytesTotal() {
   public long statsOnMs() {
     return handler.getStatsOnMs();
   }
+  @Metric("maximum number of threads in the pool")
+  public int maxThreads() {
+    return threadPool.getMaxThreads();
+  }
+  @Metric("number of idle threads in the pool")
+  public int idleThreads() {
+    return threadPool.getIdleThreads();
+  }
+  @Metric("number of busy threads in the pool")
+  public int busyThreads() {
+    return threadPool.getBusyThreads();
+  }
+  @Metric("number of threads in the pool")
+  public int threads() {
+    return threadPool.getThreads();
+  }
+  @Metric("minimum number of threads in the pool")
+  public int minThreads() {
+    return threadPool.getMinThreads();
+  }
+  @Metric("size of the job queue")
+  public int queueSize() {
+    return threadPool.getQueueSize();
+  }
+  @Metric("number of acceptor threads across all connectors")
+  public int acceptorThreads() {
+    return acceptorThreads;
+  }
+  @Metric("number of selector threads across all connectors")
+  public int selectorThreads() {
+    return selectorThreads;
+  }
+  @Metric("maximum number of worker threads in the pool")
+  public int maxWorkerThreads() {
+    return threadPool.getMaxThreads() - acceptorThreads - selectorThreads;
+  }
+  @Metric("number of busy worker threads in the pool")
+  public int busyWorkerThreads() {
+    return threadPool.getBusyThreads() - acceptorThreads - selectorThreads;
+  }
+  @Metric("number of worker threads in the pool")
+  public int workerThreads() {
+    return threadPool.getThreads() - acceptorThreads - selectorThreads;
+  }
 
-  HttpServer2Metrics(StatisticsHandler handler, int port) {
+  HttpServer2Metrics(StatisticsHandler handler, int port,
+      QueuedThreadPool threadPool, int acceptorThreads, int selectorThreads) {
     this.handler = handler;
     this.port = port;
+    this.threadPool = threadPool;
+    this.acceptorThreads = acceptorThreads;
+    this.selectorThreads = selectorThreads;
   }
 
-  static HttpServer2Metrics create(StatisticsHandler handler, int port) {
+  static HttpServer2Metrics create(StatisticsHandler handler, int port,
+      QueuedThreadPool threadPool, int acceptorThreads, int selectorThreads) {
     final MetricsSystem ms = DefaultMetricsSystem.instance();
-    final HttpServer2Metrics metrics = new HttpServer2Metrics(handler, port);
+    final HttpServer2Metrics metrics = new HttpServer2Metrics(handler, port,
+        threadPool, acceptorThreads, selectorThreads);
     // Remove the old metrics from metrics system to avoid duplicate error
     // when HttpServer2 is started twice.
     metrics.remove();
diff --git 
a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/http/TestHttpServer.java
 
b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/http/TestHttpServer.java
index ed57a1241fb..e4e0bd30f92 100644
--- 
a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/http/TestHttpServer.java
+++ 
b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/http/TestHttpServer.java
@@ -289,6 +289,38 @@ public void testHttpServer2Metrics() throws Exception {
     assertThat(after).isGreaterThan(before);
   }
 
+  @Test
+  public void testHttpServer2ThreadPoolMetrics() throws Exception {
+    final int maxThreads = 32;
+    final int acceptorCount = 2;
+    final int selectorCount = 4;
+    final Configuration conf = new Configuration();
+    conf.setInt(HttpServer2.HTTP_MAX_THREADS_KEY, maxThreads);
+    conf.setInt(HttpServer2.HTTP_ACCEPTOR_COUNT_KEY, acceptorCount);
+    conf.setInt(HttpServer2.HTTP_SELECTOR_COUNT_KEY, selectorCount);
+    conf.setBoolean(
+        CommonConfigurationKeysPublic.HADOOP_HTTP_METRICS_ENABLED, true);
+    final HttpServer2 testServer = createTestServer(conf);
+    try {
+      testServer.start();
+      final HttpServer2Metrics metrics = testServer.getMetrics();
+
+      assertThat(metrics.maxThreads()).isEqualTo(maxThreads);
+      assertThat(metrics.acceptorThreads()).isEqualTo(acceptorCount);
+      assertThat(metrics.selectorThreads()).isEqualTo(selectorCount);
+
+      // Worker gauges are defined as the pool counts minus 
acceptors+selectors.
+      assertThat(metrics.maxWorkerThreads())
+          .isEqualTo(maxThreads - acceptorCount - selectorCount);
+      assertThat(metrics.workerThreads())
+          .isEqualTo(metrics.threads() - acceptorCount - selectorCount);
+      assertThat(metrics.busyWorkerThreads())
+          .isEqualTo(metrics.busyThreads() - acceptorCount - selectorCount);
+    } finally {
+      testServer.stop();
+    }
+  }
+
   /**
    * Jetty StatisticsHandler must be inserted via Server#insertHandler
    * instead of Server#setHandler. The server fails to start if


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to