From aa8478de3c83a8ab42ce7a115d42ad918ab3a195 Mon Sep 17 00:00:00 2001 From: chuailiwu Date: Fri, 4 Mar 2022 16:10:03 +0800 Subject: [PATCH] add rpc custom thread pool monitor (#908) --- .../rpc/boot/common/RpcThreadPoolMonitor.java | 14 ++++ .../boot/container/ServerConfigContainer.java | 82 ++++++++++++++----- .../sofa/rpc/boot/log/LoggerConstant.java | 1 + .../sofa/rpc/boot/log/log4j/log-conf.xml | 16 ++++ .../sofa/rpc/boot/log/log4j2/log-conf.xml | 17 ++++ .../sofa/rpc/boot/log/logback/log-conf.xml | 27 ++++++ .../container/ServerConfigContainerTest.java | 46 +++++++++++ .../sofaboot-dependencies/pom.xml | 4 +- 8 files changed, 185 insertions(+), 22 deletions(-) diff --git a/sofa-boot-project/sofa-boot-core/rpc-sofa-boot/src/main/java/com/alipay/sofa/rpc/boot/common/RpcThreadPoolMonitor.java b/sofa-boot-project/sofa-boot-core/rpc-sofa-boot/src/main/java/com/alipay/sofa/rpc/boot/common/RpcThreadPoolMonitor.java index 6dc4281b0..8d654f2db 100644 --- a/sofa-boot-project/sofa-boot-core/rpc-sofa-boot/src/main/java/com/alipay/sofa/rpc/boot/common/RpcThreadPoolMonitor.java +++ b/sofa-boot-project/sofa-boot-core/rpc-sofa-boot/src/main/java/com/alipay/sofa/rpc/boot/common/RpcThreadPoolMonitor.java @@ -21,6 +21,7 @@ import java.util.concurrent.atomic.AtomicInteger; import com.alipay.sofa.rpc.common.annotation.VisibleForTesting; +import com.alipay.sofa.rpc.common.utils.StringUtils; import org.slf4j.Logger; import com.alipay.sofa.rpc.boot.log.SofaBootRpcLoggerFactory; @@ -53,6 +54,8 @@ public class RpcThreadPoolMonitor { private Thread monitor; + private String poolName = ""; + public RpcThreadPoolMonitor(String loggerName) { this(null, loggerName, DEFAULT_SLEEP_TIME); } @@ -99,6 +102,9 @@ public void run() { sb.append("active:" + activeSize + ", "); sb.append("idle:" + (poolSize - activeSize) + ", "); sb.append("poolSize:" + poolSize); + if (StringUtils.isNotBlank(poolName)) { + sb.append(", poolName: " + poolName); + } logger.info(sb.toString()); } } catch (Throwable throwable) { @@ -133,6 +139,14 @@ public void setThreadPoolExecutor(ThreadPoolExecutor threadPoolExecutor) { this.threadPoolExecutor = threadPoolExecutor; } + public void setPoolName(String poolName) { + this.poolName = poolName; + } + + public String getPoolName() { + return poolName; + } + public void stop() { synchronized (this) { this.active = false; diff --git a/sofa-boot-project/sofa-boot-core/rpc-sofa-boot/src/main/java/com/alipay/sofa/rpc/boot/container/ServerConfigContainer.java b/sofa-boot-project/sofa-boot-core/rpc-sofa-boot/src/main/java/com/alipay/sofa/rpc/boot/container/ServerConfigContainer.java index 60ba22a20..a6f3ad870 100644 --- a/sofa-boot-project/sofa-boot-core/rpc-sofa-boot/src/main/java/com/alipay/sofa/rpc/boot/container/ServerConfigContainer.java +++ b/sofa-boot-project/sofa-boot-core/rpc-sofa-boot/src/main/java/com/alipay/sofa/rpc/boot/container/ServerConfigContainer.java @@ -25,15 +25,21 @@ import com.alipay.sofa.rpc.boot.log.SofaBootRpcLoggerFactory; import com.alipay.sofa.rpc.common.RpcConstants; import com.alipay.sofa.rpc.config.ServerConfig; +import com.alipay.sofa.rpc.config.UserThreadPoolManager; import com.alipay.sofa.rpc.log.LogCodes; import com.alipay.sofa.rpc.server.Server; +import com.alipay.sofa.rpc.server.UserThreadPool; import com.alipay.sofa.rpc.server.bolt.BoltServer; import com.alipay.sofa.rpc.server.triple.TripleServer; import org.slf4j.Logger; import org.springframework.util.StringUtils; +import java.util.ArrayList; import java.util.HashMap; +import java.util.HashSet; +import java.util.List; import java.util.Map; +import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ThreadPoolExecutor; @@ -44,54 +50,56 @@ */ public class ServerConfigContainer { - private static final Logger LOGGER = SofaBootRpcLoggerFactory - .getLogger(ServerConfigContainer.class); + private static final Logger LOGGER = SofaBootRpcLoggerFactory + .getLogger(ServerConfigContainer.class); - private SofaBootRpcProperties sofaBootRpcProperties; + private SofaBootRpcProperties sofaBootRpcProperties; /** * bolt ServerConfig */ - private volatile ServerConfig boltServerConfig; - private final Object BOLT_LOCK = new Object(); + private volatile ServerConfig boltServerConfig; + private final Object BOLT_LOCK = new Object(); /** * rest ServerConfig */ - private volatile ServerConfig restServerConfig; - private final Object REST_LOCK = new Object(); + private volatile ServerConfig restServerConfig; + private final Object REST_LOCK = new Object(); /** * dubbo ServerConfig */ - private volatile ServerConfig dubboServerConfig; - private final Object DUBBO_LOCK = new Object(); + private volatile ServerConfig dubboServerConfig; + private final Object DUBBO_LOCK = new Object(); /** * h2c ServerConfig */ - private volatile ServerConfig h2cServerConfig; - private final Object H2C_LOCK = new Object(); + private volatile ServerConfig h2cServerConfig; + private final Object H2C_LOCK = new Object(); /** * http ServerConfig */ - private volatile ServerConfig httpServerConfig; - private final Object HTTP_LOCK = new Object(); + private volatile ServerConfig httpServerConfig; + private final Object HTTP_LOCK = new Object(); /** * http ServerConfig */ - private volatile ServerConfig tripleServerConfig; - private final Object TRIPLE_LOCK = new Object(); + private volatile ServerConfig tripleServerConfig; + private final Object TRIPLE_LOCK = new Object(); //custom server configs - private Map customServerConfigs = new ConcurrentHashMap(); + private Map customServerConfigs = new ConcurrentHashMap(); - private RpcThreadPoolMonitor boltThreadPoolMonitor = new RpcThreadPoolMonitor( - LoggerConstant.BOLT_THREAD_LOGGER_NAME); + private RpcThreadPoolMonitor boltThreadPoolMonitor = new RpcThreadPoolMonitor( + LoggerConstant.BOLT_THREAD_LOGGER_NAME); - private RpcThreadPoolMonitor tripleThreadPoolMonitor = new RpcThreadPoolMonitor( - LoggerConstant.TRIPLE_THREAD_LOGGER_NAME); + private RpcThreadPoolMonitor tripleThreadPoolMonitor = new RpcThreadPoolMonitor( + LoggerConstant.TRIPLE_THREAD_LOGGER_NAME); + + private List customThreadPoolMonitorList = new ArrayList<>(); public ServerConfigContainer(SofaBootRpcProperties sofaBootRpcProperties) { this.sofaBootRpcProperties = sofaBootRpcProperties; @@ -156,6 +164,29 @@ public void startServers() { } } + startCustomThreadPoolMonitor(); + } + + private void startCustomThreadPoolMonitor() { + Set userThreadPoolSet = UserThreadPoolManager.getUserThreadPoolSet(); + if (!userThreadPoolSet.isEmpty()) { + Set poolNames = new HashSet<>(); + for (UserThreadPool pool : userThreadPoolSet) { + RpcThreadPoolMonitor customThreadPoolMonitor = new RpcThreadPoolMonitor( + LoggerConstant.CUSTOM_THREAD_LOGGER_NAME); + customThreadPoolMonitorList.add(customThreadPoolMonitor); + if (poolNames.contains(pool.getThreadPoolName())) { + //use to distinguish some UserThreadPools set same poolName + customThreadPoolMonitor.setPoolName(pool.getThreadPoolName() + "-" + + pool.hashCode()); + } else { + customThreadPoolMonitor.setPoolName(pool.getThreadPoolName()); + } + customThreadPoolMonitor.setThreadPoolExecutor(pool.getExecutor()); + customThreadPoolMonitor.start(); + poolNames.add(pool.getThreadPoolName()); + } + } } /** @@ -584,6 +615,8 @@ public void closeAllServer() { tripleThreadPoolMonitor.stop(); } + stopCustomThreadPoolMonitor(); + destroyServerConfig(boltServerConfig); destroyServerConfig(restServerConfig); destroyServerConfig(dubboServerConfig); @@ -602,6 +635,15 @@ public void closeAllServer() { customServerConfigs.clear(); } + private void stopCustomThreadPoolMonitor() { + if (!customThreadPoolMonitorList.isEmpty()) { + for (RpcThreadPoolMonitor monitor : customThreadPoolMonitorList) { + monitor.stop(); + } + customThreadPoolMonitorList.clear(); + } + } + private void destroyServerConfig(ServerConfig serverConfig) { if (serverConfig != null) { Server server = serverConfig.getServer(); diff --git a/sofa-boot-project/sofa-boot-core/rpc-sofa-boot/src/main/java/com/alipay/sofa/rpc/boot/log/LoggerConstant.java b/sofa-boot-project/sofa-boot-core/rpc-sofa-boot/src/main/java/com/alipay/sofa/rpc/boot/log/LoggerConstant.java index 896a27683..177c8a641 100644 --- a/sofa-boot-project/sofa-boot-core/rpc-sofa-boot/src/main/java/com/alipay/sofa/rpc/boot/log/LoggerConstant.java +++ b/sofa-boot-project/sofa-boot-core/rpc-sofa-boot/src/main/java/com/alipay/sofa/rpc/boot/log/LoggerConstant.java @@ -24,4 +24,5 @@ public class LoggerConstant { public static final String BOLT_THREAD_LOGGER_NAME = "RPC-BOLT-THREADPOOL"; public static final String TRIPLE_THREAD_LOGGER_NAME = "RPC-TRIPLE-THREADPOOL"; + public static final String CUSTOM_THREAD_LOGGER_NAME = "RPC-CUSTOM-THREADPOOL"; } diff --git a/sofa-boot-project/sofa-boot-core/rpc-sofa-boot/src/main/resources/com/alipay/sofa/rpc/boot/log/log4j/log-conf.xml b/sofa-boot-project/sofa-boot-core/rpc-sofa-boot/src/main/resources/com/alipay/sofa/rpc/boot/log/log4j/log-conf.xml index 97727ae45..da4783dd9 100644 --- a/sofa-boot-project/sofa-boot-core/rpc-sofa-boot/src/main/resources/com/alipay/sofa/rpc/boot/log/log4j/log-conf.xml +++ b/sofa-boot-project/sofa-boot-core/rpc-sofa-boot/src/main/resources/com/alipay/sofa/rpc/boot/log/log4j/log-conf.xml @@ -43,6 +43,16 @@ + + + + + + + + + + @@ -55,6 +65,12 @@ + + + + + + diff --git a/sofa-boot-project/sofa-boot-core/rpc-sofa-boot/src/main/resources/com/alipay/sofa/rpc/boot/log/log4j2/log-conf.xml b/sofa-boot-project/sofa-boot-core/rpc-sofa-boot/src/main/resources/com/alipay/sofa/rpc/boot/log/log4j2/log-conf.xml index d99bb6c76..1cb97cc40 100644 --- a/sofa-boot-project/sofa-boot-core/rpc-sofa-boot/src/main/resources/com/alipay/sofa/rpc/boot/log/log4j2/log-conf.xml +++ b/sofa-boot-project/sofa-boot-core/rpc-sofa-boot/src/main/resources/com/alipay/sofa/rpc/boot/log/log4j2/log-conf.xml @@ -58,6 +58,18 @@ + + + + + %d %-5p %-32t %c{2} - %m%n %throwable + + + + + + @@ -72,6 +84,11 @@ + + + + + diff --git a/sofa-boot-project/sofa-boot-core/rpc-sofa-boot/src/main/resources/com/alipay/sofa/rpc/boot/log/logback/log-conf.xml b/sofa-boot-project/sofa-boot-core/rpc-sofa-boot/src/main/resources/com/alipay/sofa/rpc/boot/log/logback/log-conf.xml index 96074f391..b8d541a90 100644 --- a/sofa-boot-project/sofa-boot-core/rpc-sofa-boot/src/main/resources/com/alipay/sofa/rpc/boot/log/logback/log-conf.xml +++ b/sofa-boot-project/sofa-boot-core/rpc-sofa-boot/src/main/resources/com/alipay/sofa/rpc/boot/log/logback/log-conf.xml @@ -94,6 +94,28 @@ + + true + + info + ACCEPT + DENY + + ${logging.path}/rpc/custom-threadpool.log + + + + ${logging.path}/rpc/custom-threadpool.log.%d{yyyy-MM-dd} + + 30 + + + %d %-5p %-32t %c{2} - %m%n + + ${file.encoding} + + + @@ -107,6 +129,11 @@ + + + + + diff --git a/sofa-boot-project/sofa-boot-core/rpc-sofa-boot/src/test/java/com/alipay/sofa/rpc/boot/test/container/ServerConfigContainerTest.java b/sofa-boot-project/sofa-boot-core/rpc-sofa-boot/src/test/java/com/alipay/sofa/rpc/boot/test/container/ServerConfigContainerTest.java index f042bf854..0b8fdbbab 100644 --- a/sofa-boot-project/sofa-boot-core/rpc-sofa-boot/src/test/java/com/alipay/sofa/rpc/boot/test/container/ServerConfigContainerTest.java +++ b/sofa-boot-project/sofa-boot-core/rpc-sofa-boot/src/test/java/com/alipay/sofa/rpc/boot/test/container/ServerConfigContainerTest.java @@ -16,6 +16,9 @@ */ package com.alipay.sofa.rpc.boot.test.container; +import com.alipay.sofa.rpc.boot.common.RpcThreadPoolMonitor; +import com.alipay.sofa.rpc.config.UserThreadPoolManager; +import com.alipay.sofa.rpc.server.UserThreadPool; import org.junit.Assert; import org.junit.Ignore; import org.junit.Test; @@ -30,6 +33,11 @@ import com.alipay.sofa.rpc.common.RpcConstants; import com.alipay.sofa.rpc.config.ServerConfig; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.List; + /** * @author LiWei */ @@ -184,4 +192,42 @@ public void testCreateHttpServerConfig() { Assert.assertEquals(1, serverConfig.getAccepts()); Assert.assertEquals(8, serverConfig.getQueues()); } + + @Test + public void testStartCustomThreadPoolMonitor() throws NoSuchMethodException, + IllegalAccessException, + InvocationTargetException, NoSuchFieldException { + UserThreadPoolManager.registerUserThread("service1", new UserThreadPool()); + UserThreadPoolManager.registerUserThread("service2", new UserThreadPool()); + UserThreadPoolManager.registerUserThread("service3", new UserThreadPool("same-name")); + UserThreadPoolManager.registerUserThread("service4", new UserThreadPool("same-name")); + + Method privateStartMethod = serverConfigContainer.getClass().getDeclaredMethod( + "startCustomThreadPoolMonitor"); + privateStartMethod.setAccessible(true); + privateStartMethod.invoke(serverConfigContainer); + + Field privateField = serverConfigContainer.getClass().getDeclaredField( + "customThreadPoolMonitorList"); + privateField.setAccessible(true); + Object value = privateField.get(serverConfigContainer); + List customThreadPoolMonitorList = (List) value; + Assert.assertEquals(customThreadPoolMonitorList.size(), 4); + + boolean hasHashCode = false; + for (RpcThreadPoolMonitor monitor : customThreadPoolMonitorList) { + if (monitor.getPoolName().contains("same-name-")) { + hasHashCode = true; + } + } + Assert.assertTrue(hasHashCode); + + Method privateStopMethod = serverConfigContainer.getClass().getDeclaredMethod( + "stopCustomThreadPoolMonitor"); + privateStopMethod.setAccessible(true); + privateStopMethod.invoke(serverConfigContainer); + + Assert.assertEquals(customThreadPoolMonitorList.size(), 0); + + } } \ No newline at end of file diff --git a/sofa-boot-project/sofaboot-dependencies/pom.xml b/sofa-boot-project/sofaboot-dependencies/pom.xml index 565bf682c..ac01a8f86 100644 --- a/sofa-boot-project/sofaboot-dependencies/pom.xml +++ b/sofa-boot-project/sofaboot-dependencies/pom.xml @@ -26,11 +26,11 @@ 5.4.2 3.1.0 - 5.7.7 + 5.8.3 1.3.6 - 1.5.6 + 1.5.10 3.3.12