SkyWalking Java Agent 配置初始化流程分析,java对象生命周期面试

文章介绍了SkyWalkingJavaAgent如何处理配置,包括使用`replacePlaceholders`函数处理占位符,通过`overrideConfigBySystemProp`和`overrideConfigByAgentOptions`覆盖系统属性和命令行参数,以及`initializeConfig`和`configureLogger`初始化配置和日志。配置优先级遵循`AgentOptions>System.Properties(-D)>Systemenvironmentvariables>Configfile`的原则。
摘要由CSDN通过智能技术生成
  • @param value the value containing the placeholders to be replaced

  • @param properties the {@code Properties} to use for replacement

  • @return the supplied value with placeholders replaced inline

*/

public String replacePlaceholders(String value, final Properties properties) {

return replacePlaceholders(value, new PlaceholderResolver() {

@Override

public String resolvePlaceholder(String placeholderName) {

return getConfigValue(placeholderName, properties);

}

});

}

// 优先级 System.Properties(-D) > System environment variables > Config file

private String getConfigValue(String key, final Properties properties) {

// 从Java虚拟机系统属性中获取(-D)

String value = System.getProperty(key);

if (value == null) {

// 从操作系统环境变量获取, 比如 JAVA_HOME、Path 等环境变量

value = System.getenv(key);

}

if (value == null) {

// 从配置文件中获取

value = properties.getProperty(key);

}

return value;

}

复制代码

3.overrideConfigBySystemProp() 读取 System.getProperties() 中以 skywalking. 开头的系统属性覆盖配置;

/**

  • Override the config by system properties. The property key must start with skywalking, the result should be as

  • same as in agent.config

  • such as: Property key of agent.service_name should be skywalking.agent.service_name

*/

private static void overrideConfigBySystemProp() throws IllegalAccessException {

Properties systemProperties = System.getProperties();

for (final Map.Entry<Object, Object> prop : systemProperties.entrySet()) {

String key = prop.getKey().toString();

// 必须是以 skywalking. 开头的属性

if (key.startsWith(ENV_KEY_PREFIX)) {

String realKey = key.substring(ENV_KEY_PREFIX.length());

AGENT_SETTINGS.put(realKey, prop.getValue());

}

}

}

复制代码

4.overrideConfigByAgentOptions() 解析 agentArgs 参数配置覆盖配置;

  • agentArgs 就是 premain 方法的第一个参数,以 -javaagent:/path/to/skywalking-agent.jar=k1=v1,k2=v2的形式传值。

5.initializeConfig() 将以上读取到的配置信息映射到 Config 类的静态属性,后面会重点分析;

6.configureLogger() 根据配置的 Config.Logging.RESOLVER 重配置 Log,更多关于日志参见文章 SkyWalking Java Agent 日志组件分析

static void configureLogger() {

switch (Config.Logging.RESOLVER) {

case JSON:

LogManager.setLogResolver(new JsonLogResolver());

break;

case PATTERN:

default:

LogManager.setLogResolver(new PatternLogResolver());

}

}

复制代码

7.必填参数验证,验证非空参数 agent.service_name 和 collector.servers。

定位 skywalking-agent.jar 所在目录

skywalking-agent 目录结构如下:

skywalking-agent.png

config 目录存放的是默认配置文件 agent.config,读取默认配置文件,以及后面加载插件都需要用到 skywalking-agent.jar 所在目录。

/**

  • Load the specified config file or default config file

  • @return the config file {@link InputStream}, or null if not needEnhance.

*/

private static InputStreamReader loadConfig() throws AgentPackageNotFoundException, ConfigNotFoundException {

// System.getProperty() 读取 Java 虚拟机中的系统属性, Java 虚拟机中的系统属性在运行Java程序的时候通过 java -Dk1=v1 配置.

String specifiedConfigPath = System.getProperty(SPECIFIED_CONFIG_PATH);

// 使用指定的配置文件或默认的配置文件, AgentPackagePath.getPath() 获取 skywalking-agent.jar 所在目录

File configFile = StringUtil.isEmpty(specifiedConfigPath) ? new File(

AgentPackagePath.getPath(), DEFAULT_CONFIG_FILE_NAME) : new File(specifiedConfigPath);

if (configFile.exists() && configFile.isFile()) {

try {

LOGGER.info(“Config file found in {}.”, configFile);

return new InputStreamReader(new FileInputStream(configFile), StandardCharsets.UTF_8);

} catch (FileNotFoundException e) {

throw new ConfigNotFoundException(“Failed to load agent.config”, e);

}

}

throw new ConfigNotFoundException(“Failed to load agent.config.”);

}

复制代码

new File(AgentPackagePath.getPath(), DEFAULT_CONFIG_FILE_NAME) 定位默认配置文件的位置, AgentPackagePath.getPath() 方法用来获取 skywalking-agent.jar 所在目录

/**

  • AgentPackagePath is a flag and finder to locate the SkyWalking agent.jar. It gets the absolute path of the agent jar.

  • The path is the required metadata for agent core looking up the plugins and toolkit activations. If the lookup

  • mechanism fails, the agent will exit directly.

*/

