diff --git a/sermant-agentcore/sermant-agentcore-core/src/main/java/com/huaweicloud/sermant/core/AgentCoreEntrance.java b/sermant-agentcore/sermant-agentcore-core/src/main/java/com/huaweicloud/sermant/core/AgentCoreEntrance.java index cb651ead6e..590b1a4f1d 100644 --- a/sermant-agentcore/sermant-agentcore-core/src/main/java/com/huaweicloud/sermant/core/AgentCoreEntrance.java +++ b/sermant-agentcore/sermant-agentcore-core/src/main/java/com/huaweicloud/sermant/core/AgentCoreEntrance.java @@ -27,11 +27,14 @@ import com.huaweicloud.sermant.core.notification.NotificationManager; import com.huaweicloud.sermant.core.notification.SermantNotificationType; import com.huaweicloud.sermant.core.operation.OperationManager; +import com.huaweicloud.sermant.core.plugin.PluginManager; import com.huaweicloud.sermant.core.plugin.PluginSystemEntrance; import com.huaweicloud.sermant.core.plugin.agent.ByteEnhanceManager; +import com.huaweicloud.sermant.core.plugin.agent.adviser.AdviserInterface; import com.huaweicloud.sermant.core.plugin.agent.adviser.AdviserScheduler; import com.huaweicloud.sermant.core.plugin.agent.template.DefaultAdviser; import com.huaweicloud.sermant.core.service.ServiceManager; +import com.huaweicloud.sermant.god.common.SermantManager; import java.lang.instrument.Instrumentation; import java.util.Map; @@ -53,6 +56,16 @@ public class AgentCoreEntrance { */ private static int agentType = AgentType.PREMAIN.getValue(); + /** + * 缓存当前Agent的产品名 + */ + private static String artifactCache; + + /** + * 缓存当前Agent的adviser + */ + private static AdviserInterface adviserCache; + private AgentCoreEntrance() { } @@ -70,6 +83,8 @@ public static void install(String artifact, Map argsMap, Instrum if (isDynamic) { agentType = AgentType.AGENTMAIN.getValue(); } + artifactCache = artifact; + adviserCache = new DefaultAdviser(); // 初始化框架类加载器 ClassLoaderManager.init(argsMap); @@ -99,9 +114,9 @@ public static void install(String artifact, Map argsMap, Instrum PluginSystemEntrance.initialize(isDynamic); // 注册Adviser - AdviserScheduler.registry(new DefaultAdviser()); + AdviserScheduler.registry(adviserCache); - // 增强静态插件 + // 静态插件在全部加载结束后,统一增强,复用一个AgentBuilder if (!isDynamic) { ByteEnhanceManager.enhance(); } @@ -118,11 +133,32 @@ public static void install(String artifact, Map argsMap, Instrum /** * 卸载当前Sermant */ - public static void unInstall() { + public static void uninstall() { if (isPremain()) { LOGGER.log(Level.WARNING, "Sermant are not allowed to be uninstall when booting through premain."); return; } + + // 在Adviser调度器中取消注册当前Agent的Adviser + AdviserScheduler.unRegistry(adviserCache); + + // 卸载全部的插件 + PluginManager.uninstallAll(); + + // 关闭事件系统 + EventManager.shutdown(); + + // 关闭所有服务 + ServiceManager.shutdown(); + + // 清理操作类 + OperationManager.shutdown(); + + // 清理配置类 + ConfigManager.shutdown(); + + // 设置该artifact的Sermant状态为false,非运行状态 + SermantManager.updateSermantStatus(artifactCache, false); } /** diff --git a/sermant-agentcore/sermant-agentcore-core/src/main/java/com/huaweicloud/sermant/core/command/AgentUnInstallCommandExecutor.java b/sermant-agentcore/sermant-agentcore-core/src/main/java/com/huaweicloud/sermant/core/command/AgentUnInstallCommandExecutor.java index c648dc72b9..8372fc49e5 100644 --- a/sermant-agentcore/sermant-agentcore-core/src/main/java/com/huaweicloud/sermant/core/command/AgentUnInstallCommandExecutor.java +++ b/sermant-agentcore/sermant-agentcore-core/src/main/java/com/huaweicloud/sermant/core/command/AgentUnInstallCommandExecutor.java @@ -27,6 +27,6 @@ public class AgentUnInstallCommandExecutor implements CommandExecutor { @Override public void execute(String args) { - AgentCoreEntrance.unInstall(); + AgentCoreEntrance.uninstall(); } } diff --git a/sermant-agentcore/sermant-agentcore-core/src/main/java/com/huaweicloud/sermant/core/command/PluginsUnInstallCommandExecutor.java b/sermant-agentcore/sermant-agentcore-core/src/main/java/com/huaweicloud/sermant/core/command/PluginsUnInstallCommandExecutor.java index 1f325fb2ea..43d72247da 100644 --- a/sermant-agentcore/sermant-agentcore-core/src/main/java/com/huaweicloud/sermant/core/command/PluginsUnInstallCommandExecutor.java +++ b/sermant-agentcore/sermant-agentcore-core/src/main/java/com/huaweicloud/sermant/core/command/PluginsUnInstallCommandExecutor.java @@ -41,6 +41,6 @@ public void execute(String args) { return; } String[] pluginNames = args.split("\\|"); - PluginManager.unInstall(Arrays.stream(pluginNames).collect(Collectors.toSet())); + PluginManager.uninstall(Arrays.stream(pluginNames).collect(Collectors.toSet())); } } diff --git a/sermant-agentcore/sermant-agentcore-core/src/main/java/com/huaweicloud/sermant/core/config/ConfigManager.java b/sermant-agentcore/sermant-agentcore-core/src/main/java/com/huaweicloud/sermant/core/config/ConfigManager.java index d15e5dccc2..4c548dccc4 100644 --- a/sermant-agentcore/sermant-agentcore-core/src/main/java/com/huaweicloud/sermant/core/config/ConfigManager.java +++ b/sermant-agentcore/sermant-agentcore-core/src/main/java/com/huaweicloud/sermant/core/config/ConfigManager.java @@ -24,7 +24,9 @@ import com.huaweicloud.sermant.core.config.utils.ConfigKeyUtil; import java.io.File; +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Locale; import java.util.Map; import java.util.ServiceLoader; @@ -48,12 +50,19 @@ public abstract class ConfigManager { * 配置对象集合,键为配置对象的实现类Class,值为加载完毕的配置对象 *

通过{@link #getConfig(Class)}方法获取配置对象 */ - private static final Map CONFIG_MAP = new HashMap(); + private static final Map CONFIG_MAP = new HashMap<>(); - private static final Iterable LOAD_CONFIG_STRATEGIES = - ServiceLoader.load(LoadConfigStrategy.class, ClassLoaderManager.getFrameworkClassLoader()); + private static final List LOAD_CONFIG_STRATEGIES = new ArrayList<>(); - private static Map argsMap = null; + private static Map argsMap; + + /** + * 关闭配置管理器 + */ + public static void shutdown() { + CONFIG_MAP.clear(); + LOAD_CONFIG_STRATEGIES.clear(); + } /** * 通过配置对象类型获取配置对象 @@ -84,31 +93,33 @@ public static R getConfig(Class cls) { */ public static synchronized void initialize(Map args) { argsMap = args; - loadConfig(BootArgsIndexer.getConfigFile(), BaseConfig.class, ClassLoaderManager.getSermantClassLoader()); + for (LoadConfigStrategy strategy : ServiceLoader.load(LoadConfigStrategy.class, + ClassLoaderManager.getFrameworkClassLoader())) { + LOAD_CONFIG_STRATEGIES.add(strategy); + } + loadConfig(BootArgsIndexer.getConfigFile(), ClassLoaderManager.getSermantClassLoader()); } /** * 加载配置文件,将配置信息读取到配置对象中 * * @param configFile 配置文件 - * @param baseCls 配置对象的基类,该参数决定spi操作的源 * @param classLoader 类加载器,该参数决定从哪个classLoader中进行api操作 */ - protected static void loadConfig(File configFile, Class baseCls, ClassLoader classLoader) { + protected static void loadConfig(File configFile, ClassLoader classLoader) { if (configFile.exists() && configFile.isFile()) { - doLoadConfig(configFile, baseCls, classLoader); + doLoadConfig(configFile, classLoader); } else { - loadDefaultConfig(baseCls, classLoader); + loadDefaultConfig(classLoader); } } /** * 加载默认配置 * - * @param baseCls 配置对象的基类,该参数决定spi操作的源 * @param classLoader 类加载器,该参数决定从哪个classLoader中进行api操作 */ - private static synchronized void loadDefaultConfig(Class baseCls, ClassLoader classLoader) { + private static synchronized void loadDefaultConfig(ClassLoader classLoader) { foreachConfig(new ConfigConsumer() { @Override public void accept(BaseConfig config) { @@ -117,39 +128,45 @@ public void accept(BaseConfig config) { CONFIG_MAP.put(typeKey, config); } } - }, baseCls, classLoader); + }, classLoader); } /** * 配置执行从配置文件中加载 * * @param configFile 配置文件 - * @param baseCls 配置对象的基类,该参数决定spi操作的源 * @param classLoader 类加载器,当前配置加载策略api在agentcore-implement包中,所以使用FrameworkClassLoader加载 */ - private static synchronized void doLoadConfig(File configFile, Class baseCls, + private static synchronized void doLoadConfig(File configFile, ClassLoader classLoader) { + foreachConfig(config -> { + final String typeKey = ConfigKeyUtil.getTypeKey(config.getClass()); + final BaseConfig retainedConfig = CONFIG_MAP.get(typeKey); + if (retainedConfig == null) { + CONFIG_MAP.put(typeKey, doLoad(configFile, config)); + } else if (retainedConfig.getClass() == config.getClass()) { + LOGGER.fine(String.format(Locale.ROOT, "Skip load config [%s] repeatedly. ", + config.getClass().getName())); + } else { + LOGGER.warning(String.format(Locale.ROOT, "Type key of %s is %s, same as %s's. ", + config.getClass().getName(), typeKey, retainedConfig.getClass().getName())); + } + }, classLoader); + } + + /** + * 加载配置逻辑 + * + * @param configFile 配置文件 + * @param baseConfig 配置类 + * @return 加载后的配置类 + */ + public static BaseConfig doLoad(File configFile, BaseConfig baseConfig) { // 通过FrameworkClassLoader 获取配置加载策略 - final LoadConfigStrategy loadConfigStrategy = - getLoadConfigStrategy(configFile, ClassLoaderManager.getFrameworkClassLoader()); + final LoadConfigStrategy loadConfigStrategy = getLoadConfigStrategy(configFile, + ClassLoaderManager.getFrameworkClassLoader()); final Object holder = loadConfigStrategy.getConfigHolder(configFile, argsMap); - foreachConfig(new ConfigConsumer() { - @Override - public void accept(BaseConfig config) { - final String typeKey = ConfigKeyUtil.getTypeKey(config.getClass()); - final BaseConfig retainedConfig = CONFIG_MAP.get(typeKey); - if (retainedConfig == null) { - CONFIG_MAP.put(typeKey, ((LoadConfigStrategy) loadConfigStrategy).loadConfig(holder, config)); - } else if (retainedConfig.getClass() == config.getClass()) { - LOGGER.fine( - String.format(Locale.ROOT, "Skip load config [%s] repeatedly. ", - config.getClass().getName())); - } else { - LOGGER.warning(String.format(Locale.ROOT, "Type key of %s is %s, same as %s's. ", - config.getClass().getName(), typeKey, retainedConfig.getClass().getName())); - } - } - }, baseCls, classLoader); + return ((LoadConfigStrategy) loadConfigStrategy).loadConfig(holder, baseConfig); } /** @@ -176,8 +193,9 @@ private static LoadConfigStrategy getLoadConfigStrategy(File configFile, Clas } } } - LOGGER.log(Level.WARNING, String.format(Locale.ROOT, "Missing implement of [%s], use [%s].", - LoadConfigStrategy.class.getName(), LoadConfigStrategy.DefaultLoadConfigStrategy.class.getName())); + LOGGER.log(Level.WARNING, + String.format(Locale.ROOT, "Missing implement of [%s], use [%s].", LoadConfigStrategy.class.getName(), + LoadConfigStrategy.DefaultLoadConfigStrategy.class.getName())); return new LoadConfigStrategy.DefaultLoadConfigStrategy(); } @@ -188,9 +206,9 @@ private static LoadConfigStrategy getLoadConfigStrategy(File configFile, Clas * * @param configConsumer 配置处理方法 */ - private static void foreachConfig(ConfigConsumer configConsumer, Class baseCls, + private static void foreachConfig(ConfigConsumer configConsumer, ClassLoader classLoader) { - for (BaseConfig config : ServiceLoader.load(baseCls, classLoader)) { + for (BaseConfig config : ServiceLoader.load((Class) BaseConfig.class, classLoader)) { configConsumer.accept(config); } } diff --git a/sermant-agentcore/sermant-agentcore-core/src/main/java/com/huaweicloud/sermant/core/event/EventManager.java b/sermant-agentcore/sermant-agentcore-core/src/main/java/com/huaweicloud/sermant/core/event/EventManager.java index 3dea074b15..7705bd393a 100644 --- a/sermant-agentcore/sermant-agentcore-core/src/main/java/com/huaweicloud/sermant/core/event/EventManager.java +++ b/sermant-agentcore/sermant-agentcore-core/src/main/java/com/huaweicloud/sermant/core/event/EventManager.java @@ -43,10 +43,7 @@ public class EventManager { private static final ConcurrentHashMap EVENT_COLLECTORS = new ConcurrentHashMap<>(); - private static final ScheduledExecutorService EXECUTOR_SERVICE = - Executors.newScheduledThreadPool(1, new ThreadFactoryUtils("event-collect-task")); - - private static final EventConfig EVENT_CONFIG = ConfigManager.getConfig(EventConfig.class); + private static ScheduledExecutorService executorService; private static final long INITIAL_DELAY = 30000L; @@ -57,11 +54,15 @@ private EventManager() { * 初始化,创建定时任务,定时上报事件 */ public static void init() { - if (!EVENT_CONFIG.isEnable()) { - LOGGER.info("Event is not enable."); + EventConfig eventConfig = ConfigManager.getConfig(EventConfig.class); + if (!eventConfig.isEnable()) { + LOGGER.info("Event is not enabled."); return; } + // 创建定时采集事件线程 + executorService = Executors.newScheduledThreadPool(1, new ThreadFactoryUtils("event-collect-task")); + // 初始化事件发送 EventSender.init(); @@ -72,7 +73,7 @@ public static void init() { EventManager.registerCollector(LogEventCollector.getInstance()); // 开启定时采集上报事件消息 - EXECUTOR_SERVICE.scheduleAtFixedRate(EventManager::collectAll, INITIAL_DELAY, EVENT_CONFIG.getSendInterval(), + executorService.scheduleAtFixedRate(EventManager::collectAll, INITIAL_DELAY, eventConfig.getSendInterval(), TimeUnit.MILLISECONDS); } @@ -80,7 +81,16 @@ public static void init() { * 在程序终止时上报在内存中的事件 */ public static void shutdown() { + // 关闭定时采集事件线程 + if (executorService != null) { + executorService.shutdown(); + } + + // 采集全部事件并上报 collectAll(); + + // 清空注册的事件收集器 + EVENT_COLLECTORS.clear(); } /** diff --git a/sermant-agentcore/sermant-agentcore-core/src/main/java/com/huaweicloud/sermant/core/operation/OperationManager.java b/sermant-agentcore/sermant-agentcore-core/src/main/java/com/huaweicloud/sermant/core/operation/OperationManager.java index 410e2a2af1..f3d7f2c178 100644 --- a/sermant-agentcore/sermant-agentcore-core/src/main/java/com/huaweicloud/sermant/core/operation/OperationManager.java +++ b/sermant-agentcore/sermant-agentcore-core/src/main/java/com/huaweicloud/sermant/core/operation/OperationManager.java @@ -41,7 +41,7 @@ private OperationManager() { */ public static void initOperations() { for (final BaseOperation operation : ServiceLoader.load(BaseOperation.class, - ClassLoaderManager.getFrameworkClassLoader())) { + ClassLoaderManager.getFrameworkClassLoader())) { loadOperation(operation, operation.getClass(), BaseOperation.class); } } @@ -57,7 +57,7 @@ public static void initOperations() { public static T getOperation(Class operationClass) { final BaseOperation baseOperation = OPERATIONS.get(operationClass.getName()); if (baseOperation != null && operationClass.isAssignableFrom(baseOperation.getClass())) { - return (T)baseOperation; + return (T) baseOperation; } throw new IllegalArgumentException("Operation instance of [" + operationClass + "] is not found. "); } @@ -71,7 +71,7 @@ public static T getOperation(Class operationClass) * @return 是否加载成功 */ private static boolean loadOperation(BaseOperation operation, Class operationCls, - Class baseCls) { + Class baseCls) { if (operationCls == null || operationCls == baseCls || !baseCls.isAssignableFrom(operationCls)) { return false; } @@ -94,4 +94,11 @@ private static boolean loadOperation(BaseOperation operation, Class operation } return isLoadSucceed; } + + /** + * 关闭OperationManager + */ + public static void shutdown() { + OPERATIONS.clear(); + } } diff --git a/sermant-agentcore/sermant-agentcore-core/src/main/java/com/huaweicloud/sermant/core/plugin/PluginManager.java b/sermant-agentcore/sermant-agentcore-core/src/main/java/com/huaweicloud/sermant/core/plugin/PluginManager.java index ca31c8927d..ddcd0a2bde 100644 --- a/sermant-agentcore/sermant-agentcore-core/src/main/java/com/huaweicloud/sermant/core/plugin/PluginManager.java +++ b/sermant-agentcore/sermant-agentcore-core/src/main/java/com/huaweicloud/sermant/core/plugin/PluginManager.java @@ -16,18 +16,21 @@ package com.huaweicloud.sermant.core.plugin; -import com.huaweicloud.sermant.core.AgentCoreEntrance; import com.huaweicloud.sermant.core.classloader.ClassLoaderManager; import com.huaweicloud.sermant.core.common.BootArgsIndexer; import com.huaweicloud.sermant.core.common.LoggerFactory; import com.huaweicloud.sermant.core.event.collector.FrameworkEventCollector; import com.huaweicloud.sermant.core.exception.SchemaException; import com.huaweicloud.sermant.core.plugin.agent.ByteEnhanceManager; +import com.huaweicloud.sermant.core.plugin.agent.adviser.AdviserScheduler; +import com.huaweicloud.sermant.core.plugin.agent.interceptor.Interceptor; +import com.huaweicloud.sermant.core.plugin.agent.template.BaseAdviseHandler; import com.huaweicloud.sermant.core.plugin.classloader.ServiceClassLoader; import com.huaweicloud.sermant.core.plugin.common.PluginConstant; import com.huaweicloud.sermant.core.plugin.common.PluginSchemaValidator; import com.huaweicloud.sermant.core.plugin.config.PluginConfigManager; import com.huaweicloud.sermant.core.plugin.service.PluginServiceManager; +import com.huaweicloud.sermant.core.utils.CollectionUtils; import java.io.File; import java.io.FileFilter; @@ -68,33 +71,70 @@ private PluginManager() { /** * 安装插件 * - * @param plugins 插件名集合,插件产物需要存在于pluginPackage中,否则无法安装成功 + * @param pluginNames 插件名集合,插件产物需要存在于pluginPackage中,否则无法安装成功 */ - public static void install(Set plugins) { - if (AgentCoreEntrance.isPremain()) { - LOGGER.log(Level.WARNING, "Plugins are not allowed to be installed when booting through premain."); - return; - } - initPlugins(plugins, true); + public static void install(Set pluginNames) { + initPlugins(pluginNames, true); } /** * 卸载插件 * - * @param plugins 插件名集合 + * @param pluginNames 插件名集合 */ - public static void unInstall(Set plugins) { - if (AgentCoreEntrance.isPremain()) { - LOGGER.log(Level.WARNING, "Plugins are not allowed to be uninstalled when booting through premain."); + public static void uninstall(Set pluginNames) { + if (CollectionUtils.isEmpty(pluginNames)) { + LOGGER.log(Level.WARNING, "No plugin is configured to be uninstall."); return; } + for (String name : pluginNames) { + Plugin plugin = PLUGIN_MAP.get(name); + if (plugin == null) { + LOGGER.log(Level.INFO, "Plugin {0} has not been installed.", name); + continue; + } + if (!plugin.isDynamic()) { + LOGGER.log(Level.INFO, "Plugin {0} is static-support-plugin,can not be uninstalled.", name); + continue; + } + + // 释放所有的插件占用的锁 + for (String adviceKey : plugin.getAdviceLocks()) { + AdviserScheduler.unLock(adviceKey); + } + + // 取消字节码增强 + ByteEnhanceManager.unEnhanceDynamicPlugin(plugin); + + // 关闭插件服务 + PluginServiceManager.shutdownPluginServices(plugin); + + // 移除PluginClassLoaderFinder中plugin对应的PluginClassLoader + ClassLoaderManager.getPluginClassFinder().removePluginClassLoader(plugin); + + // 清理该插件创建的Interceptor + Map> interceptorListMap = BaseAdviseHandler.getInterceptorListMap(); + for (List interceptors : interceptorListMap.values()) { + interceptors.removeIf( + interceptor -> plugin.getPluginClassLoader().equals(interceptor.getClass().getClassLoader())); + } + + // 删除缓存的插件配置 + PluginConfigManager.cleanPluginConfigs(plugin); + + // 关闭插件的ClassLoader + closePluginLoaders(plugin); + + // 从插件Map中清除该插件 + PLUGIN_MAP.remove(name); + } } /** * 卸载全部插件 */ - public static void unInstallAll() { - + public static void uninstallAll() { + uninstall(PLUGIN_MAP.keySet()); } /** @@ -139,8 +179,8 @@ public static void initPlugins(Set pluginNames, boolean isDynamic) { private static void doInitPlugin(Plugin plugin) { loadPluginLibs(plugin); loadServiceLibs(plugin); - PluginConfigManager.loadPluginConfig(plugin); - PluginServiceManager.initPluginService(plugin); + PluginConfigManager.loadPluginConfigs(plugin); + PluginServiceManager.initPluginServices(plugin); // 适配逻辑,类加载器需要在字节码增强前加入到插件类检索器中,否则可能会在字节码增强时,找不到拦截器 ClassLoaderManager.getPluginClassFinder().addPluginClassLoader(plugin); @@ -307,6 +347,19 @@ private static File getServiceDir(String pluginPath) { return new File(pluginPath + File.separatorChar + PluginConstant.SERVICE_DIR_NAME); } + private static void closePluginLoaders(Plugin plugin) { + try { + plugin.getServiceClassLoader().close(); + } catch (IOException e) { + LOGGER.log(Level.SEVERE, "Failed to close ServiceClassLoader for plugin:{0}", plugin.getName()); + } + try { + plugin.getPluginClassLoader().close(); + } catch (IOException e) { + LOGGER.log(Level.SEVERE, "Failed to close PluginClassLoader for plugin:{0}", plugin.getName()); + } + } + /** * JarFile消费者 * diff --git a/sermant-agentcore/sermant-agentcore-core/src/main/java/com/huaweicloud/sermant/core/plugin/config/PluginConfigManager.java b/sermant-agentcore/sermant-agentcore-core/src/main/java/com/huaweicloud/sermant/core/plugin/config/PluginConfigManager.java index d25a095a9f..a9e3613ad8 100644 --- a/sermant-agentcore/sermant-agentcore-core/src/main/java/com/huaweicloud/sermant/core/plugin/config/PluginConfigManager.java +++ b/sermant-agentcore/sermant-agentcore-core/src/main/java/com/huaweicloud/sermant/core/plugin/config/PluginConfigManager.java @@ -19,10 +19,18 @@ import static com.huaweicloud.sermant.core.plugin.common.PluginConstant.CONFIG_DIR_NAME; import static com.huaweicloud.sermant.core.plugin.common.PluginConstant.CONFIG_FILE_NAME; +import com.huaweicloud.sermant.core.common.LoggerFactory; import com.huaweicloud.sermant.core.config.ConfigManager; +import com.huaweicloud.sermant.core.config.common.BaseConfig; +import com.huaweicloud.sermant.core.config.utils.ConfigKeyUtil; import com.huaweicloud.sermant.core.plugin.Plugin; import java.io.File; +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; +import java.util.ServiceLoader; +import java.util.logging.Logger; /** * 插件配置管理器,${ConfigManager}统一配置管理器的特化,专门用来加载插件包配置和插件服务包配置 @@ -31,27 +39,64 @@ * @version 1.0.0 * @since 2021-11-12 */ -public class PluginConfigManager extends ConfigManager { +public class PluginConfigManager { + /** + * 日志 + */ + private static final Logger LOGGER = LoggerFactory.getLogger(); + + /** + * 配置对象集合,键为配置对象的实现类Class,值为加载完毕的配置对象 + */ + private static final Map PLUGIN_CONFIG_MAP = new HashMap<>(); + + private PluginConfigManager() { + } + /** * 加载插件配置 * * @param plugin 插件 */ - public static void loadPluginConfig(Plugin plugin) { + public static void loadPluginConfigs(Plugin plugin) { File pluginConfigFile = getPluginConfigFile(plugin.getPath()); ClassLoader classLoader = plugin.getServiceClassLoader() != null ? plugin.getServiceClassLoader() : plugin.getPluginClassLoader(); - loadServiceConfig(pluginConfigFile, classLoader); + for (BaseConfig config : ServiceLoader.load(PluginConfig.class, classLoader)) { + final String typeKey = ConfigKeyUtil.getTypeKey(config.getClass()); + final BaseConfig retainedConfig = PLUGIN_CONFIG_MAP.get(typeKey); + if (pluginConfigFile.exists() && pluginConfigFile.isFile()) { + if (retainedConfig == null) { + PLUGIN_CONFIG_MAP.put(typeKey, ConfigManager.doLoad(pluginConfigFile, config)); + plugin.getConfigs().add(typeKey); + } else if (retainedConfig.getClass() == config.getClass()) { + LOGGER.fine(String.format(Locale.ROOT, "Skip load config [%s] repeatedly. ", + config.getClass().getName())); + } else { + LOGGER.warning(String.format(Locale.ROOT, "Type key of %s is %s, same as %s's. ", + config.getClass().getName(), typeKey, retainedConfig.getClass().getName())); + } + continue; + } + if (PLUGIN_CONFIG_MAP.containsKey(typeKey)) { + continue; + } + + // 不能从文件加载,则为默认配置 + PLUGIN_CONFIG_MAP.put(typeKey, config); + plugin.getConfigs().add(typeKey); + } } /** - * 加载插件服务包配置 + * 清除插件的配置缓存 * - * @param configFile 配置文件夹 - * @param classLoader 加载插件服务包的类加载器 + * @param plugin 插件 */ - public static void loadServiceConfig(File configFile, ClassLoader classLoader) { - loadConfig(configFile, PluginConfig.class, classLoader); + public static void cleanPluginConfigs(Plugin plugin) { + for (String configName : plugin.getConfigs()) { + PLUGIN_CONFIG_MAP.remove(configName); + } } /** @@ -62,7 +107,7 @@ public static void loadServiceConfig(File configFile, ClassLoader classLoader) { * @return 插件配置实例 */ public static R getPluginConfig(Class cls) { - return getConfig(cls); + return (R) PLUGIN_CONFIG_MAP.get(ConfigKeyUtil.getTypeKey(cls)); } /** diff --git a/sermant-agentcore/sermant-agentcore-core/src/main/java/com/huaweicloud/sermant/core/plugin/service/PluginServiceManager.java b/sermant-agentcore/sermant-agentcore-core/src/main/java/com/huaweicloud/sermant/core/plugin/service/PluginServiceManager.java index 54c60f0ffe..425aa572e8 100644 --- a/sermant-agentcore/sermant-agentcore-core/src/main/java/com/huaweicloud/sermant/core/plugin/service/PluginServiceManager.java +++ b/sermant-agentcore/sermant-agentcore-core/src/main/java/com/huaweicloud/sermant/core/plugin/service/PluginServiceManager.java @@ -21,9 +21,6 @@ import com.huaweicloud.sermant.core.plugin.Plugin; import com.huaweicloud.sermant.core.service.ServiceManager; -import java.util.ArrayList; -import java.util.List; -import java.util.Locale; import java.util.ServiceLoader; import java.util.logging.Level; import java.util.logging.Logger; @@ -47,32 +44,32 @@ private PluginServiceManager() { * * @param plugin 插件 */ - public static void initPluginService(Plugin plugin) { + public static void initPluginServices(Plugin plugin) { ClassLoader classLoader = plugin.getServiceClassLoader() != null ? plugin.getServiceClassLoader() : plugin.getPluginClassLoader(); - initPluginService(classLoader); - } - - /** - * 初始化插件服务 - * - * @param classLoader 插件服务包的ClassLoader - */ - public static void initPluginService(ClassLoader classLoader) { - List startServiceList = new ArrayList<>(); for (PluginService service : ServiceLoader.load(PluginService.class, classLoader)) { if (loadService(service, service.getClass(), PluginService.class)) { try { + String serviceName = service.getClass().getName(); service.start(); - startServiceList.add(service.getClass().getName()); + plugin.getServices().add(serviceName); } catch (Exception ex) { - LOGGER.log(Level.SEVERE, String.format(Locale.ENGLISH, - "Error occurs while starting plugin service: %s", - service.getClass()), ex); + LOGGER.log(Level.SEVERE, "Error occurs while starting plugin service: " + service.getClass(), ex); } } } - FrameworkEventCollector.getInstance().collectServiceStartEvent(startServiceList.toString()); + FrameworkEventCollector.getInstance().collectServiceStartEvent(plugin.getServices().toString()); + } + + /** + * 关闭插件服务 + * + * @param plugin 插件 + */ + public static void shutdownPluginServices(Plugin plugin) { + for (String serviceName : plugin.getServices()) { + stopService(serviceName); + } } /** diff --git a/sermant-agentcore/sermant-agentcore-core/src/main/java/com/huaweicloud/sermant/core/service/ServiceManager.java b/sermant-agentcore/sermant-agentcore-core/src/main/java/com/huaweicloud/sermant/core/service/ServiceManager.java index 587cd704cf..faaa34bf6e 100644 --- a/sermant-agentcore/sermant-agentcore-core/src/main/java/com/huaweicloud/sermant/core/service/ServiceManager.java +++ b/sermant-agentcore/sermant-agentcore-core/src/main/java/com/huaweicloud/sermant/core/service/ServiceManager.java @@ -34,9 +34,9 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; -import java.util.Locale; import java.util.Map; import java.util.ServiceLoader; +import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; @@ -51,38 +51,38 @@ public class ServiceManager { /** * 动态配置服务类名 */ - public static final String BUFFERED_DYNAMIC_CONFIG_SERVICE = "com.huaweicloud.sermant" - + ".implement.service.dynamicconfig.BufferedDynamicConfigService"; + public static final String BUFFERED_DYNAMIC_CONFIG_SERVICE = + "com.huaweicloud.sermant.implement.service.dynamicconfig.BufferedDynamicConfigService"; /** * 心跳服务类名 */ - public static final String HEARTBEAT_SERVICE_IMPL = "com.huaweicloud.sermant.implement.service.heartbeat" - + ".HeartbeatServiceImpl"; + public static final String HEARTBEAT_SERVICE_IMPL = + "com.huaweicloud.sermant.implement.service.heartbeat.HeartbeatServiceImpl"; /** * 注入服务类名 */ - public static final String INJECT_SERVICE_IMPL = "com.huaweicloud.sermant.implement.service.inject" - + ".InjectServiceImpl"; + public static final String INJECT_SERVICE_IMPL = + "com.huaweicloud.sermant.implement.service.inject.InjectServiceImpl"; /** * netty网关服务类名 */ - public static final String NETTY_GATEWAY_CLIENT = "com.huaweicloud.sermant.implement.service.send.netty" - + ".NettyGatewayClient"; + public static final String NETTY_GATEWAY_CLIENT = + "com.huaweicloud.sermant.implement.service.send.netty.NettyGatewayClient"; /** * 链路追踪服务类名 */ - public static final String TRACING_SERVICE_IMPL = "com.huaweicloud.sermant.implement.service.tracing" - + ".TracingServiceImpl"; + public static final String TRACING_SERVICE_IMPL = + "com.huaweicloud.sermant.implement.service.tracing.TracingServiceImpl"; /** * 服务可见性服务类名 */ - public static final String VISIBILITY_SERVICE_IMPL = "com.huaweicloud.sermant.implement.service.visibility" - + ".VisibilityServiceImpl"; + public static final String VISIBILITY_SERVICE_IMPL = + "com.huaweicloud.sermant.implement.service.visibility.VisibilityServiceImpl"; /** * 日志 @@ -92,7 +92,7 @@ public class ServiceManager { /** * 服务集合 */ - private static final Map SERVICES = new HashMap(); + private static final Map SERVICES = new HashMap<>(); /** * Agent核心服务配置 @@ -128,6 +128,7 @@ public static void initServices() { * @param serviceClass 服务class * @param 服务泛型 * @return 服务实例对象 + * @throws IllegalArgumentException IllegalArgumentException 找不到对应的服务 */ public static T getService(Class serviceClass) { final BaseService baseService = SERVICES.get(serviceClass.getName()); @@ -174,30 +175,36 @@ public BaseService handle(BaseService source, BaseService target) { return isLoadSucceed; } + /** + * 关闭服务 + * + * @param serviceName 服务名 + */ + protected static void stopService(String serviceName) { + SERVICES.remove(serviceName).stop(); + } + /** * 添加关闭服务的钩子 */ private static void addStopHook() { Runtime.getRuntime().addShutdownHook(new Thread(() -> { - BaseService nettyGateWayClient = SERVICES.get(NETTY_GATEWAY_CLIENT); - SERVICES.remove(NETTY_GATEWAY_CLIENT); - SERVICES.remove(GatewayClient.class.getCanonicalName()); for (BaseService baseService : new HashSet<>(SERVICES.values())) { try { baseService.stop(); } catch (Exception ex) { - LOGGER.log(Level.SEVERE, String.format(Locale.ENGLISH, - "Error occurs while stopping service: %s", baseService.getClass().toString()), ex); + LOGGER.log(Level.SEVERE, "Error occurs while stopping service: " + baseService.getClass(), ex); } } offerEvent(); + BaseService nettyGateWayClient = SERVICES.remove(NETTY_GATEWAY_CLIENT); + SERVICES.remove(GatewayClient.class.getCanonicalName()); if (nettyGateWayClient != null) { try { nettyGateWayClient.stop(); } catch (Exception ex) { - LOGGER.log(Level.SEVERE, String.format(Locale.ENGLISH, - "Error occurs while stopping service: %s", - nettyGateWayClient.getClass().toString()), ex); + LOGGER.log(Level.SEVERE, "Error occurs while stopping service: " + nettyGateWayClient.getClass(), + ex); } } })); @@ -215,4 +222,15 @@ private static void offerEvent() { FrameworkEventCollector.getInstance().collectAgentStopEvent(); EventManager.shutdown(); } + + /** + * 关闭服务管理器 + */ + public static void shutdown() { + Set services = new HashSet<>(SERVICES.values()); + for (BaseService baseService : services) { + baseService.stop(); + } + SERVICES.clear(); + } } diff --git a/sermant-agentcore/sermant-agentcore-core/src/main/java/com/huaweicloud/sermant/core/service/heartbeat/common/HeartbeatMessage.java b/sermant-agentcore/sermant-agentcore-core/src/main/java/com/huaweicloud/sermant/core/service/heartbeat/common/HeartbeatMessage.java index ca1de7c782..e63354395f 100644 --- a/sermant-agentcore/sermant-agentcore-core/src/main/java/com/huaweicloud/sermant/core/service/heartbeat/common/HeartbeatMessage.java +++ b/sermant-agentcore/sermant-agentcore-core/src/main/java/com/huaweicloud/sermant/core/service/heartbeat/common/HeartbeatMessage.java @@ -18,7 +18,6 @@ import com.huaweicloud.sermant.core.common.BootArgsIndexer; import com.huaweicloud.sermant.core.utils.NetworkUtils; -import com.huaweicloud.sermant.core.utils.TimeUtils; import java.util.HashMap; import java.util.List; @@ -57,8 +56,8 @@ public HeartbeatMessage() { this.ip = NetworkUtils.getAllNetworkIp(); this.service = BootArgsIndexer.getServiceName(); this.appType = BootArgsIndexer.getAppType(); - this.heartbeatTime = TimeUtils.currentTimeMillis(); - this.lastHeartbeatTime = TimeUtils.currentTimeMillis(); + this.heartbeatTime = System.currentTimeMillis(); + this.lastHeartbeatTime = System.currentTimeMillis(); this.version = BootArgsIndexer.getCoreVersion(); this.instanceId = BootArgsIndexer.getInstanceId(); } @@ -68,7 +67,7 @@ public HeartbeatMessage() { */ public void updateHeartbeatVersion() { this.lastHeartbeatTime = this.heartbeatTime; - this.heartbeatTime = TimeUtils.currentTimeMillis(); + this.heartbeatTime = System.currentTimeMillis(); this.hostName = NetworkUtils.getHostName(); this.ip = NetworkUtils.getAllNetworkIp(); } diff --git a/sermant-agentcore/sermant-agentcore-core/src/main/java/com/huaweicloud/sermant/core/utils/TimeUtils.java b/sermant-agentcore/sermant-agentcore-core/src/main/java/com/huaweicloud/sermant/core/utils/TimeUtils.java deleted file mode 100644 index fbd4c19251..0000000000 --- a/sermant-agentcore/sermant-agentcore-core/src/main/java/com/huaweicloud/sermant/core/utils/TimeUtils.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (C) 2022-2022 Huawei Technologies Co., Ltd. All rights reserved. - * - * Licensed 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 com.huaweicloud.sermant.core.utils; - -import com.huaweicloud.sermant.core.common.LoggerFactory; - -import java.util.concurrent.TimeUnit; -import java.util.logging.Logger; - -/** - * 时间相关工具 - * - * @author luanwenfei - * @since 2022-03-19 - */ -public class TimeUtils { - private static final Logger LOGGER = LoggerFactory.getLogger(); - - private static long currentTimeMillis; - - private static Object obj = new Object(); - - private TimeUtils() { - } - - static { - currentTimeMillis = System.currentTimeMillis(); - Thread daemon = new Thread(new Runnable() { - @Override - public void run() { - while (true) { - synchronized (obj) { - currentTimeMillis = System.currentTimeMillis(); - try { - TimeUnit.MILLISECONDS.sleep(1); - } catch (InterruptedException e) { - LOGGER.severe(e.getMessage()); - } - } - } - } - }); - daemon.setDaemon(true); - daemon.setName("sentinel-time-tick-thread"); - daemon.start(); - } - - /** - * currentTimeMillis - * - * @return long - */ - public static long currentTimeMillis() { - return currentTimeMillis; - } -} diff --git a/sermant-agentcore/sermant-agentcore-god/src/main/java/com/huaweicloud/sermant/core/plugin/agent/adviser/AdviserScheduler.java b/sermant-agentcore/sermant-agentcore-god/src/main/java/com/huaweicloud/sermant/core/plugin/agent/adviser/AdviserScheduler.java index 0ca60d7616..4cdc8f52e6 100644 --- a/sermant-agentcore/sermant-agentcore-god/src/main/java/com/huaweicloud/sermant/core/plugin/agent/adviser/AdviserScheduler.java +++ b/sermant-agentcore/sermant-agentcore-god/src/main/java/com/huaweicloud/sermant/core/plugin/agent/adviser/AdviserScheduler.java @@ -18,6 +18,7 @@ import com.huaweicloud.sermant.core.plugin.agent.entity.ExecuteContext; +import java.util.ArrayList; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @@ -28,7 +29,7 @@ * @since 2023-04-11 */ public class AdviserScheduler { - private static AdviserInterface currentAdviser; + private static final ArrayList ADVISERS = new ArrayList<>(); private static final Map ADVICE_LOCKS = new ConcurrentHashMap<>(); @@ -41,7 +42,7 @@ private AdviserScheduler() { * @param adviser adviser */ public static void registry(AdviserInterface adviser) { - currentAdviser = adviser; + ADVISERS.add(adviser); } /** @@ -50,7 +51,7 @@ public static void registry(AdviserInterface adviser) { * @param adviser adviser */ public static void unRegistry(AdviserInterface adviser) { - currentAdviser = null; + ADVISERS.remove(adviser); } /** @@ -63,8 +64,12 @@ public static void unRegistry(AdviserInterface adviser) { */ public static ExecuteContext onMethodEnter(Object context, String adviceKey) throws Throwable { ExecuteContext executeContext = (ExecuteContext) context; - if (currentAdviser != null) { - executeContext = currentAdviser.onMethodEnter(executeContext, adviceKey); + + // 多Sermant场景下,method enter 顺序执行 + for (AdviserInterface currentAdviser : ADVISERS) { + if (currentAdviser != null) { + executeContext = currentAdviser.onMethodEnter(executeContext, adviceKey); + } } return executeContext; } @@ -79,8 +84,13 @@ public static ExecuteContext onMethodEnter(Object context, String adviceKey) thr */ public static ExecuteContext onMethodExit(Object context, String adviceKey) throws Throwable { ExecuteContext executeContext = (ExecuteContext) context; - if (currentAdviser != null) { - executeContext = currentAdviser.onMethodExit(executeContext, adviceKey); + + // / 多Sermant场景下,method enter 倒叙执行 + for (int i = ADVISERS.size() - 1; i >= 0; i--) { + AdviserInterface currentAdviser = ADVISERS.get(i); + if (currentAdviser != null) { + executeContext = currentAdviser.onMethodExit(executeContext, adviceKey); + } } return executeContext; } diff --git a/sermant-plugins/sermant-service-registry/spring-cloud-registry-service/src/test/java/com/huawei/registry/service/client/BaseTest.java b/sermant-plugins/sermant-service-registry/spring-cloud-registry-service/src/test/java/com/huawei/registry/service/client/BaseTest.java index 0475b1e04a..59018edb20 100644 --- a/sermant-plugins/sermant-service-registry/spring-cloud-registry-service/src/test/java/com/huawei/registry/service/client/BaseTest.java +++ b/sermant-plugins/sermant-service-registry/spring-cloud-registry-service/src/test/java/com/huawei/registry/service/client/BaseTest.java @@ -21,6 +21,7 @@ import com.huawei.registry.config.RegisterServiceCommonConfig; import com.huaweicloud.sermant.core.config.ConfigManager; import com.huaweicloud.sermant.core.config.common.BaseConfig; +import com.huaweicloud.sermant.core.plugin.config.PluginConfigManager; import org.junit.BeforeClass; @@ -42,8 +43,8 @@ public class BaseTest { @BeforeClass public static void init() throws IllegalAccessException, NoSuchFieldException, ClassNotFoundException { currentClassLoader = Thread.currentThread().getContextClassLoader(); - final Class aClass = currentClassLoader.loadClass(ConfigManager.class.getName()); - final Field configMap = aClass.getDeclaredField("CONFIG_MAP"); + final Class aClass = currentClassLoader.loadClass(PluginConfigManager.class.getName()); + final Field configMap = aClass.getDeclaredField("PLUGIN_CONFIG_MAP"); configMap.setAccessible(true); removeFinalModify(configMap); diff --git a/sermant-plugins/sermant-service-removal/removal-plugin/src/test/java/com/huaweicloud/sermant/cache/RuleCacheTest.java b/sermant-plugins/sermant-service-removal/removal-plugin/src/test/java/com/huaweicloud/sermant/cache/RuleCacheTest.java index ba85534b11..9642e4d10e 100644 --- a/sermant-plugins/sermant-service-removal/removal-plugin/src/test/java/com/huaweicloud/sermant/cache/RuleCacheTest.java +++ b/sermant-plugins/sermant-service-removal/removal-plugin/src/test/java/com/huaweicloud/sermant/cache/RuleCacheTest.java @@ -18,7 +18,6 @@ import com.huaweicloud.sermant.config.RemovalConfig; import com.huaweicloud.sermant.config.RemovalRule; -import com.huaweicloud.sermant.core.config.ConfigManager; import com.huaweicloud.sermant.core.plugin.config.PluginConfigManager; import org.junit.AfterClass; @@ -46,7 +45,7 @@ public class RuleCacheTest { private static final String KEY = "SERVICE-A"; - private static MockedStatic configManagerMockedStatic; + private static MockedStatic pluginConfigManagerMockedStatic; @BeforeClass public static void setUp() { @@ -58,8 +57,8 @@ public static void setUp() { removalRule.setKey(KEY); removalConfig.setRules(new ArrayList<>()); removalConfig.getRules().add(removalRule); - configManagerMockedStatic = Mockito.mockStatic(ConfigManager.class); - configManagerMockedStatic.when(() -> PluginConfigManager.getPluginConfig(RemovalConfig.class)).thenReturn(removalConfig); + pluginConfigManagerMockedStatic = Mockito.mockStatic(PluginConfigManager.class); + pluginConfigManagerMockedStatic.when(() -> PluginConfigManager.getPluginConfig(RemovalConfig.class)).thenReturn(removalConfig); } @Test @@ -74,8 +73,8 @@ public void testRule() { @AfterClass public static void setDown() { - if (configManagerMockedStatic != null) { - configManagerMockedStatic.close(); + if (pluginConfigManagerMockedStatic != null) { + pluginConfigManagerMockedStatic.close(); } InstanceCache.INSTANCE_MAP.clear(); } diff --git a/sermant-plugins/sermant-service-removal/removal-service/src/test/java/com/huaweicloud/sermant/service/RequestDataCountTaskTest.java b/sermant-plugins/sermant-service-removal/removal-service/src/test/java/com/huaweicloud/sermant/service/RequestDataCountTaskTest.java index 8a30424ce2..2946b786ef 100644 --- a/sermant-plugins/sermant-service-removal/removal-service/src/test/java/com/huaweicloud/sermant/service/RequestDataCountTaskTest.java +++ b/sermant-plugins/sermant-service-removal/removal-service/src/test/java/com/huaweicloud/sermant/service/RequestDataCountTaskTest.java @@ -18,10 +18,11 @@ import com.huaweicloud.sermant.cache.InstanceCache; import com.huaweicloud.sermant.config.RemovalConfig; -import com.huaweicloud.sermant.core.config.ConfigManager; -import com.huaweicloud.sermant.core.service.ServiceManager; +import com.huaweicloud.sermant.core.plugin.config.PluginConfigManager; +import com.huaweicloud.sermant.core.plugin.service.PluginServiceManager; import com.huaweicloud.sermant.entity.InstanceInfo; import com.huaweicloud.sermant.entity.RequestCountData; + import org.junit.AfterClass; import org.junit.Assert; import org.junit.BeforeClass; @@ -48,9 +49,9 @@ public class RequestDataCountTaskTest { private static final double ERROR_RATE = 0.5; - private static MockedStatic configManagerMockedStatic; + private static MockedStatic pluginConfigManagerMockedStatic; - private static MockedStatic serviceManagerMockedStatic; + private static MockedStatic pluginServiceManagerMockedStatic; private static ScheduledThreadPoolExecutor scheduledThreadPoolExecutor; @@ -65,10 +66,11 @@ public static void setUp() { removalConfig.setWindowsTime(1000); removalConfig.setWindowsNum(10); removalConfig.setExpireTime(6000); - configManagerMockedStatic = Mockito.mockStatic(ConfigManager.class); - configManagerMockedStatic.when(() -> ConfigManager.getConfig(RemovalConfig.class)).thenReturn(removalConfig); - serviceManagerMockedStatic = Mockito.mockStatic(ServiceManager.class); - serviceManagerMockedStatic.when(() -> ServiceManager.getService(RemovalEventService.class)) + pluginConfigManagerMockedStatic = Mockito.mockStatic(PluginConfigManager.class); + pluginConfigManagerMockedStatic.when(() -> PluginConfigManager.getPluginConfig(RemovalConfig.class)) + .thenReturn(removalConfig); + pluginServiceManagerMockedStatic = Mockito.mockStatic(PluginServiceManager.class); + pluginServiceManagerMockedStatic.when(() -> PluginServiceManager.getPluginService(RemovalEventService.class)) .thenReturn(removalEventService); scheduledThreadPoolExecutor = new ScheduledThreadPoolExecutor(1); scheduledThreadPoolExecutor.scheduleWithFixedDelay(() -> { @@ -96,8 +98,8 @@ public void testProcessData() throws InterruptedException { @AfterClass public static void setDown() { - if (configManagerMockedStatic != null) { - configManagerMockedStatic.close(); + if (pluginConfigManagerMockedStatic != null) { + pluginConfigManagerMockedStatic.close(); } InstanceCache.INSTANCE_MAP.clear(); if (scheduledThreadPoolExecutor != null) { @@ -106,8 +108,8 @@ public static void setDown() { if (requestDataCountTask != null) { requestDataCountTask.stop(); } - if (serviceManagerMockedStatic != null) { - serviceManagerMockedStatic.close(); + if (pluginServiceManagerMockedStatic != null) { + pluginServiceManagerMockedStatic.close(); } } } \ No newline at end of file