diff --git a/agent/hippo4j-agent-core/src/main/java/cn/hippo4j/agent/core/conf/SnifferConfigInitializer.java b/agent/hippo4j-agent-core/src/main/java/cn/hippo4j/agent/core/conf/SnifferConfigInitializer.java index ef811800d0..b8f8f4d0bc 100644 --- a/agent/hippo4j-agent-core/src/main/java/cn/hippo4j/agent/core/conf/SnifferConfigInitializer.java +++ b/agent/hippo4j-agent-core/src/main/java/cn/hippo4j/agent/core/conf/SnifferConfigInitializer.java @@ -18,6 +18,8 @@ package cn.hippo4j.agent.core.conf; import cn.hippo4j.agent.core.boot.AgentPackagePath; +import cn.hippo4j.agent.core.util.PropertyPlaceholderHelper; +import cn.hippo4j.agent.core.util.StringUtil; import cn.hippo4j.common.boot.AgentPackageNotFoundException; import cn.hippo4j.common.conf.Config; import cn.hippo4j.common.conf.ConfigNotFoundException; @@ -25,9 +27,7 @@ import cn.hippo4j.common.logging.api.LogManager; import cn.hippo4j.common.logging.core.JsonLogResolver; import cn.hippo4j.common.logging.core.PatternLogResolver; -import cn.hippo4j.common.toolkit.StringUtil; import cn.hippo4j.common.toolkit.agent.ConfigInitializer; -import cn.hippo4j.common.toolkit.agent.PropertyPlaceholderHelper; import java.io.File; import java.io.FileInputStream; diff --git a/agent/hippo4j-agent-plugin/nacos-plugin/src/main/java/cn/hippo4j/agent/plugin/nacos/NacosDynamicThreadPoolChangeHandler.java b/agent/hippo4j-agent-plugin/nacos-plugin/src/main/java/cn/hippo4j/agent/plugin/nacos/NacosDynamicThreadPoolChangeHandler.java index 866f3cccda..8537f45c4e 100644 --- a/agent/hippo4j-agent-plugin/nacos-plugin/src/main/java/cn/hippo4j/agent/plugin/nacos/NacosDynamicThreadPoolChangeHandler.java +++ b/agent/hippo4j-agent-plugin/nacos-plugin/src/main/java/cn/hippo4j/agent/plugin/nacos/NacosDynamicThreadPoolChangeHandler.java @@ -17,11 +17,14 @@ package cn.hippo4j.agent.plugin.nacos; +import cn.hippo4j.agent.plugin.spring.common.conf.NacosCloudConfig; +import cn.hippo4j.agent.plugin.spring.common.conf.NacosConfig; import cn.hippo4j.agent.plugin.spring.common.conf.SpringBootConfig; import cn.hippo4j.agent.plugin.spring.common.toolkit.SpringPropertyBinder; import cn.hippo4j.common.executor.ThreadFactoryBuilder; import cn.hippo4j.common.logging.api.ILog; import cn.hippo4j.common.logging.api.LogManager; +import cn.hippo4j.common.toolkit.StringUtil; import cn.hippo4j.threadpool.dynamic.mode.config.parser.ConfigParserHandler; import cn.hippo4j.threadpool.dynamic.mode.config.properties.BootstrapConfigProperties; import cn.hippo4j.threadpool.dynamic.mode.config.refresher.AbstractConfigThreadPoolDynamicRefresh; @@ -34,6 +37,7 @@ import java.io.IOException; import java.util.HashMap; import java.util.Map; +import java.util.Optional; import java.util.Properties; import java.util.concurrent.Executor; import java.util.concurrent.ScheduledThreadPoolExecutor; @@ -64,7 +68,13 @@ public class NacosDynamicThreadPoolChangeHandler extends AbstractConfigThreadPoo public void registerListener() { // Retrieve necessary configuration properties String configFileType = SpringBootConfig.Spring.Dynamic.Thread_Pool.CONFIG_FILE_TYPE; - String serverAddr = SpringBootConfig.Spring.Dynamic.Thread_Pool.Nacos.SERVER_ADDR; + String serverAddr = Optional.ofNullable(NacosCloudConfig.Spring.Cloud.Nacos.Config.SERVER_ADDR).filter(s -> !StringUtil.isEmpty(s)) + .orElse(Optional.ofNullable(NacosConfig.Nacos.Config.SERVER_ADDR).filter(s -> !StringUtil.isEmpty(s)) + .orElse("")); + if (StringUtil.isEmpty(serverAddr)) { + LOGGER.error("[Hippo4j-Agent] add Nacos listener failure. Nacos Registry address not configured"); + return; + } String dataId = SpringBootConfig.Spring.Dynamic.Thread_Pool.Nacos.DATA_ID; String group = SpringBootConfig.Spring.Dynamic.Thread_Pool.Nacos.GROUP; String namespace = SpringBootConfig.Spring.Dynamic.Thread_Pool.Nacos.NAMESPACE.get(0); @@ -105,9 +115,9 @@ public Executor getExecutor() { }; // Add the listener to the Nacos ConfigService configService.addListener(dataId, group, configChangeListener); - LOGGER.info("[Hippo4j-Agent] Dynamic thread pool refresher, add Nacos listener successfully. namespace: {} data-id: {} group: {}", namespace, dataId, group); + LOGGER.info("[Hippo4j-Agent] Dynamic thread pool refresher, add Nacos listener successfully. serverAddr: {} namespace: {} data-id: {} group: {}", serverAddr, namespace, dataId, group); } catch (Exception e) { - LOGGER.error(e, "[Hippo4j-Agent] Dynamic thread pool refresher, add Nacos listener failure. namespace: {} data-id: {} group: {}", namespace, dataId, group); + LOGGER.error(e, "[Hippo4j-Agent] Dynamic thread pool refresher, add Nacos listener failure. serverAddr: {} namespace: {} data-id: {} group: {}", serverAddr, namespace, dataId, group); } } diff --git a/agent/hippo4j-agent-plugin/nacos-plugin/src/main/java/cn/hippo4j/agent/plugin/nacos/interceptor/NacosCloudAdapterConfigInstanceMethodInterceptor.java b/agent/hippo4j-agent-plugin/nacos-plugin/src/main/java/cn/hippo4j/agent/plugin/nacos/interceptor/NacosCloudAdapterConfigInstanceMethodInterceptor.java index 7a7cf841fb..9a227edfd8 100644 --- a/agent/hippo4j-agent-plugin/nacos-plugin/src/main/java/cn/hippo4j/agent/plugin/nacos/interceptor/NacosCloudAdapterConfigInstanceMethodInterceptor.java +++ b/agent/hippo4j-agent-plugin/nacos-plugin/src/main/java/cn/hippo4j/agent/plugin/nacos/interceptor/NacosCloudAdapterConfigInstanceMethodInterceptor.java @@ -41,9 +41,6 @@ public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allAr } - /** - * - */ @Override public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, Object ret) throws Throwable { // This logic will only be executed once diff --git a/agent/hippo4j-agent-plugin/nacos-plugin/src/main/java/cn/hippo4j/agent/plugin/nacos/interceptor/NacosConfigConstructorInterceptor.java b/agent/hippo4j-agent-plugin/nacos-plugin/src/main/java/cn/hippo4j/agent/plugin/nacos/interceptor/NacosConfigConstructorInterceptor.java index 7a62931944..9241710f21 100644 --- a/agent/hippo4j-agent-plugin/nacos-plugin/src/main/java/cn/hippo4j/agent/plugin/nacos/interceptor/NacosConfigConstructorInterceptor.java +++ b/agent/hippo4j-agent-plugin/nacos-plugin/src/main/java/cn/hippo4j/agent/plugin/nacos/interceptor/NacosConfigConstructorInterceptor.java @@ -38,7 +38,7 @@ public void onConstruct(EnhancedInstance objInst, Object[] allArguments) throws // This logic will only be executed once if (isExecuted.compareAndSet(false, true)) { - // 判断 SpringPropertiesLoader 是否初始化 + // Determine whether SpringPropertiesLoader is initialized AtomicBoolean active = SpringPropertiesLoader.getActive(); // For Nacos-Cloud, the SpringPropertiesLoader environment initialization is triggered first, and then the logic to register listeners is triggered @@ -51,7 +51,7 @@ public void onConstruct(EnhancedInstance objInst, Object[] allArguments) throws // The Nacos plugin triggers before the Spring configuration plug-in. // This means that when the Apollo plug-in executes, Spring's Environment is not yet ready, // so the configuration cannot be read - // After listening to the AGENT_SPRING_PROPERTIES_LOADER_COMPLETED event, register the listener for Apollo + // After listening to the AGENT_SPRING_PROPERTIES_LOADER_COMPLETED event, register the listener for Nacos AbstractSubjectCenter.register(AbstractSubjectCenter.SubjectType.AGENT_SPRING_PROPERTIES_LOADER_COMPLETED, new NacosConfigPropertiesLoaderCompletedListener()); } } diff --git a/agent/hippo4j-agent-plugin/spring-plugins/spring-boot-1x-plugin/pom.xml b/agent/hippo4j-agent-plugin/spring-plugins/spring-boot-1x-plugin/pom.xml index b3d2cbf96f..1c0a7fc184 100644 --- a/agent/hippo4j-agent-plugin/spring-plugins/spring-boot-1x-plugin/pom.xml +++ b/agent/hippo4j-agent-plugin/spring-plugins/spring-boot-1x-plugin/pom.xml @@ -29,13 +29,6 @@ - - cn.hippo4j - hippo4j-agent-spring-plugin-common - provided - ${project.version} - - org.springframework.boot spring-boot-starter @@ -45,9 +38,8 @@ cn.hippo4j - hippo4j-threadpool-config-spring-boot-1x-starter + hippo4j-agent-spring-plugin-common ${project.version} - provided diff --git a/agent/hippo4j-agent-plugin/spring-plugins/spring-boot-1x-plugin/src/main/java/cn/hippo4j/agent/plugin/spring/boot/v1/interceptor/ApplicationContextInterceptor.java b/agent/hippo4j-agent-plugin/spring-plugins/spring-boot-1x-plugin/src/main/java/cn/hippo4j/agent/plugin/spring/boot/v1/interceptor/ApplicationContextInterceptor.java index 8297bfb9aa..b0b1666583 100644 --- a/agent/hippo4j-agent-plugin/spring-plugins/spring-boot-1x-plugin/src/main/java/cn/hippo4j/agent/plugin/spring/boot/v1/interceptor/ApplicationContextInterceptor.java +++ b/agent/hippo4j-agent-plugin/spring-plugins/spring-boot-1x-plugin/src/main/java/cn/hippo4j/agent/plugin/spring/boot/v1/interceptor/ApplicationContextInterceptor.java @@ -25,7 +25,9 @@ import cn.hippo4j.agent.plugin.spring.common.support.SpringThreadPoolRegisterSupport; import cn.hippo4j.common.extension.design.AbstractSubjectCenter; import cn.hippo4j.core.config.ApplicationContextHolder; +import org.springframework.context.ApplicationListener; import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.context.event.ContextRefreshedEvent; import java.lang.reflect.Method; import java.util.concurrent.atomic.AtomicBoolean; @@ -50,7 +52,18 @@ public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allA ConfigurableApplicationContext context = (ConfigurableApplicationContext) objInst; if (context.getParent() != null) { // After the child container is started, the thread pool registration will be carried out - SpringThreadPoolRegisterSupport.registerThreadPoolInstances(context); + // IDEA's runtime environment or debugging mechanisms make context refresh speeds different. + // Ensure that thread pool registration logic is executed only after the context is fully started + if (context.isActive()) { + SpringThreadPoolRegisterSupport.registerThreadPoolInstances(context); + return ret; + } + // However, the packaged JAR runtime may refresh the context faster + // resulting in the context not being refreshed yet when registerThreadPoolInstances is called + // Register listener to handle the registration after the context has been fully refreshed + context.addApplicationListener((ApplicationListener) event -> { + SpringThreadPoolRegisterSupport.registerThreadPoolInstances(event.getApplicationContext()); + }); return ret; } // This logic will only be executed once diff --git a/agent/hippo4j-agent-plugin/spring-plugins/spring-boot-2x-plugin/pom.xml b/agent/hippo4j-agent-plugin/spring-plugins/spring-boot-2x-plugin/pom.xml index a05c33f3e2..6fac2cc48f 100644 --- a/agent/hippo4j-agent-plugin/spring-plugins/spring-boot-2x-plugin/pom.xml +++ b/agent/hippo4j-agent-plugin/spring-plugins/spring-boot-2x-plugin/pom.xml @@ -17,13 +17,6 @@ - - cn.hippo4j - hippo4j-agent-spring-plugin-common - provided - ${project.version} - - org.springframework.boot spring-boot-starter @@ -33,28 +26,15 @@ cn.hippo4j - hippo4j-threadpool-dynamic-mode-config + hippo4j-agent-spring-plugin-common ${project.version} - provided cn.hippo4j - hippo4j-threadpool-core + hippo4j-threadpool-dynamic-mode-config ${project.version} - provided - - com.ctrip.framework.apollo - apollo-client - provided - - - - com.alibaba.nacos - nacos-client - 2.2.1 - \ No newline at end of file diff --git a/agent/hippo4j-agent-plugin/spring-plugins/spring-boot-2x-plugin/src/main/java/cn/hippo4j/agent/plugin/spring/boot/v2/DynamicThreadPoolChangeHandlerSpring2x.java b/agent/hippo4j-agent-plugin/spring-plugins/spring-boot-2x-plugin/src/main/java/cn/hippo4j/agent/plugin/spring/boot/v2/DynamicThreadPoolChangeHandlerSpring2x.java deleted file mode 100644 index 6f70bf237c..0000000000 --- a/agent/hippo4j-agent-plugin/spring-plugins/spring-boot-2x-plugin/src/main/java/cn/hippo4j/agent/plugin/spring/boot/v2/DynamicThreadPoolChangeHandlerSpring2x.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package cn.hippo4j.agent.plugin.spring.boot.v2; - -import cn.hippo4j.common.logging.api.ILog; -import cn.hippo4j.common.logging.api.LogManager; -import cn.hippo4j.agent.plugin.spring.common.conf.SpringBootConfig; -import cn.hippo4j.threadpool.dynamic.mode.config.properties.BootstrapConfigProperties; -import cn.hippo4j.threadpool.dynamic.mode.config.refresher.AbstractConfigThreadPoolDynamicRefresh; -import com.ctrip.framework.apollo.Config; -import com.ctrip.framework.apollo.ConfigChangeListener; -import com.ctrip.framework.apollo.ConfigFile; -import com.ctrip.framework.apollo.ConfigService; -import com.ctrip.framework.apollo.core.enums.ConfigFileFormat; -import com.ctrip.framework.apollo.model.ConfigChange; -import org.springframework.boot.context.properties.bind.Bindable; -import org.springframework.boot.context.properties.bind.Binder; -import org.springframework.boot.context.properties.source.ConfigurationPropertySource; -import org.springframework.boot.context.properties.source.MapConfigurationPropertySource; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import static cn.hippo4j.agent.core.conf.Constants.SPRING_BOOT_CONFIG_PREFIX; - -/** - * Dynamic thread pool change handler spring 2x - */ -public class DynamicThreadPoolChangeHandlerSpring2x extends AbstractConfigThreadPoolDynamicRefresh { - - private static ILog LOGGER = LogManager.getLogger(DynamicThreadPoolChangeHandlerSpring2x.class); - - @Override - public void registerListener() { - List apolloNamespaces = SpringBootConfig.Spring.Dynamic.Thread_Pool.Apollo.NAMESPACE; - String namespace = apolloNamespaces.get(0); - String configFileType = SpringBootConfig.Spring.Dynamic.Thread_Pool.CONFIG_FILE_TYPE; - Config config = ConfigService.getConfig(String.format("%s.%s", namespace, configFileType)); - ConfigChangeListener configChangeListener = configChangeEvent -> { - String replacedNamespace = namespace.replaceAll("." + configFileType, ""); - ConfigFileFormat configFileFormat = ConfigFileFormat.fromString(configFileType); - ConfigFile configFile = ConfigService.getConfigFile(replacedNamespace, configFileFormat); - Map newChangeValueMap = new HashMap<>(); - configChangeEvent.changedKeys().stream().filter(each -> each.contains(SPRING_BOOT_CONFIG_PREFIX)).forEach(each -> { - ConfigChange change = configChangeEvent.getChange(each); - String newValue = change.getNewValue(); - newChangeValueMap.put(each, newValue); - }); - dynamicRefresh(configFileType, configFile.getContent(), newChangeValueMap); - }; - config.addChangeListener(configChangeListener); - LOGGER.info("[Hippo4j-Agent] Dynamic thread pool refresher, add apollo listener success. namespace: {}", namespace); - } - - @Override - public BootstrapConfigProperties buildBootstrapProperties(Map configInfo) { - BootstrapConfigProperties bindableBootstrapConfigProperties = new BootstrapConfigProperties(); - ConfigurationPropertySource sources = new MapConfigurationPropertySource(configInfo); - Binder binder = new Binder(sources); - return binder.bind(BootstrapConfigProperties.PREFIX, Bindable.ofInstance(bindableBootstrapConfigProperties)).get(); - } -} diff --git a/agent/hippo4j-agent-plugin/spring-plugins/spring-boot-2x-plugin/src/main/java/cn/hippo4j/agent/plugin/spring/boot/v2/NacosDynamicThreadPoolChangeHandlerSpring2x.java b/agent/hippo4j-agent-plugin/spring-plugins/spring-boot-2x-plugin/src/main/java/cn/hippo4j/agent/plugin/spring/boot/v2/NacosDynamicThreadPoolChangeHandlerSpring2x.java deleted file mode 100644 index 83dd7f359d..0000000000 --- a/agent/hippo4j-agent-plugin/spring-plugins/spring-boot-2x-plugin/src/main/java/cn/hippo4j/agent/plugin/spring/boot/v2/NacosDynamicThreadPoolChangeHandlerSpring2x.java +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package cn.hippo4j.agent.plugin.spring.boot.v2; - -import cn.hippo4j.agent.plugin.spring.common.conf.SpringBootConfig; -import cn.hippo4j.common.executor.ThreadFactoryBuilder; -import cn.hippo4j.common.logging.api.ILog; -import cn.hippo4j.common.logging.api.LogManager; -import cn.hippo4j.threadpool.dynamic.mode.config.parser.ConfigParserHandler; -import cn.hippo4j.threadpool.dynamic.mode.config.properties.BootstrapConfigProperties; -import cn.hippo4j.threadpool.dynamic.mode.config.refresher.AbstractConfigThreadPoolDynamicRefresh; -import com.alibaba.nacos.api.NacosFactory; -import com.alibaba.nacos.api.PropertyKeyConst; -import com.alibaba.nacos.api.config.ConfigService; -import com.alibaba.nacos.api.config.listener.Listener; -import org.springframework.boot.context.properties.bind.Bindable; -import org.springframework.boot.context.properties.bind.Binder; -import org.springframework.boot.context.properties.source.ConfigurationPropertySource; -import org.springframework.boot.context.properties.source.MapConfigurationPropertySource; - -import java.io.IOException; -import java.util.HashMap; -import java.util.Map; -import java.util.Properties; -import java.util.concurrent.Executor; -import java.util.concurrent.ScheduledThreadPoolExecutor; - -import static cn.hippo4j.common.constant.Constants.DEFAULT_NAMESPACE_ID; - -/** - * NacosDynamicThreadPoolChangeHandlerSpring2x is responsible for handling dynamic thread pool - * configuration changes in a Spring environment by listening to configuration updates from Nacos. - *

- * This class extends {@link AbstractConfigThreadPoolDynamicRefresh} and implements the logic - * to register a Nacos listener, handle configuration changes, and dynamically refresh the thread pool - * properties based on the new configuration. - *

- * The handler is specifically tailored for use with Spring 2.x and integrates with Hippo4j's - * dynamic thread pool management system. - * - */ -public class NacosDynamicThreadPoolChangeHandlerSpring2x extends AbstractConfigThreadPoolDynamicRefresh { - - private static final ILog LOGGER = LogManager.getLogger(NacosDynamicThreadPoolChangeHandlerSpring2x.class); - - /** - * Registers a listener with Nacos to monitor for changes in the thread pool configuration. - *

- * This method sets up the Nacos {@link ConfigService} with the server address and namespace - * from the Spring Boot configuration. It then adds a listener that will receive and process - * configuration updates, triggering a dynamic refresh of thread pool settings. - */ - @Override - public void registerListener() { - // Retrieve necessary configuration properties - String configFileType = SpringBootConfig.Spring.Dynamic.Thread_Pool.CONFIG_FILE_TYPE; - String serverAddr = SpringBootConfig.Spring.Dynamic.Thread_Pool.Nacos.SERVER_ADDR; - String dataId = SpringBootConfig.Spring.Dynamic.Thread_Pool.Nacos.DATA_ID; - String namespace = SpringBootConfig.Spring.Dynamic.Thread_Pool.Nacos.NAMESPACE.get(0); - namespace = namespace.equals(DEFAULT_NAMESPACE_ID) ? "" : namespace; - String group = SpringBootConfig.Spring.Dynamic.Thread_Pool.Nacos.GROUP; - try { - // Initialize Nacos ConfigService with the provided properties - Properties properties = new Properties(); - properties.put(PropertyKeyConst.SERVER_ADDR, serverAddr); - properties.put(PropertyKeyConst.NAMESPACE, namespace); - ConfigService configService = NacosFactory.createConfigService(properties); - - // Define the listener to handle configuration changes - Listener configChangeListener = new Listener() { - - @Override - public void receiveConfigInfo(String configInfo) { - LOGGER.debug("Received configuration: " + configInfo); - Map changeValueMap = new HashMap<>(); - try { - // Parse the configuration and map the values to the appropriate keys - Map configInfoMap = ConfigParserHandler.getInstance().parseConfig(configInfo, configFileType); - configInfoMap.forEach((key, value) -> { - if (key instanceof String) { - changeValueMap.put((String) key, value); - } - }); - } catch (IOException e) { - LOGGER.error(e, "[Hippo4j-Agent] Dynamic thread pool refresher, Failed to resolve configuration. configFileType: {} configInfo: {} ", configFileType, configInfo); - } - // Trigger the dynamic refresh with the parsed configuration - dynamicRefresh(configFileType, configInfo, changeValueMap); - } - - @Override - public Executor getExecutor() { - return new ScheduledThreadPoolExecutor( - 1, - ThreadFactoryBuilder.builder().daemon(true).prefix("client.dynamic.refresh.agent").build()); - } - }; - // Add the listener to the Nacos ConfigService - configService.addListener(dataId, group, configChangeListener); - LOGGER.info("[Hippo4j-Agent] Dynamic thread pool refresher, add Nacos listener successfully. namespace: {} data-id: {} group: {}", namespace, dataId, group); - } catch (Exception e) { - LOGGER.error(e, "[Hippo4j-Agent] Dynamic thread pool refresher, add Nacos listener failure. namespace: {} data-id: {} group: {}", namespace, dataId, group); - } - LOGGER.info("[Hippo4j-Agent] Dynamic thread pool refresher, added Nacos listener successfully. namespace: {} data-id: {} group: {}", namespace, dataId, group); - } - - /** - * Builds and binds the {@link BootstrapConfigProperties} from the given configuration map. - *

- * This method uses Spring's {@link Binder} to bind the configuration values to an instance - * of {@link BootstrapConfigProperties}, which can then be used to configure the thread pool - * dynamically. - * - * @param configInfo the configuration map containing properties to bind. - * @return the bound {@link BootstrapConfigProperties} instance. - */ - @Override - public BootstrapConfigProperties buildBootstrapProperties(Map configInfo) { - BootstrapConfigProperties bindableBootstrapConfigProperties = new BootstrapConfigProperties(); - ConfigurationPropertySource sources = new MapConfigurationPropertySource(configInfo); - Binder binder = new Binder(sources); - return binder.bind(BootstrapConfigProperties.PREFIX, Bindable.ofInstance(bindableBootstrapConfigProperties)).get(); - } -} diff --git a/agent/hippo4j-agent-plugin/spring-plugins/spring-plugin-common/pom.xml b/agent/hippo4j-agent-plugin/spring-plugins/spring-plugin-common/pom.xml index 853e0706fc..94992b9505 100644 --- a/agent/hippo4j-agent-plugin/spring-plugins/spring-plugin-common/pom.xml +++ b/agent/hippo4j-agent-plugin/spring-plugins/spring-plugin-common/pom.xml @@ -35,25 +35,32 @@ cn.hippo4j hippo4j-threadpool-dynamic-api ${project.version} - provided cn.hippo4j hippo4j-threadpool-dynamic-core ${project.version} - provided cn.hippo4j hippo4j-threadpool-kernel-alarm ${project.version} - provided + + + cn.hippo4j + hippo4j-threadpool-core + ${project.version} + + + org.springframework.boot + spring-boot-starter + + cn.hippo4j hippo4j-threadpool-adapter-web ${project.version} - provided cn.hippo4j diff --git a/agent/hippo4j-agent-plugin/spring-plugins/spring-plugin-common/src/main/java/cn/hippo4j/agent/plugin/spring/common/conf/NacosCloudConfig.java b/agent/hippo4j-agent-plugin/spring-plugins/spring-plugin-common/src/main/java/cn/hippo4j/agent/plugin/spring/common/conf/NacosCloudConfig.java new file mode 100644 index 0000000000..620198124e --- /dev/null +++ b/agent/hippo4j-agent-plugin/spring-plugins/spring-plugin-common/src/main/java/cn/hippo4j/agent/plugin/spring/common/conf/NacosCloudConfig.java @@ -0,0 +1,51 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.hippo4j.agent.plugin.spring.common.conf; + +import cn.hippo4j.agent.core.boot.SpringBootConfigNode; + +/** + * Nacos Cloud config + */ +public class NacosCloudConfig { + + public static class Spring { + + /** + * Cloud + */ + public static class Cloud { + + /** + * Nacos + */ + public static class Nacos { + + /** + * Config + */ + @SpringBootConfigNode(root = NacosConfig.class) + public static class Config { + + public static String SERVER_ADDR = ""; + + } + } + } + } +} \ No newline at end of file diff --git a/agent/hippo4j-agent-plugin/spring-plugins/spring-plugin-common/src/main/java/cn/hippo4j/agent/plugin/spring/common/conf/NacosConfig.java b/agent/hippo4j-agent-plugin/spring-plugins/spring-plugin-common/src/main/java/cn/hippo4j/agent/plugin/spring/common/conf/NacosConfig.java new file mode 100644 index 0000000000..0722753076 --- /dev/null +++ b/agent/hippo4j-agent-plugin/spring-plugins/spring-plugin-common/src/main/java/cn/hippo4j/agent/plugin/spring/common/conf/NacosConfig.java @@ -0,0 +1,42 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.hippo4j.agent.plugin.spring.common.conf; + +import cn.hippo4j.agent.core.boot.SpringBootConfigNode; + +/** + * nacos config + */ +public class NacosConfig { + + /** + * Nacos + */ + public static class Nacos { + + /** + * Config + */ + @SpringBootConfigNode(root = NacosCloudConfig.class) + public static class Config { + + public static String SERVER_ADDR = ""; + + } + } +} \ No newline at end of file diff --git a/agent/hippo4j-agent-plugin/spring-plugins/spring-plugin-common/src/main/java/cn/hippo4j/agent/plugin/spring/common/monitor/MonitorHandlersConfigurator.java b/agent/hippo4j-agent-plugin/spring-plugins/spring-plugin-common/src/main/java/cn/hippo4j/agent/plugin/spring/common/monitor/MonitorHandlersConfigurator.java index 56e1b7f0d2..30252ec6b7 100644 --- a/agent/hippo4j-agent-plugin/spring-plugins/spring-plugin-common/src/main/java/cn/hippo4j/agent/plugin/spring/common/monitor/MonitorHandlersConfigurator.java +++ b/agent/hippo4j-agent-plugin/spring-plugins/spring-plugin-common/src/main/java/cn/hippo4j/agent/plugin/spring/common/monitor/MonitorHandlersConfigurator.java @@ -17,14 +17,13 @@ package cn.hippo4j.agent.plugin.spring.common.monitor; +import cn.hippo4j.agent.plugin.spring.common.support.SpringPropertiesLoader; import cn.hippo4j.common.extension.spi.ServiceLoaderRegistry; import cn.hippo4j.common.logging.api.ILog; import cn.hippo4j.common.logging.api.LogManager; import cn.hippo4j.common.monitor.MonitorCollectTypeEnum; import cn.hippo4j.common.monitor.MonitorHandlerTypeEnum; import cn.hippo4j.core.executor.state.ThreadPoolRunStateHandler; -import cn.hippo4j.core.toolkit.inet.InetUtils; -import cn.hippo4j.core.toolkit.inet.InetUtilsProperties; import cn.hippo4j.monitor.elasticsearch.AdapterThreadPoolElasticSearchMonitorHandler; import cn.hippo4j.monitor.elasticsearch.DynamicThreadPoolElasticSearchMonitorHandler; import cn.hippo4j.monitor.elasticsearch.WebThreadPoolElasticSearchMonitorHandler; @@ -45,8 +44,6 @@ import java.util.Map; import java.util.function.BiConsumer; -import static cn.hippo4j.agent.plugin.spring.common.support.SpringPropertiesLoader.INET_UTILS_PROPERTIES; - /** * This class is responsible for configuring and initializing monitoring handlers * for various types of thread pools. It maps specific monitoring types (e.g., Micrometer, @@ -88,7 +85,7 @@ public static void initializeMonitorHandlers(MonitorProperties monitor, Configur List collectTypes = Arrays.asList(monitor.getCollectTypes().split(",")); List threadPoolTypes = Arrays.asList(monitor.getThreadPoolTypes().split(",")); ThreadPoolRunStateHandler threadPoolRunStateHandler = new ThreadPoolRunStateHandler( - new InetUtils(INET_UTILS_PROPERTIES), environment); + SpringPropertiesLoader.inetUtils, environment); MonitorHandlerContext context = new MonitorHandlerContext(threadPoolMonitors, threadPoolRunStateHandler); diff --git a/agent/hippo4j-agent-plugin/spring-plugins/spring-plugin-common/src/main/java/cn/hippo4j/agent/plugin/spring/common/monitor/MonitorMetricEndpoint.java b/agent/hippo4j-agent-plugin/spring-plugins/spring-plugin-common/src/main/java/cn/hippo4j/agent/plugin/spring/common/monitor/MonitorMetricEndpoint.java index b8ae07bca5..e52761044e 100644 --- a/agent/hippo4j-agent-plugin/spring-plugins/spring-plugin-common/src/main/java/cn/hippo4j/agent/plugin/spring/common/monitor/MonitorMetricEndpoint.java +++ b/agent/hippo4j-agent-plugin/spring-plugins/spring-plugin-common/src/main/java/cn/hippo4j/agent/plugin/spring/common/monitor/MonitorMetricEndpoint.java @@ -67,7 +67,7 @@ public static void startPrometheusEndpoint() { Integer port = SpringBootConfig.Spring.Dynamic.Thread_Pool.Monitor.AGENT_MICROMETER_PORT; if (port == null) { LOGGER.error( - "[Hippo4j-Agent] Failed to start Prometheus metrics endpoint server. Please configure the exposed endpoint by adding: spring.dynamic.thread-pool.monitor.port=xxx to the configuration file"); + "[Hippo4j-Agent] Failed to start Prometheus metrics endpoint server. Please configure the exposed endpoint by adding: spring.dynamic.thread-pool.monitor.agent-micrometer-port=xxx to the configuration file"); return; } diff --git a/agent/hippo4j-agent-plugin/spring-plugins/spring-plugin-common/src/main/java/cn/hippo4j/agent/plugin/spring/common/support/SpringPropertiesLoader.java b/agent/hippo4j-agent-plugin/spring-plugins/spring-plugin-common/src/main/java/cn/hippo4j/agent/plugin/spring/common/support/SpringPropertiesLoader.java index a73c800e20..907b20741e 100644 --- a/agent/hippo4j-agent-plugin/spring-plugins/spring-plugin-common/src/main/java/cn/hippo4j/agent/plugin/spring/common/support/SpringPropertiesLoader.java +++ b/agent/hippo4j-agent-plugin/spring-plugins/spring-plugin-common/src/main/java/cn/hippo4j/agent/plugin/spring/common/support/SpringPropertiesLoader.java @@ -22,6 +22,7 @@ import cn.hippo4j.common.extension.design.AbstractSubjectCenter; import cn.hippo4j.common.logging.api.ILog; import cn.hippo4j.common.logging.api.LogManager; +import cn.hippo4j.core.toolkit.inet.InetUtils; import cn.hippo4j.core.toolkit.inet.InetUtilsProperties; import cn.hippo4j.threadpool.dynamic.mode.config.properties.BootstrapConfigProperties; import lombok.Getter; @@ -57,6 +58,8 @@ public class SpringPropertiesLoader { public static InetUtilsProperties INET_UTILS_PROPERTIES = new InetUtilsProperties(); + public static InetUtils inetUtils; + public static void loadSpringProperties(ConfigurableEnvironment environment) { Iterator> iterator = environment.getPropertySources().iterator(); Properties properties = new Properties(); diff --git a/agent/hippo4j-agent-plugin/spring-plugins/spring-plugin-common/src/main/java/cn/hippo4j/agent/plugin/spring/common/support/ThreadPoolCheckAlarmSupport.java b/agent/hippo4j-agent-plugin/spring-plugins/spring-plugin-common/src/main/java/cn/hippo4j/agent/plugin/spring/common/support/ThreadPoolCheckAlarmSupport.java index 4cbd54e384..955f3bdbfd 100644 --- a/agent/hippo4j-agent-plugin/spring-plugins/spring-plugin-common/src/main/java/cn/hippo4j/agent/plugin/spring/common/support/ThreadPoolCheckAlarmSupport.java +++ b/agent/hippo4j-agent-plugin/spring-plugins/spring-plugin-common/src/main/java/cn/hippo4j/agent/plugin/spring/common/support/ThreadPoolCheckAlarmSupport.java @@ -108,8 +108,8 @@ private static void initializeEnvironmentProperties() { EnvironmentProperties.active = SpringBootConfig.Spring.Profiles.active; ConfigurableEnvironment environment = ApplicationContextHolder.getBean(ConfigurableEnvironment.class); InetUtilsProperties inetUtilsProperties = SpringPropertyBinder.bindProperties(environment, InetUtilsProperties.PREFIX, InetUtilsProperties.class); - InetUtils inetUtils = new InetUtils(inetUtilsProperties); - IdentifyUtil.generate(environment, inetUtils); + SpringPropertiesLoader.inetUtils = new InetUtils(inetUtilsProperties); + IdentifyUtil.generate(environment, SpringPropertiesLoader.inetUtils); } /** diff --git a/agent/hippo4j-agent-plugin/spring-plugins/spring-plugin-common/src/main/java/cn/hippo4j/agent/plugin/spring/common/support/ThreadPoolMonitorSupport.java b/agent/hippo4j-agent-plugin/spring-plugins/spring-plugin-common/src/main/java/cn/hippo4j/agent/plugin/spring/common/support/ThreadPoolMonitorSupport.java index d44dbf3d1f..a45c4fa977 100644 --- a/agent/hippo4j-agent-plugin/spring-plugins/spring-plugin-common/src/main/java/cn/hippo4j/agent/plugin/spring/common/support/ThreadPoolMonitorSupport.java +++ b/agent/hippo4j-agent-plugin/spring-plugins/spring-plugin-common/src/main/java/cn/hippo4j/agent/plugin/spring/common/support/ThreadPoolMonitorSupport.java @@ -98,7 +98,8 @@ public static void enableThreadPoolMonitorHandler(Environment environment) { // Determine whether the task is successfully enabled // return directly if it has been enabled, and do not start the thread pool repeatedly - if (Boolean.TRUE.equals(active.get())) return; + if (Boolean.TRUE.equals(active.get())) + return; // Expose metric endpoints based on the configured collect types List collectTypes = Arrays.asList(monitor.getCollectTypes().split(",")); @@ -107,7 +108,8 @@ public static void enableThreadPoolMonitorHandler(Environment environment) { } // Schedule periodic collection of metrics from the thread pools - collectScheduledExecutor.scheduleWithFixedDelay(scheduleRunnable(), monitor.getInitialDelay(), monitor.getCollectInterval(), TimeUnit.MILLISECONDS); + Runnable scheduledTask = scheduleRunnable(); + collectScheduledExecutor.scheduleWithFixedDelay(scheduledTask, monitor.getInitialDelay(), monitor.getCollectInterval(), TimeUnit.MILLISECONDS); active.set(true); if (ThreadPoolExecutorRegistry.getThreadPoolExecutorSize() > 0) { @@ -130,7 +132,7 @@ private static Runnable scheduleRunnable() { for (ThreadPoolMonitor each : threadPoolMonitors) { try { each.collect(); - } catch (Exception ex) { + } catch (Throwable ex) { LOGGER.error("[Hippo4j-Agent] Error monitoring the running status of dynamic thread pool. Type: {}", each.getType(), ex); } } diff --git a/agent/hippo4j-agent-plugin/threadpool-plugin/pom.xml b/agent/hippo4j-agent-plugin/threadpool-plugin/pom.xml index b571302ef1..16517f4c0a 100644 --- a/agent/hippo4j-agent-plugin/threadpool-plugin/pom.xml +++ b/agent/hippo4j-agent-plugin/threadpool-plugin/pom.xml @@ -16,7 +16,6 @@ cn.hippo4j hippo4j-threadpool-core ${project.version} - provided cn.hippo4j diff --git a/agent/hippo4j-agent-plugin/threadpool-plugin/src/main/java/cn/hippo4j/agent/plugin/thread/pool/interceptor/ThreadPoolExecutorConstructorMethodInterceptor.java b/agent/hippo4j-agent-plugin/threadpool-plugin/src/main/java/cn/hippo4j/agent/plugin/thread/pool/interceptor/ThreadPoolExecutorConstructorMethodInterceptor.java index fa4424a899..db1019d40f 100644 --- a/agent/hippo4j-agent-plugin/threadpool-plugin/src/main/java/cn/hippo4j/agent/plugin/thread/pool/interceptor/ThreadPoolExecutorConstructorMethodInterceptor.java +++ b/agent/hippo4j-agent-plugin/threadpool-plugin/src/main/java/cn/hippo4j/agent/plugin/thread/pool/interceptor/ThreadPoolExecutorConstructorMethodInterceptor.java @@ -52,7 +52,16 @@ public void onConstruct(EnhancedInstance objInst, Object[] allArguments) throws } StackTraceElement declaredClassStackTraceElement = stackTraceElements.get(0); String declaredClassName = declaredClassStackTraceElement.getClassName(); - Class declaredClass = Thread.currentThread().getContextClassLoader().loadClass(declaredClassName); + Class declaredClass = null; + try { + declaredClass = Thread.currentThread().getContextClassLoader().loadClass(declaredClassName); + } catch (ClassNotFoundException e) { + // The thread pool in the Agent plug-in is loaded by AgentclassLodaer. + // Due to the delegation model, it can only be searched upwards, so searching here will result in ClassNotFount. + // Because the parent of AgentClassLoader is AppclassLoder, it is ignored here ,skip the enhancement logic + LOGGER.debug("searching {} result in ClassNotFount , so skip the enhancement logic", declaredClassName); + return; + } ThreadPoolExecutorRegistry.REFERENCED_CLASS_MAP.put((ThreadPoolExecutor) objInst, declaredClass); } diff --git a/agent/pom.xml b/agent/pom.xml index ac0db6011b..18de9269a2 100644 --- a/agent/pom.xml +++ b/agent/pom.xml @@ -140,7 +140,6 @@ org.objenesis objenesis ${objenesis.version} - test com.github.tomakehurst diff --git a/examples/threadpool-example/agent/config-apollo-spring-boot-1x/src/main/resources/bootstrap.properties b/examples/threadpool-example/agent/config-apollo-spring-boot-1x/src/main/resources/bootstrap.properties index 7a6912062d..456739dfbf 100644 --- a/examples/threadpool-example/agent/config-apollo-spring-boot-1x/src/main/resources/bootstrap.properties +++ b/examples/threadpool-example/agent/config-apollo-spring-boot-1x/src/main/resources/bootstrap.properties @@ -13,9 +13,6 @@ env=dev apollo.configService=http://127.0.0.1:8080 spring.profiles.active=dev spring.application.name=hippo4j-config-apollo-spring-boot-starter-example -management.metrics.export.prometheus.enabled=true -management.server.port=29998 -management.endpoints.web.exposure.include=* spring.dynamic.thread-pool.enable=true spring.dynamic.thread-pool.banner=true @@ -25,6 +22,7 @@ spring.dynamic.thread-pool.monitor.collect-types=micrometer spring.dynamic.thread-pool.monitor.thread-pool-types=dynamic spring.dynamic.thread-pool.monitor.initial-delay=3000 spring.dynamic.thread-pool.monitor.collect-interval=3000 +spring.dynamic.thread-pool.monitor.agent-micrometer-port=29999 spring.dynamic.thread-pool.notify-platforms[0].platform=LARK spring.dynamic.thread-pool.notify-platforms[0].token=6de41bdc-0799-45be-b128-7cddb9e777f0 @@ -51,3 +49,17 @@ spring.dynamic.thread-pool.executors[0].active-alarm = 80 spring.dynamic.thread-pool.executors[0].capacity-alarm = 80 spring.dynamic.thread-pool.executors[0].notify.interval = 8 spring.dynamic.thread-pool.executors[0].notify.receives = nobodyiam +spring.dynamic.thread-pool.executors[1].thread-pool-id = runMessageSendTaskExecutor +spring.dynamic.thread-pool.executors[1].thread-name-prefix = runMessageSendTaskExecutor +spring.dynamic.thread-pool.executors[1].core-pool-size = 3 +spring.dynamic.thread-pool.executors[1].maximum-pool-size = 4 +spring.dynamic.thread-pool.executors[1].queue-capacity = 1024 +spring.dynamic.thread-pool.executors[1].blocking-queue = ResizableCapacityLinkedBlockingQueue +spring.dynamic.thread-pool.executors[1].execute-time-out = 800 +spring.dynamic.thread-pool.executors[1].rejected-handler = AbortPolicy +spring.dynamic.thread-pool.executors[1].keep-alive-time = 6691 +spring.dynamic.thread-pool.executors[1].allow-core-thread-time-out = true +spring.dynamic.thread-pool.executors[1].active-alarm = 80 +spring.dynamic.thread-pool.executors[1].capacity-alarm = 80 +spring.dynamic.thread-pool.executors[1].notify.interval = 8 +spring.dynamic.thread-pool.executors[1].notify.receives = nobodyiam diff --git a/examples/threadpool-example/agent/config-apollo/src/main/resources/bootstrap.properties b/examples/threadpool-example/agent/config-apollo/src/main/resources/bootstrap.properties index 7a6912062d..5192a76125 100644 --- a/examples/threadpool-example/agent/config-apollo/src/main/resources/bootstrap.properties +++ b/examples/threadpool-example/agent/config-apollo/src/main/resources/bootstrap.properties @@ -13,9 +13,6 @@ env=dev apollo.configService=http://127.0.0.1:8080 spring.profiles.active=dev spring.application.name=hippo4j-config-apollo-spring-boot-starter-example -management.metrics.export.prometheus.enabled=true -management.server.port=29998 -management.endpoints.web.exposure.include=* spring.dynamic.thread-pool.enable=true spring.dynamic.thread-pool.banner=true @@ -25,6 +22,7 @@ spring.dynamic.thread-pool.monitor.collect-types=micrometer spring.dynamic.thread-pool.monitor.thread-pool-types=dynamic spring.dynamic.thread-pool.monitor.initial-delay=3000 spring.dynamic.thread-pool.monitor.collect-interval=3000 +spring.dynamic.thread-pool.monitor.agent-micrometer-port=29999 spring.dynamic.thread-pool.notify-platforms[0].platform=LARK spring.dynamic.thread-pool.notify-platforms[0].token=6de41bdc-0799-45be-b128-7cddb9e777f0 @@ -51,3 +49,18 @@ spring.dynamic.thread-pool.executors[0].active-alarm = 80 spring.dynamic.thread-pool.executors[0].capacity-alarm = 80 spring.dynamic.thread-pool.executors[0].notify.interval = 8 spring.dynamic.thread-pool.executors[0].notify.receives = nobodyiam + +spring.dynamic.thread-pool.executors[1].thread-pool-id = runMessageSendTaskExecutor +spring.dynamic.thread-pool.executors[1].thread-name-prefix = runMessageSendTaskExecutor +spring.dynamic.thread-pool.executors[1].core-pool-size = 3 +spring.dynamic.thread-pool.executors[1].maximum-pool-size = 4 +spring.dynamic.thread-pool.executors[1].queue-capacity = 1024 +spring.dynamic.thread-pool.executors[1].blocking-queue = ResizableCapacityLinkedBlockingQueue +spring.dynamic.thread-pool.executors[1].execute-time-out = 800 +spring.dynamic.thread-pool.executors[1].rejected-handler = AbortPolicy +spring.dynamic.thread-pool.executors[1].keep-alive-time = 6691 +spring.dynamic.thread-pool.executors[1].allow-core-thread-time-out = true +spring.dynamic.thread-pool.executors[1].active-alarm = 80 +spring.dynamic.thread-pool.executors[1].capacity-alarm = 80 +spring.dynamic.thread-pool.executors[1].notify.interval = 8 +spring.dynamic.thread-pool.executors[1].notify.receives = nobodyiam diff --git a/examples/threadpool-example/agent/config-nacos-spring-boot-1x/src/main/resources/bootstrap.properties b/examples/threadpool-example/agent/config-nacos-spring-boot-1x/src/main/resources/bootstrap.properties index 4291d58202..a16da5c47a 100644 --- a/examples/threadpool-example/agent/config-nacos-spring-boot-1x/src/main/resources/bootstrap.properties +++ b/examples/threadpool-example/agent/config-nacos-spring-boot-1x/src/main/resources/bootstrap.properties @@ -11,7 +11,7 @@ spring.cloud.nacos.config.refresh.enabled=true spring.dynamic.thread-pool.enable=true spring.dynamic.thread-pool.banner=true -spring.dynamic.thread-pool.check-state-interval=10 +spring.dynamic.thread-pool.check-state-interval=3 spring.dynamic.thread-pool.monitor.enable=true spring.dynamic.thread-pool.monitor.collect-types=micrometer spring.dynamic.thread-pool.monitor.thread-pool-types=dynamic @@ -26,7 +26,6 @@ spring.dynamic.thread-pool.notify-platforms[0].token=6de41bdc-0799-45be-b128-7cd #spring.dynamic.thread-pool.notify-platforms[2].platform=DING #spring.dynamic.thread-pool.notify-platforms[2].token=56417ebba6a27ca352f0de77a2ae9da66d01f39610b5ee8a6033c60ef9071c55 -spring.dynamic.thread-pool.nacos.server-addr=127.0.0.1:8848 spring.dynamic.thread-pool.nacos.data-id=dynamic-threadpool-example-config spring.dynamic.thread-pool.nacos.group=DEFAULT_GROUP spring.dynamic.thread-pool.nacos.namespace=public @@ -58,3 +57,7 @@ spring.dynamic.thread-pool.executors[1].execute-time-out = 800 spring.dynamic.thread-pool.executors[1].rejected-handler = AbortPolicy spring.dynamic.thread-pool.executors[1].keep-alive-time = 6691 spring.dynamic.thread-pool.executors[1].allow-core-thread-time-out = true +spring.dynamic.thread-pool.executors[1].active-alarm = 80 +spring.dynamic.thread-pool.executors[1].capacity-alarm = 80 +spring.dynamic.thread-pool.executors[1].notify.interval = 8 +spring.dynamic.thread-pool.executors[1].notify.receives = nobodyiam diff --git a/examples/threadpool-example/agent/config-nacos/src/main/resources/bootstrap.properties b/examples/threadpool-example/agent/config-nacos/src/main/resources/bootstrap.properties index c9b6820e24..2486938794 100644 --- a/examples/threadpool-example/agent/config-nacos/src/main/resources/bootstrap.properties +++ b/examples/threadpool-example/agent/config-nacos/src/main/resources/bootstrap.properties @@ -32,7 +32,6 @@ spring.dynamic.thread-pool.notify-platforms[0].token=6de41bdc-0799-45be-b128-7cd #spring.dynamic.thread-pool.notify-platforms[2].platform=DING #spring.dynamic.thread-pool.notify-platforms[2].token=56417ebba6a27ca352f0de77a2ae9da66d01f39610b5ee8a6033c60ef9071c55 -spring.dynamic.thread-pool.nacos.server-addr=127.0.0.1:8848 spring.dynamic.thread-pool.nacos.data-id=dynamic-threadpool-example-config spring.dynamic.thread-pool.nacos.group=DEFAULT_GROUP spring.dynamic.thread-pool.nacos.namespace=public @@ -54,6 +53,7 @@ spring.dynamic.thread-pool.executors[0].active-alarm = 80 spring.dynamic.thread-pool.executors[0].capacity-alarm = 80 spring.dynamic.thread-pool.executors[0].notify.interval = 8 spring.dynamic.thread-pool.executors[0].notify.receives = nobodyiam + spring.dynamic.thread-pool.executors[1].thread-pool-id = runMessageSendTaskExecutor spring.dynamic.thread-pool.executors[1].thread-name-prefix = runMessageSendTaskExecutor spring.dynamic.thread-pool.executors[1].core-pool-size = 3 @@ -64,3 +64,7 @@ spring.dynamic.thread-pool.executors[1].execute-time-out = 800 spring.dynamic.thread-pool.executors[1].rejected-handler = AbortPolicy spring.dynamic.thread-pool.executors[1].keep-alive-time = 6691 spring.dynamic.thread-pool.executors[1].allow-core-thread-time-out = true +spring.dynamic.thread-pool.executors[1].active-alarm = 80 +spring.dynamic.thread-pool.executors[1].capacity-alarm = 80 +spring.dynamic.thread-pool.executors[1].notify.interval = 8 +spring.dynamic.thread-pool.executors[1].notify.receives = nobodyiam diff --git a/infra/common/src/main/java/cn/hippo4j/common/toolkit/http/HttpUtil.java b/infra/common/src/main/java/cn/hippo4j/common/toolkit/http/HttpUtil.java index 2f8a475e9d..fdd14c9bfa 100644 --- a/infra/common/src/main/java/cn/hippo4j/common/toolkit/http/HttpUtil.java +++ b/infra/common/src/main/java/cn/hippo4j/common/toolkit/http/HttpUtil.java @@ -31,10 +31,13 @@ import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; +import java.io.BufferedWriter; import java.io.OutputStream; +import java.io.OutputStreamWriter; import java.net.HttpURLConnection; import java.net.URL; import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; import java.util.Map; import java.util.Optional; @@ -198,6 +201,18 @@ public static String postJson(String url, String json) { return executeJson(url, HttpMethod.POST, json, null); } + /** + * Send a post network request. + * + * @param url target url + * @param json json data + * @param headers headers + * @return + */ + public static String postJson(String url, String json, Map headers) { + return executeJson(url, HttpMethod.POST, json, headers); + } + /** * Send a put network request. * @@ -310,8 +325,10 @@ private static HttpClientResponse doExecute(HttpURLConnection connection, Object byte[] b = bodyString.getBytes(); connection.setRequestProperty(CONTENT_LENGTH, String.valueOf(b.length)); OutputStream outputStream = connection.getOutputStream(); - outputStream.write(b, 0, b.length); - outputStream.flush(); + OutputStreamWriter osw = new OutputStreamWriter(outputStream, StandardCharsets.UTF_8); + BufferedWriter writer = new BufferedWriter(osw); + writer.write(bodyString); + writer.flush(); IoUtil.closeQuietly(outputStream); } connection.connect(); diff --git a/kernel/alarm/src/main/java/cn/hippo4j/threadpool/alarm/handler/DefaultThreadPoolCheckAlarmHandler.java b/kernel/alarm/src/main/java/cn/hippo4j/threadpool/alarm/handler/DefaultThreadPoolCheckAlarmHandler.java index 0f6cba86b4..98947939c0 100644 --- a/kernel/alarm/src/main/java/cn/hippo4j/threadpool/alarm/handler/DefaultThreadPoolCheckAlarmHandler.java +++ b/kernel/alarm/src/main/java/cn/hippo4j/threadpool/alarm/handler/DefaultThreadPoolCheckAlarmHandler.java @@ -239,9 +239,6 @@ public AlarmNotifyRequest buildAlarmNotifyRequest(ThreadPoolExecutor threadPoolE /** * Terminates the scheduled tasks and asynchronous alarm notifications by * forcefully shutting down the respective thread pools. - * - * @see alarmNotifyExecutor - * @see asyncAlarmNotifyExecutor */ public void destroyScheduleExecute() { alarmNotifyExecutor.shutdownNow(); diff --git a/kernel/dynamic/mode/config/src/main/java/cn/hippo4j/threadpool/dynamic/mode/config/parser/JsonConfigParser.java b/kernel/dynamic/mode/config/src/main/java/cn/hippo4j/threadpool/dynamic/mode/config/parser/JsonConfigParser.java index c0acf1d967..bb24706824 100644 --- a/kernel/dynamic/mode/config/src/main/java/cn/hippo4j/threadpool/dynamic/mode/config/parser/JsonConfigParser.java +++ b/kernel/dynamic/mode/config/src/main/java/cn/hippo4j/threadpool/dynamic/mode/config/parser/JsonConfigParser.java @@ -34,6 +34,7 @@ * Json config parser. */ public class JsonConfigParser extends AbstractConfigParser { + private static final ObjectMapper MAPPER; private static final String DOT = "."; private static final String LEFT_BRACE = "{"; @@ -91,7 +92,7 @@ public Map doParse(String content) throws IOException { return new HashMap<>(1); } - return doParse(content,""); + return doParse(content, ""); } @Override diff --git a/kernel/message/core/src/main/java/cn/hippo4j/threadpool/message/core/platform/LarkSendMessageHandler.java b/kernel/message/core/src/main/java/cn/hippo4j/threadpool/message/core/platform/LarkSendMessageHandler.java index 4e43da9ffa..ff1e8a0b98 100644 --- a/kernel/message/core/src/main/java/cn/hippo4j/threadpool/message/core/platform/LarkSendMessageHandler.java +++ b/kernel/message/core/src/main/java/cn/hippo4j/threadpool/message/core/platform/LarkSendMessageHandler.java @@ -43,6 +43,8 @@ import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; import java.util.Objects; import java.util.stream.Collectors; @@ -154,7 +156,9 @@ private String getReceives(String receives) { private void execute(String secretKey, String text) { String serverUrl = LarkAlarmConstants.LARK_BOT_URL + secretKey; try { - String responseBody = HttpUtil.postJson(serverUrl, text); + Map headers = new HashMap<>(); + headers.put("Content-Type", "application/json; charset=UTF-8"); + String responseBody = HttpUtil.postJson(serverUrl, text, headers); LarkRobotResponse response = JSONUtil.parseObject(responseBody, LarkRobotResponse.class); Assert.isTrue(response != null, "Response is null."); if (response.getCode() != 0) { diff --git a/kernel/message/core/src/main/java/cn/hippo4j/threadpool/message/core/service/SendMessageHandler.java b/kernel/message/core/src/main/java/cn/hippo4j/threadpool/message/core/service/SendMessageHandler.java index 5a8b063034..d5619b9d7e 100644 --- a/kernel/message/core/src/main/java/cn/hippo4j/threadpool/message/core/service/SendMessageHandler.java +++ b/kernel/message/core/src/main/java/cn/hippo4j/threadpool/message/core/service/SendMessageHandler.java @@ -17,12 +17,11 @@ package cn.hippo4j.threadpool.message.core.service; +import cn.hippo4j.threadpool.message.api.NotifyConfigDTO; import cn.hippo4j.threadpool.message.core.request.AlarmNotifyRequest; import cn.hippo4j.threadpool.message.core.request.ChangeParameterNotifyRequest; import cn.hippo4j.threadpool.message.core.request.WebChangeParameterNotifyRequest; -import cn.hippo4j.threadpool.message.api.NotifyConfigDTO; import lombok.SneakyThrows; -import org.springframework.core.io.ClassPathResource; import java.io.BufferedInputStream; import java.io.ByteArrayOutputStream; @@ -70,9 +69,9 @@ default void sendWebChangeMessage(NotifyConfigDTO notifyConfig, WebChangeParamet default String readUtf8String(String path) { int endFlagCode = -1; String resultReadStr; - ClassPathResource classPathResource = new ClassPathResource(path); + ClassLoader classLoader = this.getClass().getClassLoader(); try ( - InputStream inputStream = classPathResource.getInputStream(); + InputStream inputStream = classLoader.getResourceAsStream(path); BufferedInputStream bis = new BufferedInputStream(inputStream); ByteArrayOutputStream buf = new ByteArrayOutputStream()) { int result = bis.read(); diff --git a/threadpool/core/src/test/java/cn/hippo4j/core/adapter/ZipkinExecutorAdapterTest.java b/threadpool/core/src/test/java/cn/hippo4j/core/adapter/ZipkinExecutorAdapterTest.java index eb27eec4c9..f34f320706 100644 --- a/threadpool/core/src/test/java/cn/hippo4j/core/adapter/ZipkinExecutorAdapterTest.java +++ b/threadpool/core/src/test/java/cn/hippo4j/core/adapter/ZipkinExecutorAdapterTest.java @@ -68,7 +68,7 @@ public void testUnwrap() { @Test public void testReplace() { Object executor = new CustomWrappingExecutorService(Executors.newCachedThreadPool()); - CustomWrappingExecutorService executorChange = (CustomWrappingExecutorService)executor; + CustomWrappingExecutorService executorChange = (CustomWrappingExecutorService) executor; ExecutorService beforeReplace = executorChange.delegate(); zipkinExecutorAdapter.replace(executor, dynamicThreadPool); ExecutorService afterReplace = executorChange.delegate();