Skip to content

Commit

Permalink
Agent卸载及插件卸载
Browse files Browse the repository at this point in the history
  • Loading branch information
luanwenfei-venus committed Sep 15, 2023
1 parent 1d0fcd9 commit e76813d
Show file tree
Hide file tree
Showing 16 changed files with 350 additions and 221 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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() {
}

Expand All @@ -70,6 +83,8 @@ public static void install(String artifact, Map<String, Object> argsMap, Instrum
if (isDynamic) {
agentType = AgentType.AGENTMAIN.getValue();
}
artifactCache = artifact;
adviserCache = new DefaultAdviser();

// 初始化框架类加载器
ClassLoaderManager.init(argsMap);
Expand Down Expand Up @@ -99,9 +114,9 @@ public static void install(String artifact, Map<String, Object> argsMap, Instrum
PluginSystemEntrance.initialize(isDynamic);

// 注册Adviser
AdviserScheduler.registry(new DefaultAdviser());
AdviserScheduler.registry(adviserCache);

// 增强静态插件
// 静态插件在全部加载结束后,统一增强,复用一个AgentBuilder
if (!isDynamic) {
ByteEnhanceManager.enhance();
}
Expand All @@ -118,11 +133,32 @@ public static void install(String artifact, Map<String, Object> 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);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,6 @@
public class AgentUnInstallCommandExecutor implements CommandExecutor {
@Override
public void execute(String args) {
AgentCoreEntrance.unInstall();
AgentCoreEntrance.uninstall();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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()));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -48,12 +50,19 @@ public abstract class ConfigManager {
* 配置对象集合,键为配置对象的实现类Class,值为加载完毕的配置对象
* <p>通过{@link #getConfig(Class)}方法获取配置对象
*/
private static final Map<String, BaseConfig> CONFIG_MAP = new HashMap<String, BaseConfig>();
private static final Map<String, BaseConfig> CONFIG_MAP = new HashMap<>();

private static final Iterable<LoadConfigStrategy> LOAD_CONFIG_STRATEGIES =
ServiceLoader.load(LoadConfigStrategy.class, ClassLoaderManager.getFrameworkClassLoader());
private static final List<LoadConfigStrategy> LOAD_CONFIG_STRATEGIES = new ArrayList<>();

private static Map<String, Object> argsMap = null;
private static Map<String, Object> argsMap;

/**
* 关闭配置管理器
*/
public static void shutdown() {
CONFIG_MAP.clear();
LOAD_CONFIG_STRATEGIES.clear();
}

/**
* 通过配置对象类型获取配置对象
Expand Down Expand Up @@ -84,31 +93,33 @@ public static <R extends BaseConfig> R getConfig(Class<R> cls) {
*/
public static synchronized void initialize(Map<String, Object> 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<? extends BaseConfig> 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<? extends BaseConfig> baseCls, ClassLoader classLoader) {
private static synchronized void loadDefaultConfig(ClassLoader classLoader) {
foreachConfig(new ConfigConsumer() {
@Override
public void accept(BaseConfig config) {
Expand All @@ -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<? extends BaseConfig> 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);
}

/**
Expand All @@ -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();
}

Expand All @@ -188,9 +206,9 @@ private static LoadConfigStrategy<?> getLoadConfigStrategy(File configFile, Clas
*
* @param configConsumer 配置处理方法
*/
private static void foreachConfig(ConfigConsumer configConsumer, Class<? extends BaseConfig> baseCls,
private static void foreachConfig(ConfigConsumer configConsumer,
ClassLoader classLoader) {
for (BaseConfig config : ServiceLoader.load(baseCls, classLoader)) {
for (BaseConfig config : ServiceLoader.load((Class<? extends BaseConfig>) BaseConfig.class, classLoader)) {
configConsumer.accept(config);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,7 @@ public class EventManager {

private static final ConcurrentHashMap<String, EventCollector> 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;

Expand All @@ -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();

Expand All @@ -72,15 +73,24 @@ 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);
}

/**
* 在程序终止时上报在内存中的事件
*/
public static void shutdown() {
// 关闭定时采集事件线程
if (executorService != null) {
executorService.shutdown();
}

// 采集全部事件并上报
collectAll();

// 清空注册的事件收集器
EVENT_COLLECTORS.clear();
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
Expand All @@ -57,7 +57,7 @@ public static void initOperations() {
public static <T extends BaseOperation> T getOperation(Class<T> 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. ");
}
Expand All @@ -71,7 +71,7 @@ public static <T extends BaseOperation> T getOperation(Class<T> operationClass)
* @return 是否加载成功
*/
private static boolean loadOperation(BaseOperation operation, Class<?> operationCls,
Class<? extends BaseOperation> baseCls) {
Class<? extends BaseOperation> baseCls) {
if (operationCls == null || operationCls == baseCls || !baseCls.isAssignableFrom(operationCls)) {
return false;
}
Expand All @@ -94,4 +94,11 @@ private static boolean loadOperation(BaseOperation operation, Class<?> operation
}
return isLoadSucceed;
}

/**
* 关闭OperationManager
*/
public static void shutdown() {
OPERATIONS.clear();
}
}
Loading

0 comments on commit e76813d

Please sign in to comment.