From f1957dda881e60aa6954a019707e1e4000e4dcac Mon Sep 17 00:00:00 2001 From: furaul Date: Fri, 15 Sep 2023 23:45:52 +0800 Subject: [PATCH] Added Undertow thread pool parameters (#1464) --- .../api/BootstrapPropertiesInterface.java | 2 +- .../WebThreadPoolHandlerConfiguration.java | 4 +- .../WebThreadPoolHandlerConfiguration1x.java | 4 +- .../UndertowWebThreadPoolHandler1x.java | 5 +- .../DefaultUndertowWebThreadPoolHandler.java | 5 +- .../UndertowWebThreadPoolHandlerSupport.java | 61 ++++++++++++++++++- 6 files changed, 69 insertions(+), 12 deletions(-) diff --git a/kernel/dynamic/api/src/main/java/cn/hippo4j/threadpool/dynamic/api/BootstrapPropertiesInterface.java b/kernel/dynamic/api/src/main/java/cn/hippo4j/threadpool/dynamic/api/BootstrapPropertiesInterface.java index 2f47e414..110c3f5e 100644 --- a/kernel/dynamic/api/src/main/java/cn/hippo4j/threadpool/dynamic/api/BootstrapPropertiesInterface.java +++ b/kernel/dynamic/api/src/main/java/cn/hippo4j/threadpool/dynamic/api/BootstrapPropertiesInterface.java @@ -90,7 +90,7 @@ public interface BootstrapPropertiesInterface { /** * Get apollo. */ - default Map getApollo(){ + default Map getApollo() { return null; } diff --git a/starters/threadpool/adapter/web/src/main/java/cn/hippo4j/springboot/starter/adapter/web/WebThreadPoolHandlerConfiguration.java b/starters/threadpool/adapter/web/src/main/java/cn/hippo4j/springboot/starter/adapter/web/WebThreadPoolHandlerConfiguration.java index 7dd86213..263317f7 100644 --- a/starters/threadpool/adapter/web/src/main/java/cn/hippo4j/springboot/starter/adapter/web/WebThreadPoolHandlerConfiguration.java +++ b/starters/threadpool/adapter/web/src/main/java/cn/hippo4j/springboot/starter/adapter/web/WebThreadPoolHandlerConfiguration.java @@ -105,8 +105,8 @@ public class WebThreadPoolHandlerConfiguration { * the Web embedded server loads the {@link ServletWebServerFactory} top-level interface type at the same time */ @Bean - public UndertowWebThreadPoolHandlerAdapt undertowWebThreadPoolHandler() { - return new DefaultUndertowWebThreadPoolHandler(); + public UndertowWebThreadPoolHandlerAdapt undertowWebThreadPoolHandler(WebThreadPoolRunStateHandler webThreadPoolRunStateHandler) { + return new DefaultUndertowWebThreadPoolHandler(webThreadPoolRunStateHandler); } } } diff --git a/starters/threadpool/config-spring-boot-1x/src/main/java/cn/hippo4j/config/springboot1x/starter/config/WebThreadPoolHandlerConfiguration1x.java b/starters/threadpool/config-spring-boot-1x/src/main/java/cn/hippo4j/config/springboot1x/starter/config/WebThreadPoolHandlerConfiguration1x.java index 80df456a..fa41e3f1 100644 --- a/starters/threadpool/config-spring-boot-1x/src/main/java/cn/hippo4j/config/springboot1x/starter/config/WebThreadPoolHandlerConfiguration1x.java +++ b/starters/threadpool/config-spring-boot-1x/src/main/java/cn/hippo4j/config/springboot1x/starter/config/WebThreadPoolHandlerConfiguration1x.java @@ -89,8 +89,8 @@ public class WebThreadPoolHandlerConfiguration1x { static class EmbeddedUndertow { @Bean - public WebThreadPoolService undertowWebThreadPoolHandler() { - return new UndertowWebThreadPoolHandler1x(); + public WebThreadPoolService undertowWebThreadPoolHandler(WebThreadPoolRunStateHandler webThreadPoolRunStateHandler) { + return new UndertowWebThreadPoolHandler1x(webThreadPoolRunStateHandler); } } } diff --git a/starters/threadpool/config-spring-boot-1x/src/main/java/cn/hippo4j/config/springboot1x/starter/web/undertow/UndertowWebThreadPoolHandler1x.java b/starters/threadpool/config-spring-boot-1x/src/main/java/cn/hippo4j/config/springboot1x/starter/web/undertow/UndertowWebThreadPoolHandler1x.java index 53e34907..4d10a79d 100644 --- a/starters/threadpool/config-spring-boot-1x/src/main/java/cn/hippo4j/config/springboot1x/starter/web/undertow/UndertowWebThreadPoolHandler1x.java +++ b/starters/threadpool/config-spring-boot-1x/src/main/java/cn/hippo4j/config/springboot1x/starter/web/undertow/UndertowWebThreadPoolHandler1x.java @@ -18,6 +18,7 @@ package cn.hippo4j.config.springboot1x.starter.web.undertow; import cn.hippo4j.adapter.web.undertow.UndertowWebThreadPoolHandlerSupport; +import cn.hippo4j.common.support.AbstractThreadPoolRuntime; import cn.hippo4j.config.springboot1x.starter.web.AbstractWebThreadPoolService1x; import io.undertow.Undertow; import lombok.extern.slf4j.Slf4j; @@ -35,8 +36,8 @@ public class UndertowWebThreadPoolHandler1x extends AbstractWebThreadPoolService private static final String UNDERTOW_NAME = "undertow"; - public UndertowWebThreadPoolHandler1x() { - super(new UndertowWebThreadPoolHandlerSupport()); + public UndertowWebThreadPoolHandler1x(AbstractThreadPoolRuntime runtime) { + super(new UndertowWebThreadPoolHandlerSupport(runtime)); } @Override diff --git a/threadpool/adapter/web/src/main/java/cn/hippo4j/adapter/web/undertow/DefaultUndertowWebThreadPoolHandler.java b/threadpool/adapter/web/src/main/java/cn/hippo4j/adapter/web/undertow/DefaultUndertowWebThreadPoolHandler.java index 5b2f81ae..78fe89da 100644 --- a/threadpool/adapter/web/src/main/java/cn/hippo4j/adapter/web/undertow/DefaultUndertowWebThreadPoolHandler.java +++ b/threadpool/adapter/web/src/main/java/cn/hippo4j/adapter/web/undertow/DefaultUndertowWebThreadPoolHandler.java @@ -22,6 +22,7 @@ import java.util.Objects; import java.util.concurrent.Executor; import cn.hippo4j.adapter.web.DefaultAbstractWebThreadPoolService; +import cn.hippo4j.common.support.AbstractThreadPoolRuntime; import io.undertow.Undertow; import lombok.extern.slf4j.Slf4j; @@ -39,8 +40,8 @@ public class DefaultUndertowWebThreadPoolHandler extends DefaultAbstractWebThrea private static final String UNDERTOW_NAME = "undertow"; - public DefaultUndertowWebThreadPoolHandler() { - super(new UndertowWebThreadPoolHandlerSupport()); + public DefaultUndertowWebThreadPoolHandler(AbstractThreadPoolRuntime runtime) { + super(new UndertowWebThreadPoolHandlerSupport(runtime)); } /** diff --git a/threadpool/adapter/web/src/main/java/cn/hippo4j/adapter/web/undertow/UndertowWebThreadPoolHandlerSupport.java b/threadpool/adapter/web/src/main/java/cn/hippo4j/adapter/web/undertow/UndertowWebThreadPoolHandlerSupport.java index 2d3d3c06..d22d0c91 100644 --- a/threadpool/adapter/web/src/main/java/cn/hippo4j/adapter/web/undertow/UndertowWebThreadPoolHandlerSupport.java +++ b/threadpool/adapter/web/src/main/java/cn/hippo4j/adapter/web/undertow/UndertowWebThreadPoolHandlerSupport.java @@ -24,9 +24,12 @@ import cn.hippo4j.common.model.ThreadPoolBaseInfo; import cn.hippo4j.common.model.ThreadPoolParameter; import cn.hippo4j.common.model.ThreadPoolParameterInfo; import cn.hippo4j.common.model.ThreadPoolRunStateInfo; +import cn.hippo4j.common.support.AbstractThreadPoolRuntime; import cn.hippo4j.common.toolkit.CalculateUtil; +import cn.hippo4j.common.toolkit.ReflectUtil; import cn.hippo4j.core.executor.DynamicThreadPoolExecutor; import lombok.extern.slf4j.Slf4j; +import org.jboss.threads.EnhancedQueueExecutor; import org.springframework.util.ReflectionUtils; import org.xnio.Options; import org.xnio.XnioWorker; @@ -44,8 +47,14 @@ import java.util.concurrent.Executor; @Slf4j public class UndertowWebThreadPoolHandlerSupport implements IWebThreadPoolHandlerSupport { + private final AbstractThreadPoolRuntime runtime; + private Executor executor; + public UndertowWebThreadPoolHandlerSupport(AbstractThreadPoolRuntime runtime) { + this.runtime = runtime; + } + /** * A callback will be invoked and the Executor will be set up when the web container has been started. * @param executor Thread-pool executor in Undertow container. @@ -56,6 +65,7 @@ public class UndertowWebThreadPoolHandlerSupport implements IWebThreadPoolHandle } private final long noRejectCount = -1L; + @Override public ThreadPoolBaseInfo simpleInfo() { ThreadPoolBaseInfo poolBaseInfo = new ThreadPoolBaseInfo(); @@ -67,8 +77,17 @@ public class UndertowWebThreadPoolHandlerSupport implements IWebThreadPoolHandle poolBaseInfo.setCoreSize(coreSize); poolBaseInfo.setMaximumSize(maximumPoolSize); poolBaseInfo.setKeepAliveTime((long) keepAliveTime); - poolBaseInfo.setRejectedName("-"); - poolBaseInfo.setQueueType("-"); + poolBaseInfo.setRejectedName("RejectedExecutionException"); + poolBaseInfo.setQueueType("org.jboss.threads.EnhancedQueueExecutor.TaskNode:FIFO"); + + EnhancedQueueExecutor enhancedQueueExecutor = + (EnhancedQueueExecutor) ReflectUtil.getFieldValue( + ReflectUtil.getFieldValue(xnioWorker, "taskPool"), "executor"); + + Method getMaximumQueueSize = ReflectionUtils.findMethod(enhancedQueueExecutor.getClass(), "getMaximumQueueSize"); + ReflectionUtils.makeAccessible(getMaximumQueueSize); + int queueCapacity = (int) ReflectionUtils.invokeMethod(getMaximumQueueSize, enhancedQueueExecutor); + poolBaseInfo.setQueueCapacity(queueCapacity); } catch (Exception ex) { log.error("The undertow container failed to get thread pool parameters.", ex); } @@ -112,6 +131,33 @@ public class UndertowWebThreadPoolHandlerSupport implements IWebThreadPoolHandle Method getActiveCount = ReflectionUtils.findMethod(fieldObject.getClass(), "getActiveCount"); ReflectionUtils.makeAccessible(getActiveCount); int activeCount = (int) ReflectionUtils.invokeMethod(getActiveCount, fieldObject); + + Field executorFiled = ReflectionUtils.findField(fieldObject.getClass(), "executor"); + ReflectionUtils.makeAccessible(executorFiled); + EnhancedQueueExecutor enhancedQueueExecutor = (EnhancedQueueExecutor) ReflectionUtils.getField(executorFiled, fieldObject); + + Method getLargestPoolSize = ReflectionUtils.findMethod(enhancedQueueExecutor.getClass(), "getLargestPoolSize"); + ReflectionUtils.makeAccessible(getLargestPoolSize); + int largestPoolSize = (int) ReflectionUtils.invokeMethod(getLargestPoolSize, enhancedQueueExecutor); + + Method getQueueSize = ReflectionUtils.findMethod(enhancedQueueExecutor.getClass(), "getQueueSize"); + ReflectionUtils.makeAccessible(getQueueSize); + int queueSize = (int) ReflectionUtils.invokeMethod(getQueueSize, enhancedQueueExecutor); + + Method getMaximumQueueSize = ReflectionUtils.findMethod(enhancedQueueExecutor.getClass(), "getMaximumQueueSize"); + ReflectionUtils.makeAccessible(getMaximumQueueSize); + int queueCapacity = (int) ReflectionUtils.invokeMethod(getMaximumQueueSize, enhancedQueueExecutor); + + int remainingCapacity = queueCapacity - queueSize; + + Method getCompletedTaskCount = ReflectionUtils.findMethod(enhancedQueueExecutor.getClass(), "getCompletedTaskCount"); + ReflectionUtils.makeAccessible(getCompletedTaskCount); + long completedTaskCount = (long) ReflectionUtils.invokeMethod(getCompletedTaskCount, enhancedQueueExecutor); + + Method getHandoffExecutor = ReflectionUtils.findMethod(enhancedQueueExecutor.getClass(), "getHandoffExecutor"); + ReflectionUtils.makeAccessible(getHandoffExecutor); + Executor handoffExecutor = (Executor) ReflectionUtils.invokeMethod(getHandoffExecutor, enhancedQueueExecutor); + activeCount = Math.max(activeCount, 0); String currentLoad = CalculateUtil.divide(activeCount, maximumPoolSize) + ""; String peakLoad = CalculateUtil.divide(activeCount, maximumPoolSize) + ""; @@ -127,7 +173,16 @@ public class UndertowWebThreadPoolHandlerSupport implements IWebThreadPoolHandle stateInfo.setRejectCount(rejectCount); stateInfo.setClientLastRefreshTime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))); stateInfo.setTimestamp(System.currentTimeMillis()); - return stateInfo; + + stateInfo.setQueueType("org.jboss.threads.EnhancedQueueExecutor.TaskNode:FIFO"); + stateInfo.setQueueSize(queueSize); + stateInfo.setQueueCapacity(queueCapacity); + stateInfo.setQueueRemainingCapacity(remainingCapacity); + stateInfo.setLargestPoolSize(largestPoolSize); + stateInfo.setCompletedTaskCount(completedTaskCount); + stateInfo.setRejectedName(handoffExecutor.getClass().getName()); + + return runtime.supplement(stateInfo); } @Override