mirror of https://github.com/longtai-cn/hippo4j
parent
1d8d116877
commit
a043504e89
@ -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