public class AgentPackagePath {

private static final ILog LOGGER = LogManager.getLogger(AgentPackagePath.class);

private static File AGENT_PACKAGE_PATH;

public static File getPath() throws AgentPackageNotFoundException {

if (AGENT_PACKAGE_PATH == null) {

// 返回 skywalking-agent.jar 文件所在的目录 E:\develop\source\sample\source\skywalking-java\skywalking-agent

AGENT_PACKAGE_PATH = findPath();

}

return AGENT_PACKAGE_PATH;

}

public static boolean isPathFound() {

return AGENT_PACKAGE_PATH != null;

}

private static File findPath() throws AgentPackageNotFoundException {

// 将 AgentPackagePath 全类名中的.替换成 /

// org/apache/skywalking/apm/agent/core/boot/AgentPackagePath.class

String classResourcePath = AgentPackagePath.class.getName().replaceAll(“.”, “/”) + “.class”;

// 使用 AppClassLoader 加载资源,通常情况下 AgentPackagePath 类是被 AppClassLoader 加载的。

URL resource = ClassLoader.getSystemClassLoader().getResource(classResourcePath);

if (resource != null) {

String urlString = resource.toString();

//jar:file:/E:/source/skywalking-java/skywalking-agent/skywalking-agent.jar!/org/apache/skywalking/apm/agent/core/boot/AgentPackagePath.class

LOGGER.debug(“The beacon class location is {}.”, urlString);

// 判断 url 中是否包含!,如果包含则说明 AgentPackagePath.class 是包含在jar中。

int insidePathIndex = urlString.indexOf(‘!’);

boolean isInJar = insidePathIndex > -1;

if (isInJar) {

// file:/E:/source/skywalking-java/skywalking-agent/skywalking-agent.jar

urlString = urlString.substring(urlString.indexOf(“file:”), insidePathIndex);

File agentJarFile = null;

try {

// E:\source\skywalking-java\skywalking-agent\skywalking-agent.jar

agentJarFile = new File(new URL(urlString).toURI());

} catch (MalformedURLException | URISyntaxException e) {

LOGGER.error(e, “Can not locate agent jar file by url:” + urlString);

}

if (agentJarFile.exists()) {

// 返回 skywalking-agent.jar 文件所在的目录

return agentJarFile.getParentFile();

}

} else {

int prefixLength = “file:”.length();

String classLocation = urlString.substring(

prefixLength, urlString.length() - classResourcePath.length());

return new File(classLocation);

}

}

LOGGER.error(“Can not locate agent jar file.”);

throw new AgentPackageNotFoundException(“Can not locate agent jar file.”);

}

}

复制代码

通过类加载器 AppClassLoader 加载 AgentPackagePath.class 资源,定位到 skywalking-agent.jar 所在的目录,保存到静态成员变量 AGENT_PACKAGE_PATH 中,下次获取直接读取静态变量。

配置优先级

Agent Options > System.Properties(-D) > System environment variables > Config file

System.getProperties() 和 System.getenv() 区别,请参考文章 www.cnblogs.com/clarke157/p…

  • System.getProperties() 获取 Java 虚拟机相关的系统属性(比如 java.version、 java.io.tmpdir 等),通过 java -D配置;

  • System.getenv() 获取系统环境变量(比如 JAVA_HOME、Path 等),通过操作系统配置。

将配置信息映射到 Config 类

在我们的日常开发中一般是直接从 Properties 读取需要的配置项,SkyWalking Java Agent 并没有这么做,而是定义一个配置类 Config,将配置项映射到 Config 类的静态属性中,其他地方需要配置项的时候,直接从类的静态属性获取就可以了,非常方便使用。

ConfigInitializer 就是负责将 Properties 中的 key/value 键值对映射到类(比如 Config 类)的静态属性,其中 key 对应类的静态属性,value 赋值给静态属性的值。

/**

  • This is the core config in sniffer agent.

*/

public class Config {

public static class Agent {

/**

  • Namespace isolates headers in cross process propagation. The HEADER name will be HeaderName:Namespace.

*/

public static String NAMESPACE = “”;

/**

  • Service name is showed in skywalking-ui. Suggestion: set a unique name for each service, service instance

  • nodes share the same code

*/

@Length(50)

public static String SERVICE_NAME = “”;

// 省略部分代码…

}

public static class Collector {

/**

  • Collector skywalking trace receiver service addresses.

小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Java工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Java开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频

如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Java)
img

华为、OPPO等大厂,18年进入阿里一直到现在。**

深知大多数初中级Java工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Java开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
[外链图片转存中…(img-gSAXwQLX-1710890635714)]
[外链图片转存中…(img-Elgv14eU-1710890635715)]
[外链图片转存中…(img-najwfJbR-1710890635716)]

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频

如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Java)
[外链图片转存中…(img-JevGrx2s-1710890635716)]

  • 10
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值