mirror of https://github.com/longtai-cn/hippo4j
parent
92dec458b2
commit
7b8a43175a
@ -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<String> 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<String, Object> 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<Object, Object> configInfo) {
|
|
||||||
BootstrapConfigProperties bindableBootstrapConfigProperties = new BootstrapConfigProperties();
|
|
||||||
ConfigurationPropertySource sources = new MapConfigurationPropertySource(configInfo);
|
|
||||||
Binder binder = new Binder(sources);
|
|
||||||
return binder.bind(BootstrapConfigProperties.PREFIX, Bindable.ofInstance(bindableBootstrapConfigProperties)).get();
|
|
||||||
}
|
|
||||||
}
|
|
@ -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.
|
|
||||||
* <p>
|
|
||||||
* 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.
|
|
||||||
* <p>
|
|
||||||
* 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.
|
|
||||||
* <p>
|
|
||||||
* 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<String, Object> changeValueMap = new HashMap<>();
|
|
||||||
try {
|
|
||||||
// Parse the configuration and map the values to the appropriate keys
|
|
||||||
Map<Object, Object> 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.
|
|
||||||
* <p>
|
|
||||||
* 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<Object, Object> configInfo) {
|
|
||||||
BootstrapConfigProperties bindableBootstrapConfigProperties = new BootstrapConfigProperties();
|
|
||||||
ConfigurationPropertySource sources = new MapConfigurationPropertySource(configInfo);
|
|
||||||
Binder binder = new Binder(sources);
|
|
||||||
return binder.bind(BootstrapConfigProperties.PREFIX, Bindable.ofInstance(bindableBootstrapConfigProperties)).get();
|
|
||||||
}
|
|
||||||
}
|
|
@ -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 = "";
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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 = "";
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in new issue