Adapt to higher version Tomcat thread pool (#260)

pull/275/head
chen.ma 3 years ago
parent 2651fcc2f5
commit 70b91313f5

@ -35,24 +35,28 @@
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-core</artifactId>
<version>${tomcat-embed-core.version}</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>compile</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
<scope>compile</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-undertow</artifactId>
<scope>compile</scope>
<optional>true</optional>
</dependency>
</dependencies>

@ -43,7 +43,7 @@ public abstract class AbstractThreadPoolRuntime {
* @param threadPoolRunStateInfo
* @return
*/
protected abstract ThreadPoolRunStateInfo supplement(ThreadPoolRunStateInfo threadPoolRunStateInfo);
public abstract ThreadPoolRunStateInfo supplement(ThreadPoolRunStateInfo threadPoolRunStateInfo);
/**
* Get pool run state.

@ -51,7 +51,7 @@ public class ThreadPoolRunStateHandler extends AbstractThreadPoolRuntime {
private final ConfigurableEnvironment environment;
@Override
protected ThreadPoolRunStateInfo supplement(ThreadPoolRunStateInfo poolRunStateInfo) {
public ThreadPoolRunStateInfo supplement(ThreadPoolRunStateInfo poolRunStateInfo) {
RuntimeInfo runtimeInfo = new RuntimeInfo();
String memoryProportion = StrUtil.builder(
"已分配: ",

@ -22,11 +22,14 @@ import cn.hippo4j.common.model.ThreadPoolParameter;
import cn.hippo4j.common.model.ThreadPoolParameterInfo;
import cn.hippo4j.common.model.ThreadPoolRunStateInfo;
import cn.hippo4j.core.executor.state.AbstractThreadPoolRuntime;
import cn.hippo4j.core.toolkit.CalculateUtil;
import cn.hutool.core.date.DateUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.web.embedded.tomcat.TomcatWebServer;
import org.springframework.boot.web.server.WebServer;
import java.util.Date;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicBoolean;
@ -68,36 +71,58 @@ public class TomcatWebThreadPoolHandler extends AbstractWebThreadPoolService {
@Override
public ThreadPoolBaseInfo simpleInfo() {
ThreadPoolBaseInfo poolBaseInfo = new ThreadPoolBaseInfo();
ThreadPoolExecutor threadPoolExecutor = (ThreadPoolExecutor) executor;
int corePoolSize = threadPoolExecutor.getCorePoolSize();
int maximumPoolSize = threadPoolExecutor.getMaximumPoolSize();
RejectedExecutionHandler rejectedExecutionHandler = threadPoolExecutor.getRejectedExecutionHandler();
long keepAliveTime = threadPoolExecutor.getKeepAliveTime(TimeUnit.SECONDS);
BlockingQueue<Runnable> queue = threadPoolExecutor.getQueue();
int queueSize = queue.size();
int remainingCapacity = queue.remainingCapacity();
int queueCapacity = queueSize + remainingCapacity;
int corePoolSize, maximumPoolSize, queueCapacity;
long keepAliveTime;
String rejectedExecutionHandlerName;
BlockingQueue<Runnable> blockingQueue;
if (executor instanceof ThreadPoolExecutor) {
ThreadPoolExecutor threadPoolExecutor = (ThreadPoolExecutor) executor;
corePoolSize = threadPoolExecutor.getCorePoolSize();
maximumPoolSize = threadPoolExecutor.getMaximumPoolSize();
keepAliveTime = threadPoolExecutor.getKeepAliveTime(TimeUnit.SECONDS);
blockingQueue = threadPoolExecutor.getQueue();
int queueSize = blockingQueue.size();
int remainingCapacity = blockingQueue.remainingCapacity();
queueCapacity = queueSize + remainingCapacity;
RejectedExecutionHandler rejectedExecutionHandler = threadPoolExecutor.getRejectedExecutionHandler();
rejectedExecutionHandlerName = rejectedExecutionHandler.getClass().getSimpleName();
} else {
org.apache.tomcat.util.threads.ThreadPoolExecutor tomcatThreadPoolExecutor = (org.apache.tomcat.util.threads.ThreadPoolExecutor) executor;
corePoolSize = tomcatThreadPoolExecutor.getCorePoolSize();
maximumPoolSize = tomcatThreadPoolExecutor.getMaximumPoolSize();
keepAliveTime = tomcatThreadPoolExecutor.getKeepAliveTime(TimeUnit.SECONDS);
blockingQueue = tomcatThreadPoolExecutor.getQueue();
int queueSize = blockingQueue.size();
int remainingCapacity = blockingQueue.remainingCapacity();
queueCapacity = queueSize + remainingCapacity;
rejectedExecutionHandlerName = tomcatThreadPoolExecutor.getRejectedExecutionHandler().getClass().getSimpleName();
}
poolBaseInfo.setCoreSize(corePoolSize);
poolBaseInfo.setMaximumSize(maximumPoolSize);
poolBaseInfo.setKeepAliveTime(keepAliveTime);
poolBaseInfo.setQueueType(queue.getClass().getSimpleName());
poolBaseInfo.setQueueType(blockingQueue.getClass().getSimpleName());
poolBaseInfo.setQueueCapacity(queueCapacity);
poolBaseInfo.setRejectedName(rejectedExecutionHandler.getClass().getSimpleName());
poolBaseInfo.setRejectedName(rejectedExecutionHandlerName);
return poolBaseInfo;
}
@Override
public ThreadPoolParameter getWebThreadPoolParameter() {
ThreadPoolParameterInfo parameterInfo = null;
ThreadPoolParameterInfo parameterInfo = new ThreadPoolParameterInfo();
int minThreads, maxThreads;
long keepAliveTime;
try {
parameterInfo = new ThreadPoolParameterInfo();
ThreadPoolExecutor tomcatExecutor = (ThreadPoolExecutor) executor;
int minThreads = tomcatExecutor.getCorePoolSize();
int maxThreads = tomcatExecutor.getMaximumPoolSize();
long keepAliveTime = tomcatExecutor.getKeepAliveTime(TimeUnit.SECONDS);
if (executor instanceof ThreadPoolExecutor) {
ThreadPoolExecutor tomcatExecutor = (ThreadPoolExecutor) executor;
minThreads = tomcatExecutor.getCorePoolSize();
maxThreads = tomcatExecutor.getMaximumPoolSize();
keepAliveTime = tomcatExecutor.getKeepAliveTime(TimeUnit.SECONDS);
} else {
org.apache.tomcat.util.threads.ThreadPoolExecutor tomcatThreadPoolExecutor = (org.apache.tomcat.util.threads.ThreadPoolExecutor) executor;
minThreads = tomcatThreadPoolExecutor.getCorePoolSize();
maxThreads = tomcatThreadPoolExecutor.getMaximumPoolSize();
keepAliveTime = tomcatThreadPoolExecutor.getKeepAliveTime(TimeUnit.SECONDS);
}
parameterInfo.setCoreSize(minThreads);
parameterInfo.setMaxSize(maxThreads);
parameterInfo.setKeepAliveTime((int) keepAliveTime);
@ -109,19 +134,75 @@ public class TomcatWebThreadPoolHandler extends AbstractWebThreadPoolService {
@Override
public ThreadPoolRunStateInfo getWebRunStateInfo() {
return webThreadPoolRunStateHandler.getPoolRunState(null, executor);
if (executor instanceof ThreadPoolExecutor) {
return webThreadPoolRunStateHandler.getPoolRunState(null, executor);
}
ThreadPoolRunStateInfo runStateInfo = new ThreadPoolRunStateInfo();
org.apache.tomcat.util.threads.ThreadPoolExecutor tomcatThreadPoolExecutor = (org.apache.tomcat.util.threads.ThreadPoolExecutor) executor;
// 核心线程数
int corePoolSize = tomcatThreadPoolExecutor.getCorePoolSize();
// 最大线程数
int maximumPoolSize = tomcatThreadPoolExecutor.getMaximumPoolSize();
// 线程池当前线程数 (有锁)
int poolSize = tomcatThreadPoolExecutor.getPoolSize();
// 活跃线程数 (有锁)
int activeCount = tomcatThreadPoolExecutor.getActiveCount();
// 同时进入池中的最大线程数 (有锁)
int largestPoolSize = tomcatThreadPoolExecutor.getLargestPoolSize();
// 线程池中执行任务总数量 (有锁)
long completedTaskCount = tomcatThreadPoolExecutor.getCompletedTaskCount();
// 当前负载
String currentLoad = CalculateUtil.divide(activeCount, maximumPoolSize) + "";
// 峰值负载
String peakLoad = CalculateUtil.divide(largestPoolSize, maximumPoolSize) + "";
BlockingQueue<Runnable> queue = tomcatThreadPoolExecutor.getQueue();
// 队列元素个数
int queueSize = queue.size();
// 队列类型
String queueType = queue.getClass().getSimpleName();
// 队列剩余容量
int remainingCapacity = queue.remainingCapacity();
// 队列容量
int queueCapacity = queueSize + remainingCapacity;
runStateInfo.setCoreSize(corePoolSize);
runStateInfo.setPoolSize(poolSize);
runStateInfo.setMaximumSize(maximumPoolSize);
runStateInfo.setActiveSize(activeCount);
runStateInfo.setCurrentLoad(currentLoad);
runStateInfo.setPeakLoad(peakLoad);
runStateInfo.setQueueType(queueType);
runStateInfo.setQueueSize(queueSize);
runStateInfo.setQueueCapacity(queueCapacity);
runStateInfo.setQueueRemainingCapacity(remainingCapacity);
runStateInfo.setLargestPoolSize(largestPoolSize);
runStateInfo.setCompletedTaskCount(completedTaskCount);
runStateInfo.setClientLastRefreshTime(DateUtil.formatDateTime(new Date()));
runStateInfo.setTimestamp(System.currentTimeMillis());
return webThreadPoolRunStateHandler.supplement(runStateInfo);
}
@Override
public void updateWebThreadPool(ThreadPoolParameterInfo threadPoolParameterInfo) {
int originalCoreSize, originalMaximumPoolSize;
long originalKeepAliveTime;
try {
ThreadPoolExecutor tomcatExecutor = (ThreadPoolExecutor) executor;
int originalCoreSize = tomcatExecutor.getCorePoolSize();
int originalMaximumPoolSize = tomcatExecutor.getMaximumPoolSize();
long originalKeepAliveTime = tomcatExecutor.getKeepAliveTime(TimeUnit.SECONDS);
tomcatExecutor.setCorePoolSize(threadPoolParameterInfo.corePoolSizeAdapt());
tomcatExecutor.setMaximumPoolSize(threadPoolParameterInfo.maximumPoolSizeAdapt());
tomcatExecutor.setKeepAliveTime(threadPoolParameterInfo.getKeepAliveTime(), TimeUnit.SECONDS);
if (executor instanceof ThreadPoolExecutor) {
ThreadPoolExecutor threadPoolExecutor = (ThreadPoolExecutor) executor;
originalCoreSize = threadPoolExecutor.getCorePoolSize();
originalMaximumPoolSize = threadPoolExecutor.getMaximumPoolSize();
originalKeepAliveTime = threadPoolExecutor.getKeepAliveTime(TimeUnit.SECONDS);
threadPoolExecutor.setCorePoolSize(threadPoolParameterInfo.corePoolSizeAdapt());
threadPoolExecutor.setMaximumPoolSize(threadPoolParameterInfo.maximumPoolSizeAdapt());
threadPoolExecutor.setKeepAliveTime(threadPoolParameterInfo.getKeepAliveTime(), TimeUnit.SECONDS);
} else {
org.apache.tomcat.util.threads.ThreadPoolExecutor tomcatThreadPoolExecutor = (org.apache.tomcat.util.threads.ThreadPoolExecutor) executor;
originalCoreSize = tomcatThreadPoolExecutor.getCorePoolSize();
originalMaximumPoolSize = tomcatThreadPoolExecutor.getMaximumPoolSize();
originalKeepAliveTime = tomcatThreadPoolExecutor.getKeepAliveTime(TimeUnit.SECONDS);
tomcatThreadPoolExecutor.setCorePoolSize(threadPoolParameterInfo.corePoolSizeAdapt());
tomcatThreadPoolExecutor.setMaximumPoolSize(threadPoolParameterInfo.maximumPoolSizeAdapt());
tomcatThreadPoolExecutor.setKeepAliveTime(threadPoolParameterInfo.getKeepAliveTime(), TimeUnit.SECONDS);
}
log.info("[TOMCAT] Changed web thread pool. corePoolSize :: [{}], maximumPoolSize :: [{}], keepAliveTime :: [{}]",
String.format(CHANGE_DELIMITER, originalCoreSize, threadPoolParameterInfo.corePoolSizeAdapt()),
String.format(CHANGE_DELIMITER, originalMaximumPoolSize, threadPoolParameterInfo.maximumPoolSizeAdapt()),

@ -34,7 +34,7 @@ import lombok.extern.slf4j.Slf4j;
public class WebThreadPoolRunStateHandler extends AbstractThreadPoolRuntime {
@Override
protected ThreadPoolRunStateInfo supplement(ThreadPoolRunStateInfo poolRunStateInfo) {
public ThreadPoolRunStateInfo supplement(ThreadPoolRunStateInfo poolRunStateInfo) {
RuntimeInfo runtimeInfo = new RuntimeInfo();
String memoryProportion = StrUtil.builder(
"已分配: ",

@ -61,7 +61,7 @@ public class RunTimeInfoCollector extends AbstractThreadPoolRuntime implements C
}
@Override
protected ThreadPoolRunStateInfo supplement(ThreadPoolRunStateInfo threadPoolRunStateInfo) {
public ThreadPoolRunStateInfo supplement(ThreadPoolRunStateInfo threadPoolRunStateInfo) {
return threadPoolRunStateInfo;
}
}

@ -48,6 +48,7 @@
<spring-boot.version>2.3.2.RELEASE</spring-boot.version>
<apollo.version>1.9.1</apollo.version>
<rocketmq.version>2.2.2</rocketmq.version>
<tomcat-embed-core.version>9.0.55</tomcat-embed-core.version>
<spring-cloud-starter-stream-rocketmq.version>2.2.6.RELEASE</spring-cloud-starter-stream-rocketmq.version>
<maven.javadoc.failOnError>false</maven.javadoc.failOnError>

Loading…
Cancel
Save